From e97ff023d2b752a678979cbb14ae47eb28c330e1 Mon Sep 17 00:00:00 2001 From: Matthew Date: Tue, 9 Mar 2021 19:46:37 +0800 Subject: [PATCH] Commit code folders --- .settings/language.settings.xml | 17 + .../org.eclipse.cdt.managedbuilder.core.prefs | 11 + CMSIS/arm_common_tables.h | 121 + CMSIS/arm_const_structs.h | 66 + CMSIS/arm_math.h | 7160 +++++ CMSIS/cmsis_armcc.h | 870 + CMSIS/cmsis_armclang.h | 1877 ++ CMSIS/cmsis_compiler.h | 266 + CMSIS/cmsis_gcc.h | 2088 ++ CMSIS/cmsis_iccarm.h | 913 + CMSIS/cmsis_version.h | 39 + CMSIS/core_armv8mbl.h | 1896 ++ CMSIS/core_armv8mml.h | 2960 ++ CMSIS/core_cm4.h | 2118 ++ CMSIS/mpu_armv7.h | 197 + CMSIS/mpu_armv8.h | 333 + board/board.c | 46 + board/board.h | 61 + board/clock_config.c | 54 + board/clock_config.h | 56 + board/peripherals.c | 50 + board/peripherals.h | 56 + board/pin_mux.c | 50 + board/pin_mux.h | 56 + device/MK64F12.h | 22404 ++++++++++++++++ device/MK64F12_features.h | 1942 ++ device/fsl_device_registers.h | 36 + device/system_MK64F12.c | 302 + device/system_MK64F12.h | 164 + drivers/fsl_clock.c | 2266 ++ drivers/fsl_clock.h | 1546 ++ drivers/fsl_common.c | 147 + drivers/fsl_common.h | 585 + drivers/fsl_sdhc.c | 1573 ++ drivers/fsl_sdhc.h | 1091 + drivers/fsl_wdog.c | 240 + drivers/fsl_wdog.h | 411 + osa/usb_osa.h | 576 + osa/usb_osa_bm.c | 522 + osa/usb_osa_bm.h | 35 + redlib/include/assert.h | 43 + redlib/include/ctype.h | 123 + redlib/include/errno.h | 144 + redlib/include/float.h | 169 + redlib/include/limits.h | 81 + redlib/include/locale.h | 180 + redlib/include/math.h | 220 + redlib/include/setjmp.h | 68 + redlib/include/signal.h | 94 + redlib/include/stdarg.h | 30 + redlib/include/stdbool.h | 26 + redlib/include/stddef.h | 35 + redlib/include/stdint.h | 320 + redlib/include/stdio.h | 235 + redlib/include/stdlib.h | 106 + redlib/include/string.h | 71 + redlib/include/sys/libconfig-arm.h | 349 + redlib/include/sys/libconfig.h | 29 + redlib/include/sys/redlib_version.h | 21 + redlib/include/time.h | 87 + source/API/ADCAPI.h | 75 + source/API/CEMAPI.h | 59 + source/API/CTRLAPI.h | 72 + source/API/DACAPI.h | 80 + source/API/DIAGAPI.h | 72 + source/API/IICAPI.h | 28 + source/API/IOAPI.h | 404 + source/API/MAPSAPI.h | 45 + source/API/PIMAPI.h | 69 + source/API/PROTAPI.h | 62 + source/API/RESAPI.h | 33 + source/API/SPREADSAPI.h | 69 + source/API/SYSAPI.h | 221 + source/API/TABLESAPI.h | 37 + source/API/TASKAPI.h | 48 + source/API/TEPMAPI.h | 139 + source/Client/AFM.c | 190 + source/Client/AFM.h | 63 + source/Client/ATS.c | 261 + source/Client/ATS.h | 55 + source/Client/BOOSTED.c | 99 + source/Client/BOOSTED.h | 40 + source/Client/BVM.c | 176 + source/Client/BVM.h | 73 + source/Client/CAM.c | 174 + source/Client/CAM.h | 57 + source/Client/CLO2.c | 341 + source/Client/CLO2.h | 78 + source/Client/CONV.c | 149 + source/Client/CONV.h | 67 + source/Client/CTS.c | 369 + source/Client/CTS.h | 62 + source/Client/DIAG.c | 801 + source/Client/DIAG.h | 388 + source/Client/EST.c | 651 + source/Client/EST.h | 92 + source/Client/FILM.c | 109 + source/Client/FILM.h | 43 + source/Client/FME.c | 148 + source/Client/FME.h | 83 + source/Client/FUEL.c | 1246 + source/Client/FUEL.h | 91 + source/Client/GENDATA.c | 358 + source/Client/GENDATA.h | 83 + source/Client/IAC.c | 727 + source/Client/IAC.h | 66 + source/Client/LSU4X.c | 520 + source/Client/LSU4X.h | 122 + source/Client/LSUH.c | 651 + source/Client/LSUH.h | 101 + source/Client/MAP.c | 422 + source/Client/MAP.h | 65 + source/Client/MCP23S08.c | 160 + source/Client/MCP23S08.h | 72 + source/Client/RELAYS.c | 454 + source/Client/RELAYS.h | 125 + source/Client/SENSORS.c | 852 + source/Client/SENSORS.h | 217 + source/Client/SETUP.c | 199 + source/Client/SETUP.h | 44 + source/Client/TORQUE.c | 216 + source/Client/TORQUE.h | 67 + source/Client/TPS.c | 381 + source/Client/TPS.h | 117 + source/Client/Test_60_M2.h | 1891 ++ source/Client/UNITS.c | 28 + source/Client/UNITS.h | 71 + source/Client/USER.c | 111 + source/Client/USER.h | 135 + source/Client/USERCAL.c | 120 + source/Client/USERCAL.h | 1235 + source/Client/USERMAIN.c | 32 + source/Client/USERMATH.c | 224 + source/Client/USERMATH.h | 1596 ++ source/Client/golf_mk6.h | 2210 ++ source/GenericDrivers/diskio.h | 85 + source/GenericDrivers/ff.c | 4524 ++++ source/GenericDrivers/ff.h | 342 + source/KernelServices/CBYTEQUEUE.h | 31 + source/KernelServices/COMMONNL.h | 65 + source/KernelServices/DISK.c | 70 + source/KernelServices/DISK.h | 34 + source/KernelServices/DLL.c | 1290 + source/KernelServices/DSCRIO.c | 34 + source/KernelServices/DSCRIO.h | 56 + source/KernelServices/DSCRIOHA.c | 79 + source/KernelServices/DSCRIOHA.h | 73 + source/KernelServices/KERNELDIAG.c | 104 + source/KernelServices/KERNELDIAG.h | 48 + source/KernelServices/KERNELIO.c | 257 + source/KernelServices/KERNELIO.h | 213 + source/KernelServices/PACKEDDLL.c | 53 + source/KernelServices/PACKEDDLL.h | 21 + source/KernelServices/PIM.c | 59 + source/KernelServices/PIM.h | 28 + source/KernelServices/PIMHA.c | 213 + source/KernelServices/PIMHA.h | 170 + source/KernelServices/PIT.c | 51 + source/KernelServices/PIT.h | 31 + source/KernelServices/RESM.c | 106 + source/KernelServices/RESM.h | 51 + source/KernelServices/SIM.c | 55 + source/KernelServices/SIM.h | 29 + source/KernelServices/SIMHA.c | 161 + source/KernelServices/SIMHA.h | 74 + source/KernelServices/TIMER.c | 99 + source/KernelServices/TIMER.h | 46 + source/KernelServices/dll.h | 165 + source/KernelServices/ffconf.h | 212 + source/KernelServices/regset.c | 175 + source/KernelServices/regset.h | 57 + .../include/FTFx_FX_256K_32K_2K_1K_1K.h | 418 + .../include/FTFx_JX_128K_32K_2K_1K_1K.h | 389 + .../FTFx_KX_(128_64_32)K_0K_0K_1K_0K.h | 297 + .../FTFx_KX_(128_64_32)K_32K_2K_1K_1K.h | 393 + .../FTFx_KX_(256_128_64)K_32K_2K_2K_1K.h | 420 + .../include/FTFx_KX_1024K_0K_16K_4K_0K.h | 325 + .../include/FTFx_KX_256K_256K_4K_2K_2K.h | 390 + .../include/FTFx_KX_512K_0K_0K_2K_0K.h | 326 + .../include/FTFx_KX_512K_512K_16K_4K_4K.h | 420 + .../FTFx_LX_(128_64_32_16_8)K_0K_0K_1K_0K.h | 263 + .../FTFx_NX_(256_128_96_64)K_32K_2K_2K_1K.h | 395 + source/LegacyDrivers/include/SSD_FTFx.h | 101 + .../LegacyDrivers/include/SSD_FTFx_Common.h | 176 + .../LegacyDrivers/include/SSD_FTFx_Device.h | 87 + .../LegacyDrivers/include/SSD_FTFx_Internal.h | 178 + source/LegacyDrivers/include/SSD_Types.h | 53 + source/LegacyDrivers/include/diskio.h | 85 + source/LegacyDrivers/include/enet.h | 85 + source/LegacyDrivers/include/eth.h | 58 + source/LegacyDrivers/include/eth_phy.h | 176 + source/LegacyDrivers/include/integer.h | 37 + source/LegacyDrivers/include/mii.h | 30 + source/LegacyDrivers/include/nbuf.h | 237 + .../include/usb_device_descriptor.h | 225 + .../LegacyDrivers/source/DEFlashPartition.c | 79 + .../source/DFlashGetProtection.c | 79 + .../source/DFlashSetProtection.c | 110 + source/LegacyDrivers/source/EEEWrite.c | 118 + .../LegacyDrivers/source/EERAMGetProtection.c | 77 + .../LegacyDrivers/source/EERAMSetProtection.c | 108 + .../source/FTFx_KX_256K_256K_4K_2K_2K.h | 390 + source/LegacyDrivers/source/FlashCheckSum.c | 167 + .../source/FlashCommandSequence.c | 157 + .../LegacyDrivers/source/FlashEraseAllBlock.c | 93 + source/LegacyDrivers/source/FlashEraseBlock.c | 123 + .../LegacyDrivers/source/FlashEraseResume.c | 92 + .../LegacyDrivers/source/FlashEraseSector.c | 175 + .../LegacyDrivers/source/FlashEraseSuspend.c | 97 + .../source/FlashGetInterruptEnable.c | 90 + .../source/FlashGetSecurityState.c | 103 + source/LegacyDrivers/source/FlashInit.c | 178 + .../LegacyDrivers/source/FlashProgramCheck.c | 244 + .../source/FlashProgramLongword.c | 191 + .../LegacyDrivers/source/FlashProgramOnce.c | 129 + .../LegacyDrivers/source/FlashProgramPhrase.c | 167 + .../source/FlashProgramSection.c | 174 + source/LegacyDrivers/source/FlashReadOnce.c | 126 + .../LegacyDrivers/source/FlashReadResource.c | 178 + .../source/FlashSecurityBypass.c | 108 + .../source/FlashSetInterruptEnable.c | 99 + .../source/FlashVerifyAllBlock.c | 96 + .../LegacyDrivers/source/FlashVerifyBlock.c | 124 + .../LegacyDrivers/source/FlashVerifySection.c | 171 + source/LegacyDrivers/source/NormalDemo.h | 87 + .../source/PFlashGetProtection.c | 89 + .../source/PFlashGetSwapStatus.c | 124 + .../source/PFlashSetProtection.c | 129 + source/LegacyDrivers/source/PFlashSwap.c | 344 + source/LegacyDrivers/source/SetEEEEnable.c | 76 + .../source/usb_device_descriptor.c | 488 + source/MK64FX512xxx12_Project.c | 63 + source/OS/CLIENT.c | 162 + source/OS/CLIENT.h | 57 + source/OS/MSG.c | 174 + source/OS/MSG.h | 62 + source/OS/OS.c | 587 + source/OS/OS.h | 217 + source/OS/OSHA.h | 23 + source/OS/OSTASKS.h | 130 + source/OS/STACK.c | 18 + source/OS/STACK.h | 32 + source/OS/TASK.c | 27 + source/OS/TASK.h | 82 + source/OS/THREAD.c | 70 + source/OS/THREAD.h | 27 + source/OS/tqueue.c | 53 + source/OS/tqueue.h | 42 + source/OS/tqueueHA.c | 77 + source/OS/tqueueHA.h | 20 + source/Peripherals/ADCHA.c | 431 + source/Peripherals/ADCHA.h | 624 + source/Peripherals/CANHA.c | 544 + source/Peripherals/CANHA.h | 135 + source/Peripherals/CRC16.c | 48 + source/Peripherals/CRC16.h | 31 + source/Peripherals/CRC16HA.c | 122 + source/Peripherals/CRC16HA.h | 72 + source/Peripherals/DAC.c | 48 + source/Peripherals/DAC.h | 34 + source/Peripherals/DACHA.c | 131 + source/Peripherals/DACHA.h | 49 + source/Peripherals/FEE.c | 247 + source/Peripherals/FEE.h | 86 + source/Peripherals/FEEHA.c | 1062 + source/Peripherals/FEEHA.h | 200 + source/Peripherals/IIC.c | 54 + source/Peripherals/IIC.h | 27 + source/Peripherals/IICHA.c | 202 + source/Peripherals/IICHA.h | 186 + source/Peripherals/PERADC.c | 407 + source/Peripherals/PERCAN.c | 54 + source/Peripherals/PERCAN.h | 41 + source/Peripherals/PERSPI.c | 54 + source/Peripherals/PERSPI.h | 27 + source/Peripherals/PERUART.c | 141 + source/Peripherals/PERUART.h | 53 + source/Peripherals/PERUSB.c | 65 + source/Peripherals/PERUSB.h | 42 + source/Peripherals/PERWDT.c | 24 + source/Peripherals/PERWDT.h | 26 + source/Peripherals/SDHC.c | 62 + source/Peripherals/SDHC.h | 29 + source/Peripherals/SDHC1HA.c | 2879 ++ source/Peripherals/SDHC1HA.h | 1536 ++ source/Peripherals/SDHCHA.c | 213 + source/Peripherals/SDHCHA.h | 164 + source/Peripherals/SPIHA.c | 351 + source/Peripherals/SPIHA.h | 182 + source/Peripherals/SRLTFR.c | 113 + source/Peripherals/SRLTFR.h | 40 + source/Peripherals/TIME.c | 44 + source/Peripherals/TIME.h | 40 + source/Peripherals/UARTHA.c | 221 + source/Peripherals/UARTHA.h | 74 + source/Peripherals/USBHA.c | 142 + source/Peripherals/USBHA.h | 48 + source/Peripherals/VCOMHA.c | 757 + source/Peripherals/VCOMHA.h | 113 + source/Peripherals/WDTHA.c | 42 + source/Peripherals/WDTHA.h | 33 + source/Peripherals/peradc.h | 49 + source/Suites/UDS/Include/UDSAL.h | 289 + source/Suites/UDS/Include/UDSNL.h | 51 + source/Suites/UDS/Include/UDSSL.h | 51 + source/Suites/UDS/UDSAL.c | 1139 + source/Suites/UDS/UDSNL.c | 307 + source/Suites/UDS/UDSSL.c | 100 + source/Support/BUILD.h | 85 + source/Support/CQUEUE.h | 112 + source/Support/DECLARATIONS.h | 56 + source/Support/MACROS.h | 42 + source/Support/MATH.c | 75 + source/Support/MATH.h | 18 + source/System/CPUAbstract.c | 45 + source/System/CPUAbstract.h | 29 + source/System/ECUHostMain.c | 45 + source/System/IRQ.c | 660 + source/System/IRQ.h | 71 + source/System/SYS.h | 57 + source/System/SYSAPI.c | 488 + source/System/SYSAbstract.h | 23 + source/System/TYPES.h | 57 + source/UserServices/CEM.c | 1025 + source/UserServices/CEM.h | 82 + source/UserServices/CTRL.c | 184 + source/UserServices/CTRL.h | 69 + source/UserServices/SPREADS.c | 429 + source/UserServices/SPREADS.h | 30 + source/UserServices/TABLES.c | 276 + source/UserServices/TABLES.h | 28 + source/UserServices/TEPM.c | 1285 + source/UserServices/TEPM.h | 276 + source/UserServices/TEPMHA.c | 1410 + source/UserServices/TEPMHA.h | 538 + source/UserServices/maps.c | 268 + source/UserServices/maps.h | 28 + source/generated/usb_device_config.h | 157 + source/semihost_hardfault.c | 109 + startup/startup_mk64f12.c | 941 + usb/device/class/usb_device_audio.c | 1817 ++ usb/device/class/usb_device_audio.h | 394 + usb/device/class/usb_device_ccid.c | 1101 + usb/device/class/usb_device_ccid.h | 1096 + usb/device/class/usb_device_cdc_acm.c | 846 + usb/device/class/usb_device_cdc_acm.h | 269 + usb/device/class/usb_device_cdc_rndis.c | 984 + usb/device/class/usb_device_cdc_rndis.h | 712 + usb/device/class/usb_device_class.c | 552 + usb/device/class/usb_device_class.h | 421 + usb/device/class/usb_device_hid.c | 745 + usb/device/class/usb_device_hid.h | 260 + usb/device/class/usb_device_msc.c | 1204 + usb/device/class/usb_device_msc.h | 264 + usb/device/class/usb_device_msc_ufi.c | 915 + usb/device/class/usb_device_msc_ufi.h | 246 + usb/device/class/usb_device_phdc.c | 745 + usb/device/class/usb_device_phdc.h | 166 + usb/device/class/usb_device_printer.c | 634 + usb/device/class/usb_device_printer.h | 191 + usb/device/class/usb_device_video.c | 1437 + usb/device/class/usb_device_video.h | 1009 + usb/device/include/usb_device.h | 635 + usb/device/source/ehci/usb_device_ehci.c | 1856 ++ usb/device/source/ehci/usb_device_ehci.h | 301 + usb/device/source/khci/usb_device_khci.c | 1652 ++ usb/device/source/khci/usb_device_khci.h | 262 + .../source/lpcip3511/usb_device_lpcip3511.c | 1883 ++ .../source/lpcip3511/usb_device_lpcip3511.h | 237 + usb/device/source/usb_device_ch9.c | 952 + usb/device/source/usb_device_ch9.h | 79 + usb/device/source/usb_device_dci.c | 1482 + usb/device/source/usb_device_dci.h | 156 + usb/include/usb.h | 130 + usb/include/usb_misc.h | 430 + usb/include/usb_spec.h | 300 + usb/phy/usb_phy.c | 240 + usb/phy/usb_phy.h | 91 + 378 files changed, 150779 insertions(+) create mode 100644 .settings/language.settings.xml create mode 100644 .settings/org.eclipse.cdt.managedbuilder.core.prefs create mode 100644 CMSIS/arm_common_tables.h create mode 100644 CMSIS/arm_const_structs.h create mode 100644 CMSIS/arm_math.h create mode 100644 CMSIS/cmsis_armcc.h create mode 100644 CMSIS/cmsis_armclang.h create mode 100644 CMSIS/cmsis_compiler.h create mode 100644 CMSIS/cmsis_gcc.h create mode 100644 CMSIS/cmsis_iccarm.h create mode 100644 CMSIS/cmsis_version.h create mode 100644 CMSIS/core_armv8mbl.h create mode 100644 CMSIS/core_armv8mml.h create mode 100644 CMSIS/core_cm4.h create mode 100644 CMSIS/mpu_armv7.h create mode 100644 CMSIS/mpu_armv8.h create mode 100644 board/board.c create mode 100644 board/board.h create mode 100644 board/clock_config.c create mode 100644 board/clock_config.h create mode 100644 board/peripherals.c create mode 100644 board/peripherals.h create mode 100644 board/pin_mux.c create mode 100644 board/pin_mux.h create mode 100644 device/MK64F12.h create mode 100644 device/MK64F12_features.h create mode 100644 device/fsl_device_registers.h create mode 100644 device/system_MK64F12.c create mode 100644 device/system_MK64F12.h create mode 100644 drivers/fsl_clock.c create mode 100644 drivers/fsl_clock.h create mode 100644 drivers/fsl_common.c create mode 100644 drivers/fsl_common.h create mode 100644 drivers/fsl_sdhc.c create mode 100644 drivers/fsl_sdhc.h create mode 100644 drivers/fsl_wdog.c create mode 100644 drivers/fsl_wdog.h create mode 100644 osa/usb_osa.h create mode 100644 osa/usb_osa_bm.c create mode 100644 osa/usb_osa_bm.h create mode 100644 redlib/include/assert.h create mode 100644 redlib/include/ctype.h create mode 100644 redlib/include/errno.h create mode 100644 redlib/include/float.h create mode 100644 redlib/include/limits.h create mode 100644 redlib/include/locale.h create mode 100644 redlib/include/math.h create mode 100644 redlib/include/setjmp.h create mode 100644 redlib/include/signal.h create mode 100644 redlib/include/stdarg.h create mode 100644 redlib/include/stdbool.h create mode 100644 redlib/include/stddef.h create mode 100644 redlib/include/stdint.h create mode 100644 redlib/include/stdio.h create mode 100644 redlib/include/stdlib.h create mode 100644 redlib/include/string.h create mode 100644 redlib/include/sys/libconfig-arm.h create mode 100644 redlib/include/sys/libconfig.h create mode 100644 redlib/include/sys/redlib_version.h create mode 100644 redlib/include/time.h create mode 100644 source/API/ADCAPI.h create mode 100644 source/API/CEMAPI.h create mode 100644 source/API/CTRLAPI.h create mode 100644 source/API/DACAPI.h create mode 100644 source/API/DIAGAPI.h create mode 100644 source/API/IICAPI.h create mode 100644 source/API/IOAPI.h create mode 100644 source/API/MAPSAPI.h create mode 100644 source/API/PIMAPI.h create mode 100644 source/API/PROTAPI.h create mode 100644 source/API/RESAPI.h create mode 100644 source/API/SPREADSAPI.h create mode 100644 source/API/SYSAPI.h create mode 100644 source/API/TABLESAPI.h create mode 100644 source/API/TASKAPI.h create mode 100644 source/API/TEPMAPI.h create mode 100644 source/Client/AFM.c create mode 100644 source/Client/AFM.h create mode 100644 source/Client/ATS.c create mode 100644 source/Client/ATS.h create mode 100644 source/Client/BOOSTED.c create mode 100644 source/Client/BOOSTED.h create mode 100644 source/Client/BVM.c create mode 100644 source/Client/BVM.h create mode 100644 source/Client/CAM.c create mode 100644 source/Client/CAM.h create mode 100644 source/Client/CLO2.c create mode 100644 source/Client/CLO2.h create mode 100644 source/Client/CONV.c create mode 100644 source/Client/CONV.h create mode 100644 source/Client/CTS.c create mode 100644 source/Client/CTS.h create mode 100644 source/Client/DIAG.c create mode 100644 source/Client/DIAG.h create mode 100644 source/Client/EST.c create mode 100644 source/Client/EST.h create mode 100644 source/Client/FILM.c create mode 100644 source/Client/FILM.h create mode 100644 source/Client/FME.c create mode 100644 source/Client/FME.h create mode 100644 source/Client/FUEL.c create mode 100644 source/Client/FUEL.h create mode 100644 source/Client/GENDATA.c create mode 100644 source/Client/GENDATA.h create mode 100644 source/Client/IAC.c create mode 100644 source/Client/IAC.h create mode 100644 source/Client/LSU4X.c create mode 100644 source/Client/LSU4X.h create mode 100644 source/Client/LSUH.c create mode 100644 source/Client/LSUH.h create mode 100644 source/Client/MAP.c create mode 100644 source/Client/MAP.h create mode 100644 source/Client/MCP23S08.c create mode 100644 source/Client/MCP23S08.h create mode 100644 source/Client/RELAYS.c create mode 100644 source/Client/RELAYS.h create mode 100644 source/Client/SENSORS.c create mode 100644 source/Client/SENSORS.h create mode 100644 source/Client/SETUP.c create mode 100644 source/Client/SETUP.h create mode 100644 source/Client/TORQUE.c create mode 100644 source/Client/TORQUE.h create mode 100644 source/Client/TPS.c create mode 100644 source/Client/TPS.h create mode 100644 source/Client/Test_60_M2.h create mode 100644 source/Client/UNITS.c create mode 100644 source/Client/UNITS.h create mode 100644 source/Client/USER.c create mode 100644 source/Client/USER.h create mode 100644 source/Client/USERCAL.c create mode 100644 source/Client/USERCAL.h create mode 100644 source/Client/USERMAIN.c create mode 100644 source/Client/USERMATH.c create mode 100644 source/Client/USERMATH.h create mode 100644 source/Client/golf_mk6.h create mode 100644 source/GenericDrivers/diskio.h create mode 100644 source/GenericDrivers/ff.c create mode 100644 source/GenericDrivers/ff.h create mode 100644 source/KernelServices/CBYTEQUEUE.h create mode 100644 source/KernelServices/COMMONNL.h create mode 100644 source/KernelServices/DISK.c create mode 100644 source/KernelServices/DISK.h create mode 100644 source/KernelServices/DLL.c create mode 100644 source/KernelServices/DSCRIO.c create mode 100644 source/KernelServices/DSCRIO.h create mode 100644 source/KernelServices/DSCRIOHA.c create mode 100644 source/KernelServices/DSCRIOHA.h create mode 100644 source/KernelServices/KERNELDIAG.c create mode 100644 source/KernelServices/KERNELDIAG.h create mode 100644 source/KernelServices/KERNELIO.c create mode 100644 source/KernelServices/KERNELIO.h create mode 100644 source/KernelServices/PACKEDDLL.c create mode 100644 source/KernelServices/PACKEDDLL.h create mode 100644 source/KernelServices/PIM.c create mode 100644 source/KernelServices/PIM.h create mode 100644 source/KernelServices/PIMHA.c create mode 100644 source/KernelServices/PIMHA.h create mode 100644 source/KernelServices/PIT.c create mode 100644 source/KernelServices/PIT.h create mode 100644 source/KernelServices/RESM.c create mode 100644 source/KernelServices/RESM.h create mode 100644 source/KernelServices/SIM.c create mode 100644 source/KernelServices/SIM.h create mode 100644 source/KernelServices/SIMHA.c create mode 100644 source/KernelServices/SIMHA.h create mode 100644 source/KernelServices/TIMER.c create mode 100644 source/KernelServices/TIMER.h create mode 100644 source/KernelServices/dll.h create mode 100644 source/KernelServices/ffconf.h create mode 100644 source/KernelServices/regset.c create mode 100644 source/KernelServices/regset.h create mode 100644 source/LegacyDrivers/include/FTFx_FX_256K_32K_2K_1K_1K.h create mode 100644 source/LegacyDrivers/include/FTFx_JX_128K_32K_2K_1K_1K.h create mode 100644 source/LegacyDrivers/include/FTFx_KX_(128_64_32)K_0K_0K_1K_0K.h create mode 100644 source/LegacyDrivers/include/FTFx_KX_(128_64_32)K_32K_2K_1K_1K.h create mode 100644 source/LegacyDrivers/include/FTFx_KX_(256_128_64)K_32K_2K_2K_1K.h create mode 100644 source/LegacyDrivers/include/FTFx_KX_1024K_0K_16K_4K_0K.h create mode 100644 source/LegacyDrivers/include/FTFx_KX_256K_256K_4K_2K_2K.h create mode 100644 source/LegacyDrivers/include/FTFx_KX_512K_0K_0K_2K_0K.h create mode 100644 source/LegacyDrivers/include/FTFx_KX_512K_512K_16K_4K_4K.h create mode 100644 source/LegacyDrivers/include/FTFx_LX_(128_64_32_16_8)K_0K_0K_1K_0K.h create mode 100644 source/LegacyDrivers/include/FTFx_NX_(256_128_96_64)K_32K_2K_2K_1K.h create mode 100644 source/LegacyDrivers/include/SSD_FTFx.h create mode 100644 source/LegacyDrivers/include/SSD_FTFx_Common.h create mode 100644 source/LegacyDrivers/include/SSD_FTFx_Device.h create mode 100644 source/LegacyDrivers/include/SSD_FTFx_Internal.h create mode 100644 source/LegacyDrivers/include/SSD_Types.h create mode 100644 source/LegacyDrivers/include/diskio.h create mode 100644 source/LegacyDrivers/include/enet.h create mode 100644 source/LegacyDrivers/include/eth.h create mode 100644 source/LegacyDrivers/include/eth_phy.h create mode 100644 source/LegacyDrivers/include/integer.h create mode 100644 source/LegacyDrivers/include/mii.h create mode 100644 source/LegacyDrivers/include/nbuf.h create mode 100644 source/LegacyDrivers/include/usb_device_descriptor.h create mode 100644 source/LegacyDrivers/source/DEFlashPartition.c create mode 100644 source/LegacyDrivers/source/DFlashGetProtection.c create mode 100644 source/LegacyDrivers/source/DFlashSetProtection.c create mode 100644 source/LegacyDrivers/source/EEEWrite.c create mode 100644 source/LegacyDrivers/source/EERAMGetProtection.c create mode 100644 source/LegacyDrivers/source/EERAMSetProtection.c create mode 100644 source/LegacyDrivers/source/FTFx_KX_256K_256K_4K_2K_2K.h create mode 100644 source/LegacyDrivers/source/FlashCheckSum.c create mode 100644 source/LegacyDrivers/source/FlashCommandSequence.c create mode 100644 source/LegacyDrivers/source/FlashEraseAllBlock.c create mode 100644 source/LegacyDrivers/source/FlashEraseBlock.c create mode 100644 source/LegacyDrivers/source/FlashEraseResume.c create mode 100644 source/LegacyDrivers/source/FlashEraseSector.c create mode 100644 source/LegacyDrivers/source/FlashEraseSuspend.c create mode 100644 source/LegacyDrivers/source/FlashGetInterruptEnable.c create mode 100644 source/LegacyDrivers/source/FlashGetSecurityState.c create mode 100644 source/LegacyDrivers/source/FlashInit.c create mode 100644 source/LegacyDrivers/source/FlashProgramCheck.c create mode 100644 source/LegacyDrivers/source/FlashProgramLongword.c create mode 100644 source/LegacyDrivers/source/FlashProgramOnce.c create mode 100644 source/LegacyDrivers/source/FlashProgramPhrase.c create mode 100644 source/LegacyDrivers/source/FlashProgramSection.c create mode 100644 source/LegacyDrivers/source/FlashReadOnce.c create mode 100644 source/LegacyDrivers/source/FlashReadResource.c create mode 100644 source/LegacyDrivers/source/FlashSecurityBypass.c create mode 100644 source/LegacyDrivers/source/FlashSetInterruptEnable.c create mode 100644 source/LegacyDrivers/source/FlashVerifyAllBlock.c create mode 100644 source/LegacyDrivers/source/FlashVerifyBlock.c create mode 100644 source/LegacyDrivers/source/FlashVerifySection.c create mode 100644 source/LegacyDrivers/source/NormalDemo.h create mode 100644 source/LegacyDrivers/source/PFlashGetProtection.c create mode 100644 source/LegacyDrivers/source/PFlashGetSwapStatus.c create mode 100644 source/LegacyDrivers/source/PFlashSetProtection.c create mode 100644 source/LegacyDrivers/source/PFlashSwap.c create mode 100644 source/LegacyDrivers/source/SetEEEEnable.c create mode 100644 source/LegacyDrivers/source/usb_device_descriptor.c create mode 100644 source/MK64FX512xxx12_Project.c create mode 100644 source/OS/CLIENT.c create mode 100644 source/OS/CLIENT.h create mode 100644 source/OS/MSG.c create mode 100644 source/OS/MSG.h create mode 100644 source/OS/OS.c create mode 100644 source/OS/OS.h create mode 100644 source/OS/OSHA.h create mode 100644 source/OS/OSTASKS.h create mode 100644 source/OS/STACK.c create mode 100644 source/OS/STACK.h create mode 100644 source/OS/TASK.c create mode 100644 source/OS/TASK.h create mode 100644 source/OS/THREAD.c create mode 100644 source/OS/THREAD.h create mode 100644 source/OS/tqueue.c create mode 100644 source/OS/tqueue.h create mode 100644 source/OS/tqueueHA.c create mode 100644 source/OS/tqueueHA.h create mode 100644 source/Peripherals/ADCHA.c create mode 100644 source/Peripherals/ADCHA.h create mode 100644 source/Peripherals/CANHA.c create mode 100644 source/Peripherals/CANHA.h create mode 100644 source/Peripherals/CRC16.c create mode 100644 source/Peripherals/CRC16.h create mode 100644 source/Peripherals/CRC16HA.c create mode 100644 source/Peripherals/CRC16HA.h create mode 100644 source/Peripherals/DAC.c create mode 100644 source/Peripherals/DAC.h create mode 100644 source/Peripherals/DACHA.c create mode 100644 source/Peripherals/DACHA.h create mode 100644 source/Peripherals/FEE.c create mode 100644 source/Peripherals/FEE.h create mode 100644 source/Peripherals/FEEHA.c create mode 100644 source/Peripherals/FEEHA.h create mode 100644 source/Peripherals/IIC.c create mode 100644 source/Peripherals/IIC.h create mode 100644 source/Peripherals/IICHA.c create mode 100644 source/Peripherals/IICHA.h create mode 100644 source/Peripherals/PERADC.c create mode 100644 source/Peripherals/PERCAN.c create mode 100644 source/Peripherals/PERCAN.h create mode 100644 source/Peripherals/PERSPI.c create mode 100644 source/Peripherals/PERSPI.h create mode 100644 source/Peripherals/PERUART.c create mode 100644 source/Peripherals/PERUART.h create mode 100644 source/Peripherals/PERUSB.c create mode 100644 source/Peripherals/PERUSB.h create mode 100644 source/Peripherals/PERWDT.c create mode 100644 source/Peripherals/PERWDT.h create mode 100644 source/Peripherals/SDHC.c create mode 100644 source/Peripherals/SDHC.h create mode 100644 source/Peripherals/SDHC1HA.c create mode 100644 source/Peripherals/SDHC1HA.h create mode 100644 source/Peripherals/SDHCHA.c create mode 100644 source/Peripherals/SDHCHA.h create mode 100644 source/Peripherals/SPIHA.c create mode 100644 source/Peripherals/SPIHA.h create mode 100644 source/Peripherals/SRLTFR.c create mode 100644 source/Peripherals/SRLTFR.h create mode 100644 source/Peripherals/TIME.c create mode 100644 source/Peripherals/TIME.h create mode 100644 source/Peripherals/UARTHA.c create mode 100644 source/Peripherals/UARTHA.h create mode 100644 source/Peripherals/USBHA.c create mode 100644 source/Peripherals/USBHA.h create mode 100644 source/Peripherals/VCOMHA.c create mode 100644 source/Peripherals/VCOMHA.h create mode 100644 source/Peripherals/WDTHA.c create mode 100644 source/Peripherals/WDTHA.h create mode 100644 source/Peripherals/peradc.h create mode 100644 source/Suites/UDS/Include/UDSAL.h create mode 100644 source/Suites/UDS/Include/UDSNL.h create mode 100644 source/Suites/UDS/Include/UDSSL.h create mode 100644 source/Suites/UDS/UDSAL.c create mode 100644 source/Suites/UDS/UDSNL.c create mode 100644 source/Suites/UDS/UDSSL.c create mode 100644 source/Support/BUILD.h create mode 100644 source/Support/CQUEUE.h create mode 100644 source/Support/DECLARATIONS.h create mode 100644 source/Support/MACROS.h create mode 100644 source/Support/MATH.c create mode 100644 source/Support/MATH.h create mode 100644 source/System/CPUAbstract.c create mode 100644 source/System/CPUAbstract.h create mode 100644 source/System/ECUHostMain.c create mode 100644 source/System/IRQ.c create mode 100644 source/System/IRQ.h create mode 100644 source/System/SYS.h create mode 100644 source/System/SYSAPI.c create mode 100644 source/System/SYSAbstract.h create mode 100644 source/System/TYPES.h create mode 100644 source/UserServices/CEM.c create mode 100644 source/UserServices/CEM.h create mode 100644 source/UserServices/CTRL.c create mode 100644 source/UserServices/CTRL.h create mode 100644 source/UserServices/SPREADS.c create mode 100644 source/UserServices/SPREADS.h create mode 100644 source/UserServices/TABLES.c create mode 100644 source/UserServices/TABLES.h create mode 100644 source/UserServices/TEPM.c create mode 100644 source/UserServices/TEPM.h create mode 100644 source/UserServices/TEPMHA.c create mode 100644 source/UserServices/TEPMHA.h create mode 100644 source/UserServices/maps.c create mode 100644 source/UserServices/maps.h create mode 100644 source/generated/usb_device_config.h create mode 100644 source/semihost_hardfault.c create mode 100644 startup/startup_mk64f12.c create mode 100644 usb/device/class/usb_device_audio.c create mode 100644 usb/device/class/usb_device_audio.h create mode 100644 usb/device/class/usb_device_ccid.c create mode 100644 usb/device/class/usb_device_ccid.h create mode 100644 usb/device/class/usb_device_cdc_acm.c create mode 100644 usb/device/class/usb_device_cdc_acm.h create mode 100644 usb/device/class/usb_device_cdc_rndis.c create mode 100644 usb/device/class/usb_device_cdc_rndis.h create mode 100644 usb/device/class/usb_device_class.c create mode 100644 usb/device/class/usb_device_class.h create mode 100644 usb/device/class/usb_device_hid.c create mode 100644 usb/device/class/usb_device_hid.h create mode 100644 usb/device/class/usb_device_msc.c create mode 100644 usb/device/class/usb_device_msc.h create mode 100644 usb/device/class/usb_device_msc_ufi.c create mode 100644 usb/device/class/usb_device_msc_ufi.h create mode 100644 usb/device/class/usb_device_phdc.c create mode 100644 usb/device/class/usb_device_phdc.h create mode 100644 usb/device/class/usb_device_printer.c create mode 100644 usb/device/class/usb_device_printer.h create mode 100644 usb/device/class/usb_device_video.c create mode 100644 usb/device/class/usb_device_video.h create mode 100644 usb/device/include/usb_device.h create mode 100644 usb/device/source/ehci/usb_device_ehci.c create mode 100644 usb/device/source/ehci/usb_device_ehci.h create mode 100644 usb/device/source/khci/usb_device_khci.c create mode 100644 usb/device/source/khci/usb_device_khci.h create mode 100644 usb/device/source/lpcip3511/usb_device_lpcip3511.c create mode 100644 usb/device/source/lpcip3511/usb_device_lpcip3511.h create mode 100644 usb/device/source/usb_device_ch9.c create mode 100644 usb/device/source/usb_device_ch9.h create mode 100644 usb/device/source/usb_device_dci.c create mode 100644 usb/device/source/usb_device_dci.h create mode 100644 usb/include/usb.h create mode 100644 usb/include/usb_misc.h create mode 100644 usb/include/usb_spec.h create mode 100644 usb/phy/usb_phy.c create mode 100644 usb/phy/usb_phy.h diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml new file mode 100644 index 0000000..c3d6f94 --- /dev/null +++ b/.settings/language.settings.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/.settings/org.eclipse.cdt.managedbuilder.core.prefs b/.settings/org.eclipse.cdt.managedbuilder.core.prefs new file mode 100644 index 0000000..d829c00 --- /dev/null +++ b/.settings/org.eclipse.cdt.managedbuilder.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +environment/buildEnvironmentInclude/com.crt.advproject.config.exe.debug.1158252545/CPATH/delimiter=; +environment/buildEnvironmentInclude/com.crt.advproject.config.exe.debug.1158252545/CPATH/operation=remove +environment/buildEnvironmentInclude/com.crt.advproject.config.exe.debug.1158252545/C_INCLUDE_PATH/delimiter=; +environment/buildEnvironmentInclude/com.crt.advproject.config.exe.debug.1158252545/C_INCLUDE_PATH/operation=remove +environment/buildEnvironmentInclude/com.crt.advproject.config.exe.debug.1158252545/append=true +environment/buildEnvironmentInclude/com.crt.advproject.config.exe.debug.1158252545/appendContributed=true +environment/buildEnvironmentLibrary/com.crt.advproject.config.exe.debug.1158252545/LIBRARY_PATH/delimiter=; +environment/buildEnvironmentLibrary/com.crt.advproject.config.exe.debug.1158252545/LIBRARY_PATH/operation=remove +environment/buildEnvironmentLibrary/com.crt.advproject.config.exe.debug.1158252545/append=true +environment/buildEnvironmentLibrary/com.crt.advproject.config.exe.debug.1158252545/appendContributed=true diff --git a/CMSIS/arm_common_tables.h b/CMSIS/arm_common_tables.h new file mode 100644 index 0000000..dfea746 --- /dev/null +++ b/CMSIS/arm_common_tables.h @@ -0,0 +1,121 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_common_tables.h + * Description: Extern declaration for common tables + * + * $Date: 27. January 2017 + * $Revision: V.1.5.1 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ARM_COMMON_TABLES_H +#define _ARM_COMMON_TABLES_H + +#include "arm_math.h" + +extern const uint16_t armBitRevTable[1024]; +extern const q15_t armRecipTableQ15[64]; +extern const q31_t armRecipTableQ31[64]; +extern const float32_t twiddleCoef_16[32]; +extern const float32_t twiddleCoef_32[64]; +extern const float32_t twiddleCoef_64[128]; +extern const float32_t twiddleCoef_128[256]; +extern const float32_t twiddleCoef_256[512]; +extern const float32_t twiddleCoef_512[1024]; +extern const float32_t twiddleCoef_1024[2048]; +extern const float32_t twiddleCoef_2048[4096]; +extern const float32_t twiddleCoef_4096[8192]; +#define twiddleCoef twiddleCoef_4096 +extern const q31_t twiddleCoef_16_q31[24]; +extern const q31_t twiddleCoef_32_q31[48]; +extern const q31_t twiddleCoef_64_q31[96]; +extern const q31_t twiddleCoef_128_q31[192]; +extern const q31_t twiddleCoef_256_q31[384]; +extern const q31_t twiddleCoef_512_q31[768]; +extern const q31_t twiddleCoef_1024_q31[1536]; +extern const q31_t twiddleCoef_2048_q31[3072]; +extern const q31_t twiddleCoef_4096_q31[6144]; +extern const q15_t twiddleCoef_16_q15[24]; +extern const q15_t twiddleCoef_32_q15[48]; +extern const q15_t twiddleCoef_64_q15[96]; +extern const q15_t twiddleCoef_128_q15[192]; +extern const q15_t twiddleCoef_256_q15[384]; +extern const q15_t twiddleCoef_512_q15[768]; +extern const q15_t twiddleCoef_1024_q15[1536]; +extern const q15_t twiddleCoef_2048_q15[3072]; +extern const q15_t twiddleCoef_4096_q15[6144]; +extern const float32_t twiddleCoef_rfft_32[32]; +extern const float32_t twiddleCoef_rfft_64[64]; +extern const float32_t twiddleCoef_rfft_128[128]; +extern const float32_t twiddleCoef_rfft_256[256]; +extern const float32_t twiddleCoef_rfft_512[512]; +extern const float32_t twiddleCoef_rfft_1024[1024]; +extern const float32_t twiddleCoef_rfft_2048[2048]; +extern const float32_t twiddleCoef_rfft_4096[4096]; + +/* floating-point bit reversal tables */ +#define ARMBITREVINDEXTABLE_16_TABLE_LENGTH ((uint16_t)20) +#define ARMBITREVINDEXTABLE_32_TABLE_LENGTH ((uint16_t)48) +#define ARMBITREVINDEXTABLE_64_TABLE_LENGTH ((uint16_t)56) +#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208) +#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440) +#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448) +#define ARMBITREVINDEXTABLE_1024_TABLE_LENGTH ((uint16_t)1800) +#define ARMBITREVINDEXTABLE_2048_TABLE_LENGTH ((uint16_t)3808) +#define ARMBITREVINDEXTABLE_4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE_16_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE_32_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE_64_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE_1024_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE_2048_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE_4096_TABLE_LENGTH]; + +/* fixed-point bit reversal tables */ +#define ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH ((uint16_t)12) +#define ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH ((uint16_t)24) +#define ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH ((uint16_t)56) +#define ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH ((uint16_t)112) +#define ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH ((uint16_t)240) +#define ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH ((uint16_t)480) +#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992) +#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) +#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED_16_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED_32_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED_64_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED_128_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED_256_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED_512_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; + +/* Tables for Fast Math Sine and Cosine */ +extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; +extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1]; +extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1]; + +#endif /* ARM_COMMON_TABLES_H */ diff --git a/CMSIS/arm_const_structs.h b/CMSIS/arm_const_structs.h new file mode 100644 index 0000000..80a3e8b --- /dev/null +++ b/CMSIS/arm_const_structs.h @@ -0,0 +1,66 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS DSP Library + * Title: arm_const_structs.h + * Description: Constant structs that are initialized for user convenience. + * For example, some can be given as arguments to the arm_cfft_f32() function. + * + * $Date: 27. January 2017 + * $Revision: V.1.5.1 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ARM_CONST_STRUCTS_H +#define _ARM_CONST_STRUCTS_H + +#include "arm_math.h" +#include "arm_common_tables.h" + + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096; + + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096; + + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096; + +#endif diff --git a/CMSIS/arm_math.h b/CMSIS/arm_math.h new file mode 100644 index 0000000..62f87be --- /dev/null +++ b/CMSIS/arm_math.h @@ -0,0 +1,7160 @@ +/****************************************************************************** + * @file arm_math.h + * @brief Public header file for CMSIS DSP LibraryU + * @version V1.5.3 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + \mainpage CMSIS DSP Software Library + * + * Introduction + * ------------ + * + * This user manual describes the CMSIS DSP software library, + * a suite of common signal processing functions for use on Cortex-M processor based devices. + * + * The library is divided into a number of functions each covering a specific category: + * - Basic math functions + * - Fast math functions + * - Complex math functions + * - Filters + * - Matrix functions + * - Transforms + * - Motor control functions + * - Statistical functions + * - Support functions + * - Interpolation functions + * + * The library has separate functions for operating on 8-bit integers, 16-bit integers, + * 32-bit integer and 32-bit floating-point values. + * + * Using the Library + * ------------ + * + * The library installer contains prebuilt versions of the libraries in the Lib folder. + * - arm_cortexM7lfdp_math.lib (Cortex-M7, Little endian, Double Precision Floating Point Unit) + * - arm_cortexM7bfdp_math.lib (Cortex-M7, Big endian, Double Precision Floating Point Unit) + * - arm_cortexM7lfsp_math.lib (Cortex-M7, Little endian, Single Precision Floating Point Unit) + * - arm_cortexM7bfsp_math.lib (Cortex-M7, Big endian and Single Precision Floating Point Unit on) + * - arm_cortexM7l_math.lib (Cortex-M7, Little endian) + * - arm_cortexM7b_math.lib (Cortex-M7, Big endian) + * - arm_cortexM4lf_math.lib (Cortex-M4, Little endian, Floating Point Unit) + * - arm_cortexM4bf_math.lib (Cortex-M4, Big endian, Floating Point Unit) + * - arm_cortexM4l_math.lib (Cortex-M4, Little endian) + * - arm_cortexM4b_math.lib (Cortex-M4, Big endian) + * - arm_cortexM3l_math.lib (Cortex-M3, Little endian) + * - arm_cortexM3b_math.lib (Cortex-M3, Big endian) + * - arm_cortexM0l_math.lib (Cortex-M0 / Cortex-M0+, Little endian) + * - arm_cortexM0b_math.lib (Cortex-M0 / Cortex-M0+, Big endian) + * - arm_ARMv8MBLl_math.lib (Armv8-M Baseline, Little endian) + * - arm_ARMv8MMLl_math.lib (Armv8-M Mainline, Little endian) + * - arm_ARMv8MMLlfsp_math.lib (Armv8-M Mainline, Little endian, Single Precision Floating Point Unit) + * - arm_ARMv8MMLld_math.lib (Armv8-M Mainline, Little endian, DSP instructions) + * - arm_ARMv8MMLldfsp_math.lib (Armv8-M Mainline, Little endian, DSP instructions, Single Precision Floating Point Unit) + * + * The library functions are declared in the public file arm_math.h which is placed in the Include folder. + * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single + * public header file arm_math.h for Cortex-M cores with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. + * Define the appropriate preprocessor macro ARM_MATH_CM7 or ARM_MATH_CM4 or ARM_MATH_CM3 or + * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application. + * For Armv8-M cores define preprocessor macro ARM_MATH_ARMV8MBL or ARM_MATH_ARMV8MML. + * Set preprocessor macro __DSP_PRESENT if Armv8-M Mainline core supports DSP instructions. + * + * + * Examples + * -------- + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * Toolchain Support + * ------------ + * + * The library has been developed and tested with MDK version 5.14.0.0 + * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. + * + * Building the Library + * ------------ + * + * The library installer contains a project file to rebuild libraries on MDK toolchain in the CMSIS\\DSP_Lib\\Source\\ARM folder. + * - arm_cortexM_math.uvprojx + * + * + * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional preprocessor macros detailed above. + * + * Preprocessor Macros + * ------------ + * + * Each library project have different preprocessor macros. + * + * - UNALIGNED_SUPPORT_DISABLE: + * + * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access + * + * - ARM_MATH_BIG_ENDIAN: + * + * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. + * + * - ARM_MATH_MATRIX_CHECK: + * + * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices + * + * - ARM_MATH_ROUNDING: + * + * Define macro ARM_MATH_ROUNDING for rounding on support functions + * + * - ARM_MATH_CMx: + * + * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target + * and ARM_MATH_CM0 for building library on Cortex-M0 target, ARM_MATH_CM0PLUS for building library on Cortex-M0+ target, and + * ARM_MATH_CM7 for building the library on cortex-M7. + * + * - ARM_MATH_ARMV8MxL: + * + * Define macro ARM_MATH_ARMV8MBL for building the library on Armv8-M Baseline target, ARM_MATH_ARMV8MML for building library + * on Armv8-M Mainline target. + * + * - __FPU_PRESENT: + * + * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for floating point libraries. + * + * - __DSP_PRESENT: + * + * Initialize macro __DSP_PRESENT = 1 when Armv8-M Mainline core supports DSP instructions. + * + *
+ * CMSIS-DSP in ARM::CMSIS Pack + * ----------------------------- + * + * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories: + * |File/Folder |Content | + * |------------------------------|------------------------------------------------------------------------| + * |\b CMSIS\\Documentation\\DSP | This documentation | + * |\b CMSIS\\DSP_Lib | Software license agreement (license.txt) | + * |\b CMSIS\\DSP_Lib\\Examples | Example projects demonstrating the usage of the library functions | + * |\b CMSIS\\DSP_Lib\\Source | Source files for rebuilding the library | + * + *
+ * Revision History of CMSIS-DSP + * ------------ + * Please refer to \ref ChangeLog_pg. + * + * Copyright Notice + * ------------ + * + * Copyright (C) 2010-2015 Arm Limited. All rights reserved. + */ + + +/** + * @defgroup groupMath Basic Math Functions + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * This set of functions provides a fast approximation to sine, cosine, and square root. + * As compared to most of the other functions in the CMSIS math library, the fast math functions + * operate on individual values and not arrays. + * There are separate functions for Q15, Q31, and floating-point data. + * + */ + +/** + * @defgroup groupCmplxMath Complex Math Functions + * This set of functions operates on complex data vectors. + * The data in the complex arrays is stored in an interleaved fashion + * (real, imag, real, imag, ...). + * In the API functions, the number of samples in a complex array refers + * to the number of complex values; the array contains twice this number of + * real values. + */ + +/** + * @defgroup groupFilters Filtering Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * + * This set of functions provides basic matrix math operations. + * The functions operate on matrix data structures. For example, + * the type + * definition for the floating-point matrix structure is shown + * below: + *
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } arm_matrix_instance_f32;
+ * 
+ * There are similar definitions for Q15 and Q31 data types. + * + * The structure specifies the size of the matrix and then points to + * an array of data. The array is of size numRows X numCols + * and the values are arranged in row order. That is, the + * matrix element (i, j) is stored at: + *
+ *     pData[i*numCols + j]
+ * 
+ * + * \par Init Functions + * There is an associated initialization function for each type of matrix + * data structure. + * The initialization function sets the values of the internal structure fields. + * Refer to the function arm_mat_init_f32(), arm_mat_init_q31() + * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively. + * + * \par + * Use of the initialization function is optional. However, if initialization function is used + * then the instance structure cannot be placed into a const data section. + * To place the instance structure in a const data + * section, manually initialize the data structure. For example: + *
+ * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
+ * 
+ * where nRows specifies the number of rows, nColumns + * specifies the number of columns, and pData points to the + * data array. + * + * \par Size Checking + * By default all of the matrix functions perform size checking on the input and + * output matrices. For example, the matrix addition function verifies that the + * two input matrices and the output matrix all have the same number of rows and + * columns. If the size check fails the functions return: + *
+ *     ARM_MATH_SIZE_MISMATCH
+ * 
+ * Otherwise the functions return + *
+ *     ARM_MATH_SUCCESS
+ * 
+ * There is some overhead associated with this matrix size checking. + * The matrix size checking is enabled via the \#define + *
+ *     ARM_MATH_MATRIX_CHECK
+ * 
+ * within the library project settings. By default this macro is defined + * and size checking is enabled. By changing the project settings and + * undefining this macro size checking is eliminated and the functions + * run a bit faster. With size checking disabled the functions always + * return ARM_MATH_SUCCESS. + */ + +/** + * @defgroup groupTransforms Transform Functions + */ + +/** + * @defgroup groupController Controller Functions + */ + +/** + * @defgroup groupStats Statistics Functions + */ +/** + * @defgroup groupSupport Support Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * These functions perform 1- and 2-dimensional interpolation of data. + * Linear interpolation is used for 1-dimensional data and + * bilinear interpolation is used for 2-dimensional data. + */ + +/** + * @defgroup groupExamples Examples + */ +#ifndef _ARM_MATH_H +#define _ARM_MATH_H + +/* Compiler specific diagnostic adjustment */ +#if defined ( __CC_ARM ) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + +#elif defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +#elif defined ( __ICCARM__ ) + +#elif defined ( __TI_ARM__ ) + +#elif defined ( __CSMC__ ) + +#elif defined ( __TASKING__ ) + +#else + #error Unknown compiler +#endif + + +#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ + +#if defined(ARM_MATH_CM7) + #include "core_cm7.h" + #define ARM_MATH_DSP +#elif defined (ARM_MATH_CM4) + #include "core_cm4.h" + #define ARM_MATH_DSP +#elif defined (ARM_MATH_CM33) + #include "core_cm33.h" + #define ARM_MATH_DSP +#elif defined (ARM_MATH_CM3) + #include "core_cm3.h" +#elif defined (ARM_MATH_CM0) + #include "core_cm0.h" + #define ARM_MATH_CM0_FAMILY +#elif defined (ARM_MATH_CM0PLUS) + #include "core_cm0plus.h" + #define ARM_MATH_CM0_FAMILY +#elif defined (ARM_MATH_ARMV8MBL) + #include "core_armv8mbl.h" + #define ARM_MATH_CM0_FAMILY +#elif defined (ARM_MATH_ARMV8MML) + #include "core_armv8mml.h" + #if (defined (__DSP_PRESENT) && (__DSP_PRESENT == 1)) + #define ARM_MATH_DSP + #endif +#else + #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS, ARM_MATH_CM0, ARM_MATH_ARMV8MBL, ARM_MATH_ARMV8MML" +#endif + +#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */ +#include "string.h" +#include "math.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 (0x100) +#define DELTA_Q15 0x5 +#define INDEX_MASK 0x0000003F +#ifndef PI + #define PI 3.14159265358979f +#endif + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define FAST_MATH_TABLE_SIZE 512 +#define FAST_MATH_Q31_SHIFT (32 - 10) +#define FAST_MATH_Q15_SHIFT (16 - 10) +#define CONTROLLER_Q31_SHIFT (32 - 9) +#define TABLE_SPACING_Q31 0x400000 +#define TABLE_SPACING_Q15 0x80 + + /** + * @brief Macros required for SINE and COSINE Controller functions + */ + /* 1.31(q31) Fixed value of 2/360 */ + /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + + /** + * @brief Macro for Unaligned Support + */ +#ifndef UNALIGNED_SUPPORT_DISABLE + #define ALIGN4 +#else + #if defined (__GNUC__) + #define ALIGN4 __attribute__((aligned(4))) + #else + #define ALIGN4 __align(4) + #endif +#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + ARM_MATH_SUCCESS = 0, /**< No error */ + ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ + ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ + ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } arm_status; + + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief 64-bit floating-point type definition. + */ + typedef double float64_t; + + /** + * @brief definition to read/write two 16 bit values. + */ +#if defined ( __CC_ARM ) + #define __SIMD32_TYPE int32_t __packed + #define CMSIS_UNUSED __attribute__((unused)) + #define CMSIS_INLINE __attribute__((always_inline)) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + #define CMSIS_INLINE __attribute__((always_inline)) + +#elif defined ( __GNUC__ ) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + #define CMSIS_INLINE __attribute__((always_inline)) + +#elif defined ( __ICCARM__ ) + #define __SIMD32_TYPE int32_t __packed + #define CMSIS_UNUSED + #define CMSIS_INLINE + +#elif defined ( __TI_ARM__ ) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + #define CMSIS_INLINE + +#elif defined ( __CSMC__ ) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED + #define CMSIS_INLINE + +#elif defined ( __TASKING__ ) + #define __SIMD32_TYPE __unaligned int32_t + #define CMSIS_UNUSED + #define CMSIS_INLINE + +#else + #error Unknown compiler +#endif + +#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) +#define __SIMD32_CONST(addr) ((__SIMD32_TYPE *)(addr)) +#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE *) (addr)) +#define __SIMD64(addr) (*(int64_t **) & (addr)) + +#if !defined (ARM_MATH_DSP) + /** + * @brief definition to pack two 16 bit values. + */ +#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) +#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ + (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) + +#endif /* !defined (ARM_MATH_DSP) */ + + /** + * @brief definition to pack four 8 bit values. + */ +#ifndef ARM_MATH_BIG_ENDIAN + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) +#else + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) + +#endif + + + /** + * @brief Clips Q63 to Q31 values. + */ + CMSIS_INLINE __STATIC_INLINE q31_t clip_q63_to_q31( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; + } + + /** + * @brief Clips Q63 to Q15 values. + */ + CMSIS_INLINE __STATIC_INLINE q15_t clip_q63_to_q15( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); + } + + /** + * @brief Clips Q31 to Q7 values. + */ + CMSIS_INLINE __STATIC_INLINE q7_t clip_q31_to_q7( + q31_t x) + { + return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? + ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; + } + + /** + * @brief Clips Q31 to Q15 values. + */ + CMSIS_INLINE __STATIC_INLINE q15_t clip_q31_to_q15( + q31_t x) + { + return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? + ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; + } + + /** + * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. + */ + + CMSIS_INLINE __STATIC_INLINE q63_t mult32x64( + q63_t x, + q31_t y) + { + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y))); + } + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. + */ + + CMSIS_INLINE __STATIC_INLINE uint32_t arm_recip_q31( + q31_t in, + q31_t * dst, + q31_t * pRecipTable) + { + q31_t out; + uint32_t tempVal; + uint32_t index, i; + uint32_t signBits; + + if (in > 0) + { + signBits = ((uint32_t) (__CLZ( in) - 1)); + } + else + { + signBits = ((uint32_t) (__CLZ(-in) - 1)); + } + + /* Convert input sample to 1.31 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 24); + index = (index & INDEX_MASK); + + /* 1.31 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0U; i < 2U; i++) + { + tempVal = (uint32_t) (((q63_t) in * out) >> 31); + tempVal = 0x7FFFFFFFu - tempVal; + /* 1.31 with exp 1 */ + /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */ + out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1U); + } + + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type. + */ + CMSIS_INLINE __STATIC_INLINE uint32_t arm_recip_q15( + q15_t in, + q15_t * dst, + q15_t * pRecipTable) + { + q15_t out = 0; + uint32_t tempVal = 0; + uint32_t index = 0, i = 0; + uint32_t signBits = 0; + + if (in > 0) + { + signBits = ((uint32_t)(__CLZ( in) - 17)); + } + else + { + signBits = ((uint32_t)(__CLZ(-in) - 17)); + } + + /* Convert input sample to 1.15 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 8); + index = (index & INDEX_MASK); + + /* 1.15 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0U; i < 2U; i++) + { + tempVal = (uint32_t) (((q31_t) in * out) >> 15); + tempVal = 0x7FFFu - tempVal; + /* 1.15 with exp 1 */ + out = (q15_t) (((q31_t) out * tempVal) >> 14); + /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */ + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1); + } + + +/* + * @brief C custom defined intrinsic function for M3 and M0 processors + */ +#if !defined (ARM_MATH_DSP) + + /* + * @brief C custom defined QADD8 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QADD8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QSUB8 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QSUB8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QADD16( + uint32_t x, + uint32_t y) + { +/* q31_t r, s; without initialisation 'arm_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */ + q31_t r = 0, s = 0; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHADD16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SHADD16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSUB16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSUB16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SHSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QASX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHASX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SHASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSAX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __QSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSAX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SHSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SMUSDX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMUSDX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + /* + * @brief C custom defined SMUADX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMUADX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + + /* + * @brief C custom defined QADD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE int32_t __QADD( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y))); + } + + + /* + * @brief C custom defined QSUB for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE int32_t __QSUB( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y))); + } + + + /* + * @brief C custom defined SMLAD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMLAD( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLADX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMLADX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLSDX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMLSDX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint64_t __SMLALD( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALDX for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint64_t __SMLALDX( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMUAD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMUAD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SMUSD for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SMUSD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SXTB16 for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE uint32_t __SXTB16( + uint32_t x) + { + return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) | + ((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) )); + } + + /* + * @brief C custom defined SMMLA for M3 and M0 processors + */ + CMSIS_INLINE __STATIC_INLINE int32_t __SMMLA( + int32_t x, + int32_t y, + int32_t sum) + { + return (sum + (int32_t) (((int64_t) x * y) >> 32)); + } + +#endif /* !defined (ARM_MATH_DSP) */ + + + /** + * @brief Instance structure for the Q7 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q7; + + /** + * @brief Instance structure for the Q15 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_f32; + + + /** + * @brief Processing function for the Q7 FIR filter. + * @param[in] S points to an instance of the Q7 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q7( + const arm_fir_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 FIR filter. + * @param[in,out] S points to an instance of the Q7 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed. + */ + void arm_fir_init_q7( + arm_fir_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR filter. + * @param[in] S points to an instance of the Q15 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR filter. + * @param[in,out] S points to an instance of the Q15 FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if + * numTaps is not a supported value. + */ + arm_status arm_fir_init_q15( + arm_fir_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR filter. + * @param[in] S points to an instance of the Q31 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR filter. + * @param[in,out] S points to an instance of the Q31 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_q31( + arm_fir_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR filter. + * @param[in] S points to an instance of the floating-point FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_f32( + const arm_fir_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR filter. + * @param[in,out] S points to an instance of the floating-point FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_f32( + arm_fir_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ + typedef struct + { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q15; + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q31; + + /** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_casd_df1_inst_f32; + + + /** + * @brief Processing function for the Q15 Biquad cascade filter. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q15( + arm_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + + + /** + * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 Biquad cascade filter + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q31( + arm_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + + + /** + * @brief Processing function for the floating-point Biquad cascade filter. + * @param[in] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_f32( + const arm_biquad_casd_df1_inst_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point Biquad cascade filter. + * @param[in,out] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df1_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f32; + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float64_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f64; + + /** + * @brief Instance structure for the Q15 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q15; + + /** + * @brief Instance structure for the Q31 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q31; + + + /** + * @brief Floating-point matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pScratch); + + + /** + * @brief Q31, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_q15( + const arm_matrix_instance_q15 * pSrc, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_q31( + const arm_matrix_instance_q31 * pSrc, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + + /** + * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_fast_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + + /** + * @brief Q31 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_fast_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix scaling. + * @param[in] pSrc points to the input matrix + * @param[in] scale scale factor + * @param[out] pDst points to the output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_f32( + const arm_matrix_instance_f32 * pSrc, + float32_t scale, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_q15( + const arm_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_q31( + const arm_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_q31( + arm_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData); + + + /** + * @brief Q15 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_q15( + arm_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData); + + + /** + * @brief Floating-point matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_f32( + arm_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData); + + + + /** + * @brief Instance structure for the Q15 PID Control. + */ + typedef struct + { + q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ +#if !defined (ARM_MATH_DSP) + q15_t A1; + q15_t A2; +#else + q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ +#endif + q15_t state[3]; /**< The state array of length 3. */ + q15_t Kp; /**< The proportional gain. */ + q15_t Ki; /**< The integral gain. */ + q15_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q15; + + /** + * @brief Instance structure for the Q31 PID Control. + */ + typedef struct + { + q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + q31_t A2; /**< The derived gain, A2 = Kd . */ + q31_t state[3]; /**< The state array of length 3. */ + q31_t Kp; /**< The proportional gain. */ + q31_t Ki; /**< The integral gain. */ + q31_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q31; + + /** + * @brief Instance structure for the floating-point PID Control. + */ + typedef struct + { + float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + float32_t A2; /**< The derived gain, A2 = Kd . */ + float32_t state[3]; /**< The state array of length 3. */ + float32_t Kp; /**< The proportional gain. */ + float32_t Ki; /**< The integral gain. */ + float32_t Kd; /**< The derivative gain. */ + } arm_pid_instance_f32; + + + + /** + * @brief Initialization function for the floating-point PID Control. + * @param[in,out] S points to an instance of the PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_f32( + arm_pid_instance_f32 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + */ + void arm_pid_reset_f32( + arm_pid_instance_f32 * S); + + + /** + * @brief Initialization function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q31( + arm_pid_instance_q31 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + */ + + void arm_pid_reset_q31( + arm_pid_instance_q31 * S); + + + /** + * @brief Initialization function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q15( + arm_pid_instance_q15 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q15 PID Control. + * @param[in,out] S points to an instance of the q15 PID Control structure + */ + void arm_pid_reset_q15( + arm_pid_instance_q15 * S); + + + /** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ + typedef struct + { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ + } arm_linear_interp_instance_f32; + + /** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_f32; + + /** + * @brief Instance structure for the Q31 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q31; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q15; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q7; + + + /** + * @brief Q7 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q15( + arm_cfft_radix2_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q15( + const arm_cfft_radix2_instance_q15 * S, + q15_t * pSrc); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q31; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q31( + arm_cfft_radix2_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q31( + const arm_cfft_radix2_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q31; + +/* Deprecated */ + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix2_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_f32( + arm_cfft_radix2_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_f32( + const arm_cfft_radix2_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix4_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q15; + +void arm_cfft_q15( + const arm_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q31; + +void arm_cfft_q31( + const arm_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_f32; + + void arm_cfft_f32( + const arm_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q15; + + arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q31; + + arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_f32; + + arm_status arm_rfft_init_f32( + arm_rfft_instance_f32 * S, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ +typedef struct + { + arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } arm_rfft_fast_instance_f32 ; + +arm_status arm_rfft_fast_init_f32 ( + arm_rfft_fast_instance_f32 * S, + uint16_t fftLen); + +void arm_rfft_fast_f32( + arm_rfft_fast_instance_f32 * S, + float32_t * p, float32_t * pOut, + uint8_t ifftFlag); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + float32_t *pTwiddle; /**< points to the twiddle factor table. */ + float32_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_f32; + + + /** + * @brief Initialization function for the floating-point DCT4/IDCT4. + * @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. + */ + arm_status arm_dct4_init_f32( + arm_dct4_instance_f32 * S, + arm_rfft_instance_f32 * S_RFFT, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + + /** + * @brief Processing function for the floating-point DCT4/IDCT4. + * @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_f32( + const arm_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + q31_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q31; + + + /** + * @brief Initialization function for the Q31 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q31 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q31 RFFT/RIFFT structure + * @param[in] S_CFFT points to an instance of Q31 CFFT/CIFFT structure + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q31( + arm_dct4_instance_q31 * S, + arm_rfft_instance_q31 * S_RFFT, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + + /** + * @brief Processing function for the Q31 DCT4/IDCT4. + * @param[in] S points to an instance of the Q31 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q31( + const arm_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + q15_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q15; + + + /** + * @brief Initialization function for the Q15 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q15 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q15 RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of Q15 CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q15( + arm_dct4_instance_q15 * S, + arm_rfft_instance_q15 * S_RFFT, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + + /** + * @brief Processing function for the Q15 DCT4/IDCT4. + * @param[in] S points to an instance of the Q15 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q15( + const arm_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + + /** + * @brief Floating-point vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a floating-point vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scale scale factor to be applied + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_f32( + float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q7 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q7( + q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q15 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q15( + q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q31 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q31( + q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Dot product of floating-point vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + + /** + * @brief Dot product of Q7 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q7( + q7_t * pSrcA, + q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + + /** + * @brief Dot product of Q15 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Dot product of Q31 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Shifts the elements of a Q7 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q7( + q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q15 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q15( + q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q31 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q31( + q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_f32( + float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q7( + q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q15( + q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q31( + q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a floating-point vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q7 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a floating-point vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q7 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q15 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q31 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + */ + void arm_conv_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + */ + void arm_conv_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_conv_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + */ + void arm_conv_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Partial convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q7 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + arm_status arm_conv_partial_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR decimator. + */ + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_f32; + + + /** + * @brief Processing function for the floating-point FIR decimator. + * @param[in] S points to an instance of the floating-point FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_f32( + const arm_fir_decimate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR decimator. + * @param[in,out] S points to an instance of the floating-point FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_f32( + arm_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR decimator. + * @param[in,out] S points to an instance of the Q15 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q15( + arm_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR decimator. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q31( + const arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q31( + arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR decimator. + * @param[in,out] S points to an instance of the Q31 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q31( + arm_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR interpolator. + */ + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ + } arm_fir_interpolate_instance_f32; + + + /** + * @brief Processing function for the Q15 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q15( + const arm_fir_interpolate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR interpolator. + * @param[in,out] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q15( + arm_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q31( + const arm_fir_interpolate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR interpolator. + * @param[in,out] S points to an instance of the Q31 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q31( + arm_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR interpolator. + * @param[in] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_f32( + const arm_fir_interpolate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR interpolator. + * @param[in,out] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_f32( + arm_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the high precision Q31 Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ + } arm_biquad_cas_df1_32x64_ins_q31; + + + /** + * @param[in] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cas_df1_32x64_q31( + const arm_biquad_cas_df1_32x64_ins_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @param[in,out] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cas_df1_32x64_init_q31( + arm_biquad_cas_df1_32x64_ins_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q63_t * pState, + uint8_t postShift); + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_stereo_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f64; + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_stereo_df2T_f32( + const arm_biquad_cascade_stereo_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f64( + const arm_biquad_cascade_df2T_instance_f64 * S, + float64_t * pSrc, + float64_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_stereo_df2T_init_f32( + arm_biquad_cascade_stereo_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f64( + arm_biquad_cascade_df2T_instance_f64 * S, + uint8_t numStages, + float64_t * pCoeffs, + float64_t * pState); + + + /** + * @brief Instance structure for the Q15 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_f32; + + + /** + * @brief Initialization function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q15( + arm_fir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pCoeffs, + q15_t * pState); + + + /** + * @brief Processing function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q15( + const arm_fir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q31( + arm_fir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pCoeffs, + q31_t * pState); + + + /** + * @brief Processing function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q31( + const arm_fir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_f32( + arm_fir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Processing function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_f32( + const arm_fir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_f32; + + + /** + * @brief Processing function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_f32( + const arm_iir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize-1. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_f32( + arm_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pkCoeffs, + float32_t * pvCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q31( + const arm_iir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to the state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_init_q31( + arm_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pkCoeffs, + q31_t * pvCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the Q15 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q15( + const arm_iir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the fixed-point Q15 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] pkCoeffs points to reflection coefficient buffer. The array is of length numStages. + * @param[in] pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. + * @param[in] pState points to state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process per call. + */ + void arm_iir_lattice_init_q15( + arm_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pkCoeffs, + q15_t * pvCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the floating-point LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that controls filter coefficient updates. */ + } arm_lms_instance_f32; + + + /** + * @brief Processing function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_f32( + const arm_lms_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_init_f32( + arm_lms_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q15; + + + /** + * @brief Initialization function for the Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q15( + arm_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Processing function for Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q15( + const arm_lms_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q31; + + + /** + * @brief Processing function for Q31 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q31( + const arm_lms_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 LMS filter. + * @param[in] S points to an instance of the Q31 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q31( + arm_lms_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Instance structure for the floating-point normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that control filter coefficient updates. */ + float32_t energy; /**< saves previous frame energy. */ + float32_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_f32; + + + /** + * @brief Processing function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_f32( + arm_lms_norm_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_init_f32( + arm_lms_norm_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q31; + + + /** + * @brief Processing function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q31( + arm_lms_norm_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q31( + arm_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Instance structure for the Q15 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< Number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q15; + + + /** + * @brief Processing function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q15( + arm_lms_norm_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q15( + arm_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Correlation of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Correlation of Q15 sequences + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ + void arm_correlate_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + + void arm_correlate_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + + void arm_correlate_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ + void arm_correlate_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + */ + void arm_correlate_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Instance structure for the floating-point sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_f32; + + /** + * @brief Instance structure for the Q31 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q31; + + /** + * @brief Instance structure for the Q15 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q15; + + /** + * @brief Instance structure for the Q7 sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q7; + + + /** + * @brief Processing function for the floating-point sparse FIR filter. + * @param[in] S points to an instance of the floating-point sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_f32( + arm_fir_sparse_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point sparse FIR filter. + * @param[in,out] S points to an instance of the floating-point sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_f32( + arm_fir_sparse_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 sparse FIR filter. + * @param[in] S points to an instance of the Q31 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q31( + arm_fir_sparse_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 sparse FIR filter. + * @param[in,out] S points to an instance of the Q31 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q31( + arm_fir_sparse_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 sparse FIR filter. + * @param[in] S points to an instance of the Q15 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q15( + arm_fir_sparse_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 sparse FIR filter. + * @param[in,out] S points to an instance of the Q15 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q15( + arm_fir_sparse_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q7 sparse FIR filter. + * @param[in] S points to an instance of the Q7 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q7( + arm_fir_sparse_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 sparse FIR filter. + * @param[in,out] S points to an instance of the Q7 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q7( + arm_fir_sparse_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Floating-point sin_cos function. + * @param[in] theta input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cos output. + */ + void arm_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCosVal); + + + /** + * @brief Q31 sin_cos function. + * @param[in] theta scaled input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cosine output. + */ + void arm_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal); + + + /** + * @brief Floating-point complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup PID PID Motor Control + * + * A Proportional Integral Derivative (PID) controller is a generic feedback control + * loop mechanism widely used in industrial control systems. + * A PID controller is the most commonly used type of feedback controller. + * + * This set of functions implements (PID) controllers + * for Q15, Q31, and floating-point data types. The functions operate on a single sample + * of data and each call to the function returns a single processed value. + * S points to an instance of the PID control data structure. in + * is the input sample value. The functions return the output value. + * + * \par Algorithm: + *
+   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+   *    A0 = Kp + Ki + Kd
+   *    A1 = (-Kp ) - (2 * Kd )
+   *    A2 = Kd  
+ * + * \par + * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant + * + * \par + * \image html PID.gif "Proportional Integral Derivative Controller" + * + * \par + * The PID controller calculates an "error" value as the difference between + * the measured output and the reference input. + * The controller attempts to minimize the error by adjusting the process control inputs. + * The proportional value determines the reaction to the current error, + * the integral value determines the reaction based on the sum of recent errors, + * and the derivative value determines the reaction based on the rate at which the error has been changing. + * + * \par Instance Structure + * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. + * A separate instance structure must be defined for each PID Controller. + * There are separate instance structure declarations for each of the 3 supported data types. + * + * \par Reset Functions + * There is also an associated reset function for each data type which clears the state array. + * + * \par Initialization Functions + * There is also an associated initialization function for each data type. + * The initialization function performs the following operations: + * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. + * - Zeros out the values in the state buffer. + * + * \par + * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. + * + * \par Fixed-Point Behavior + * Care must be taken when using the fixed-point versions of the PID Controller functions. + * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup PID + * @{ + */ + + /** + * @brief Process function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + */ + CMSIS_INLINE __STATIC_INLINE float32_t arm_pid_f32( + arm_pid_instance_f32 * S, + float32_t in) + { + float32_t out; + + /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ + out = (S->A0 * in) + + (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @brief Process function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 64-bit accumulator. + * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. + * Thus, if the accumulator result overflows it wraps around rather than clip. + * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. + * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ + CMSIS_INLINE __STATIC_INLINE q31_t arm_pid_q31( + arm_pid_instance_q31 * S, + q31_t in) + { + q63_t acc; + q31_t out; + + /* acc = A0 * x[n] */ + acc = (q63_t) S->A0 * in; + + /* acc += A1 * x[n-1] */ + acc += (q63_t) S->A1 * S->state[0]; + + /* acc += A2 * x[n-2] */ + acc += (q63_t) S->A2 * S->state[1]; + + /* convert output to 1.31 format to add y[n-1] */ + out = (q31_t) (acc >> 31U); + + /* out += y[n-1] */ + out += S->state[2]; + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + + /** + * @brief Process function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using a 64-bit internal accumulator. + * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. + * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. + * Lastly, the accumulator is saturated to yield a result in 1.15 format. + */ + CMSIS_INLINE __STATIC_INLINE q15_t arm_pid_q15( + arm_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + +#if defined (ARM_MATH_DSP) + __SIMD32_TYPE *vstate; + + /* Implementation of PID controller */ + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in); + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + vstate = __SIMD32_CONST(S->state); + acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)*vstate, (uint64_t)acc); +#else + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0) * in; + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0]; + acc += (q31_t) S->A2 * S->state[1]; +#endif + + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + + /* saturate the output */ + out = (q15_t) (__SSAT((acc >> 15), 16)); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + /** + * @} end of PID group + */ + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f32( + const arm_matrix_instance_f32 * src, + arm_matrix_instance_f32 * dst); + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f64( + const arm_matrix_instance_f64 * src, + arm_matrix_instance_f64 * dst); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup clarke Vector Clarke Transform + * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. + * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents + * in the two-phase orthogonal stator axis Ialpha and Ibeta. + * When Ialpha is superposed with Ia as shown in the figure below + * \image html clarke.gif Stator current space vector and its components in (a,b). + * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta + * can be calculated using only Ia and Ib. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeFormula.gif + * where Ia and Ib are the instantaneous stator phases and + * pIalpha and pIbeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup clarke + * @{ + */ + + /** + * + * @brief Floating-point Clarke transform + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + */ + CMSIS_INLINE __STATIC_INLINE void arm_clarke_f32( + float32_t Ia, + float32_t Ib, + float32_t * pIalpha, + float32_t * pIbeta) + { + /* Calculate pIalpha using the equation, pIalpha = Ia */ + *pIalpha = Ia; + + /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ + *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); + } + + + /** + * @brief Clarke transform for Q31 version + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + CMSIS_INLINE __STATIC_INLINE void arm_clarke_q31( + q31_t Ia, + q31_t Ib, + q31_t * pIalpha, + q31_t * pIbeta) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIalpha from Ia by equation pIalpha = Ia */ + *pIalpha = Ia; + + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); + + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); + + /* pIbeta is calculated by adding the intermediate products */ + *pIbeta = __QADD(product1, product2); + } + + /** + * @} end of clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q31( + q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_clarke Vector Inverse Clarke Transform + * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeInvFormula.gif + * where pIa and pIb are the instantaneous stator phases and + * Ialpha and Ibeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_clarke + * @{ + */ + + /** + * @brief Floating-point Inverse Clarke transform + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + */ + CMSIS_INLINE __STATIC_INLINE void arm_inv_clarke_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pIa, + float32_t * pIb) + { + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ + *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta; + } + + + /** + * @brief Inverse Clarke transform for Q31 version + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the subtraction, hence there is no risk of overflow. + */ + CMSIS_INLINE __STATIC_INLINE void arm_inv_clarke_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pIa, + q31_t * pIb) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); + + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); + + /* pIb is calculated by subtracting the products */ + *pIb = __QSUB(product2, product1); + } + + /** + * @} end of inv_clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q15( + q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup park Vector Park Transform + * + * Forward Park transform converts the input two-coordinate vector to flux and torque components. + * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents + * from the stationary to the moving reference frame and control the spatial relationship between + * the stator vector current and rotor flux vector. + * If we consider the d axis aligned with the rotor flux, the diagram below shows the + * current vector and the relationship from the two reference frames: + * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkFormula.gif + * where Ialpha and Ibeta are the stator vector components, + * pId and pIq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup park + * @{ + */ + + /** + * @brief Floating-point Park transform + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * The function implements the forward Park transform. + * + */ + CMSIS_INLINE __STATIC_INLINE void arm_park_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pId, + float32_t * pIq, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ + *pId = Ialpha * cosVal + Ibeta * sinVal; + + /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ + *pIq = -Ialpha * sinVal + Ibeta * cosVal; + } + + + /** + * @brief Park transform for Q31 version + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition and subtraction, hence there is no risk of overflow. + */ + CMSIS_INLINE __STATIC_INLINE void arm_park_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pId, + q31_t * pIq, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Ialpha * cosVal) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * sinVal) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Ialpha * sinVal) */ + product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * cosVal) */ + product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); + + /* Calculate pId by adding the two intermediate products 1 and 2 */ + *pId = __QADD(product1, product2); + + /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ + *pIq = __QSUB(product4, product3); + } + + /** + * @} end of park group + */ + + /** + * @brief Converts the elements of the Q7 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q7_to_float( + q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_park Vector Inverse Park transform + * Inverse Park transform converts the input flux and torque components to two-coordinate vector. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkInvFormula.gif + * where pIalpha and pIbeta are the stator vector components, + * Id and Iq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_park + * @{ + */ + + /** + * @brief Floating-point Inverse Park transform + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + */ + CMSIS_INLINE __STATIC_INLINE void arm_inv_park_f32( + float32_t Id, + float32_t Iq, + float32_t * pIalpha, + float32_t * pIbeta, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ + *pIalpha = Id * cosVal - Iq * sinVal; + + /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ + *pIbeta = Id * sinVal + Iq * cosVal; + } + + + /** + * @brief Inverse Park transform for Q31 version + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + CMSIS_INLINE __STATIC_INLINE void arm_inv_park_q31( + q31_t Id, + q31_t Iq, + q31_t * pIalpha, + q31_t * pIbeta, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Id * cosVal) */ + product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Iq * sinVal) */ + product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Id * sinVal) */ + product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Iq * cosVal) */ + product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); + + /* Calculate pIalpha by using the two intermediate products 1 and 2 */ + *pIalpha = __QSUB(product1, product2); + + /* Calculate pIbeta by using the two intermediate products 3 and 4 */ + *pIbeta = __QADD(product4, product3); + } + + /** + * @} end of Inverse park group + */ + + + /** + * @brief Converts the elements of the Q31 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_float( + q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup LinearInterpolate Linear Interpolation + * + * Linear interpolation is a method of curve fitting using linear polynomials. + * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line + * + * \par + * \image html LinearInterp.gif "Linear interpolation" + * + * \par + * A Linear Interpolate function calculates an output value(y), for the input(x) + * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) + * + * \par Algorithm: + *
+   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+   *       where x0, x1 are nearest values of input x
+   *             y0, y1 are nearest values to output y
+   * 
+ * + * \par + * This set of functions implements Linear interpolation process + * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single + * sample of data and each call to the function returns a single processed value. + * S points to an instance of the Linear Interpolate function data structure. + * x is the input sample value. The functions returns the output value. + * + * \par + * if x is outside of the table boundary, Linear interpolation returns first value of the table + * if x is below input range and returns last value of table if x is above range. + */ + + /** + * @addtogroup LinearInterpolate + * @{ + */ + + /** + * @brief Process function for the floating-point Linear Interpolation Function. + * @param[in,out] S is an instance of the floating-point Linear Interpolation structure + * @param[in] x input sample to process + * @return y processed output sample. + * + */ + CMSIS_INLINE __STATIC_INLINE float32_t arm_linear_interp_f32( + arm_linear_interp_instance_f32 * S, + float32_t x) + { + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + + /* Calculation of index */ + i = (int32_t) ((x - S->x1) / xSpacing); + + if (i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if ((uint32_t)i >= S->nValues) + { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues - 1]; + } + else + { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i + 1) * xSpacing; + + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); + + } + + /* returns output value */ + return (y); + } + + + /** + * + * @brief Process function for the Q31 Linear Interpolation Function. + * @param[in] pYData pointer to Q31 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + CMSIS_INLINE __STATIC_INLINE q31_t arm_linear_interp_q31( + q31_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q31_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (q31_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if (index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); + + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y += ((q31_t) (((q63_t) y1 * fract) >> 32)); + + /* Convert y to 1.31 format */ + return (y << 1U); + } + } + + + /** + * + * @brief Process function for the Q15 Linear Interpolation Function. + * @param[in] pYData pointer to Q15 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + CMSIS_INLINE __STATIC_INLINE q15_t arm_linear_interp_q15( + q15_t * pYData, + q31_t x, + uint32_t nValues) + { + q63_t y; /* output */ + q15_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (int32_t)0xFFF00000) >> 20); + + if (index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if (index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = ((q63_t) y0 * (0xFFFFF - fract)); + + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y += ((q63_t) y1 * (fract)); + + /* convert y to 1.15 format */ + return (q15_t) (y >> 20); + } + } + + + /** + * + * @brief Process function for the Q7 Linear Interpolation Function. + * @param[in] pYData pointer to Q7 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + */ + CMSIS_INLINE __STATIC_INLINE q7_t arm_linear_interp_q7( + q7_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + uint32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + if (x < 0) + { + return (pYData[0]); + } + index = (x >> 20) & 0xfff; + + if (index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ + y = ((y0 * (0xFFFFF - fract))); + + /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ + y += (y1 * fract); + + /* convert y to 1.7(q7) format */ + return (q7_t) (y >> 20); + } + } + + /** + * @} end of LinearInterpolate group + */ + + /** + * @brief Fast approximation to the trigonometric sine function for floating-point data. + * @param[in] x input value in radians. + * @return sin(x). + */ + float32_t arm_sin_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q31_t arm_sin_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q15_t arm_sin_q15( + q15_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for floating-point data. + * @param[in] x input value in radians. + * @return cos(x). + */ + float32_t arm_cos_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q31_t arm_cos_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q15_t arm_cos_q15( + q15_t x); + + + /** + * @ingroup groupFastMath + */ + + + /** + * @defgroup SQRT Square Root + * + * Computes the square root of a number. + * There are separate functions for Q15, Q31, and floating-point data types. + * The square root function is computed using the Newton-Raphson algorithm. + * This is an iterative algorithm of the form: + *
+   *      x1 = x0 - f(x0)/f'(x0)
+   * 
+ * where x1 is the current estimate, + * x0 is the previous estimate, and + * f'(x0) is the derivative of f() evaluated at x0. + * For the square root function, the algorithm reduces to: + *
+   *     x0 = in/2                         [initial guess]
+   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
+   * 
+ */ + + + /** + * @addtogroup SQRT + * @{ + */ + + /** + * @brief Floating-point square root function. + * @param[in] in input value. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + CMSIS_INLINE __STATIC_INLINE arm_status arm_sqrt_f32( + float32_t in, + float32_t * pOut) + { + if (in >= 0.0f) + { + +#if (__FPU_USED == 1) && defined ( __CC_ARM ) + *pOut = __sqrtf(in); +#elif (__FPU_USED == 1) && (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) + *pOut = __builtin_sqrtf(in); +#elif (__FPU_USED == 1) && defined(__GNUC__) + *pOut = __builtin_sqrtf(in); +#elif (__FPU_USED == 1) && defined ( __ICCARM__ ) && (__VER__ >= 6040000) + __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in)); +#else + *pOut = sqrtf(in); +#endif + + return (ARM_MATH_SUCCESS); + } + else + { + *pOut = 0.0f; + return (ARM_MATH_ARGUMENT_ERROR); + } + } + + + /** + * @brief Q31 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q31( + q31_t in, + q31_t * pOut); + + + /** + * @brief Q15 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q15( + q15_t in, + q15_t * pOut); + + /** + * @} end of SQRT group + */ + + + /** + * @brief floating-point Circular write function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularWrite_f32( + int32_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const int32_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + + /** + * @brief floating-point Circular Read function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularRead_f32( + int32_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + int32_t * dst, + int32_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == (int32_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q15 Circular write function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularWrite_q15( + q15_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q15_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q15 Circular Read function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularRead_q15( + q15_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q15_t * dst, + q15_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == (q15_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update wOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q7 Circular write function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularWrite_q7( + q7_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q7_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0U; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if (wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q7 Circular Read function. + */ + CMSIS_INLINE __STATIC_INLINE void arm_circularRead_q7( + q7_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q7_t * dst, + q7_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while (i > 0U) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if (dst == (q7_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if (rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Sum of the squares of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q31( + q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q15( + q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q7( + q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + + /** + * @brief Mean value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Mean value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Variance of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Standard deviation of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Floating-point complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + + /** + * @brief Q31 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + + /** + * @brief Floating-point complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + + /** + * @brief Q15 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q15( + q15_t * pSrcCmplx, + q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q31( + q31_t * pSrcCmplx, + q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_f32( + float32_t * pSrcCmplx, + float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Minimum value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] result is output pointer + * @param[in] index is the array index of the minimum value in the input buffer. + */ + void arm_min_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * result, + uint32_t * index); + + + /** + * @brief Minimum value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[in] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q7 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q15 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q31 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a floating-point vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Q15 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Converts the elements of the floating-point vector to Q31 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q31 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q31( + float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q15 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q15( + float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q7 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q7 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q7( + float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q15 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q15( + q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q7( + q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_float( + q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q31 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q31( + q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q7( + q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup BilinearInterpolate Bilinear Interpolation + * + * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. + * The underlying function f(x, y) is sampled on a regular grid and the interpolation process + * determines values between the grid points. + * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. + * Bilinear interpolation is often used in image processing to rescale images. + * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. + * + * Algorithm + * \par + * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. + * For floating-point, the instance structure is defined as: + *
+   *   typedef struct
+   *   {
+   *     uint16_t numRows;
+   *     uint16_t numCols;
+   *     float32_t *pData;
+   * } arm_bilinear_interp_instance_f32;
+   * 
+ * + * \par + * where numRows specifies the number of rows in the table; + * numCols specifies the number of columns in the table; + * and pData points to an array of size numRows*numCols values. + * The data table pTable is organized in row order and the supplied data values fall on integer indexes. + * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. + * + * \par + * Let (x, y) specify the desired interpolation point. Then define: + *
+   *     XF = floor(x)
+   *     YF = floor(y)
+   * 
+ * \par + * The interpolated output point is computed as: + *
+   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+   * 
+ * Note that the coordinates (x, y) contain integer and fractional components. + * The integer components specify which portion of the table to use while the + * fractional components control the interpolation processor. + * + * \par + * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. + */ + + /** + * @addtogroup BilinearInterpolate + * @{ + */ + + + /** + * + * @brief Floating-point bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate. + * @param[in] Y interpolation coordinate. + * @return out interpolated value. + */ + CMSIS_INLINE __STATIC_INLINE float32_t arm_bilinear_interp_f32( + const arm_bilinear_interp_instance_f32 * S, + float32_t X, + float32_t Y) + { + float32_t out; + float32_t f00, f01, f10, f11; + float32_t *pData = S->pData; + int32_t xIndex, yIndex, index; + float32_t xdiff, ydiff; + float32_t b1, b2, b3, b4; + + xIndex = (int32_t) X; + yIndex = (int32_t) Y; + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1)) + { + return (0); + } + + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex - 1) + (yIndex - 1) * S->numCols; + + + /* Read two nearest points in X-direction */ + f00 = pData[index]; + f01 = pData[index + 1]; + + /* Calculation of index for two nearest points in Y-direction */ + index = (xIndex - 1) + (yIndex) * S->numCols; + + + /* Read two nearest points in Y-direction */ + f10 = pData[index]; + f11 = pData[index + 1]; + + /* Calculation of intermediate values */ + b1 = f00; + b2 = f01 - f00; + b3 = f10 - f00; + b4 = f00 - f01 - f10 + f11; + + /* Calculation of fractional part in X */ + xdiff = X - xIndex; + + /* Calculation of fractional part in Y */ + ydiff = Y - yIndex; + + /* Calculation of bi-linear interpolated output */ + out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; + + /* return to application */ + return (out); + } + + + /** + * + * @brief Q31 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + CMSIS_INLINE __STATIC_INLINE q31_t arm_bilinear_interp_q31( + arm_bilinear_interp_instance_q31 * S, + q31_t X, + q31_t Y) + { + q31_t out; /* Temporary output */ + q31_t acc = 0; /* output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q31_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q31_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* shift left xfract by 11 to keep 1.31 format */ + xfract = (X & 0x000FFFFF) << 11U; + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + (int32_t)nCols * (cI) ]; + x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1]; + + /* 20 bits for the fractional part */ + /* shift left yfract by 11 to keep 1.31 format */ + yfract = (Y & 0x000FFFFF) << 11U; + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + (int32_t)nCols * (cI + 1) ]; + y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); + acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); + + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); + + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* Convert acc to 1.31(q31) format */ + return ((q31_t)(acc << 2)); + } + + + /** + * @brief Q15 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + CMSIS_INLINE __STATIC_INLINE q15_t arm_bilinear_interp_q15( + arm_bilinear_interp_instance_q15 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q15_t x1, x2, y1, y2; /* Nearest output values */ + q31_t xfract, yfract; /* X, Y fractional parts */ + int32_t rI, cI; /* Row and column indices */ + q15_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ + + /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ + /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ + out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4U); + acc = ((q63_t) out * (0xFFFFF - yfract)); + + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4U); + acc += ((q63_t) out * (xfract)); + + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4U); + acc += ((q63_t) out * (yfract)); + + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y2 * (xfract)) >> 4U); + acc += ((q63_t) out * (yfract)); + + /* acc is in 13.51 format and down shift acc by 36 times */ + /* Convert out to 1.15 format */ + return ((q15_t)(acc >> 36)); + } + + + /** + * @brief Q7 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + CMSIS_INLINE __STATIC_INLINE q7_t arm_bilinear_interp_q7( + arm_bilinear_interp_instance_q7 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q7_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q7_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ + out = ((x1 * (0xFFFFF - xfract))); + acc = (((q63_t) out * (0xFFFFF - yfract))); + + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc += (((q63_t) out * (xfract))); + + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc += (((q63_t) out * (yfract))); + + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc += (((q63_t) out * (xfract))); + + /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ + return ((q7_t)(acc >> 40)); + } + + /** + * @} end of BilinearInterpolate group + */ + + +/* SMMLAR */ +#define multAcc_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMLSR */ +#define multSub_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMULR */ +#define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) + +/* SMMLA */ +#define multAcc_32x32_keep32(a, x, y) \ + a += (q31_t) (((q63_t) x * y) >> 32) + +/* SMMLS */ +#define multSub_32x32_keep32(a, x, y) \ + a -= (q31_t) (((q63_t) x * y) >> 32) + +/* SMMUL */ +#define mult_32x32_keep32(a, x, y) \ + a = (q31_t) (((q63_t) x * y ) >> 32) + + +#if defined ( __CC_ARM ) + /* Enter low optimization region - place directly above function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("push") \ + _Pragma ("O1") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) + #define LOW_OPTIMIZATION_EXIT \ + _Pragma ("pop") + #else + #define LOW_OPTIMIZATION_EXIT + #endif + + /* Enter low optimization region - place directly above function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined (__ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __GNUC__ ) + #define LOW_OPTIMIZATION_ENTER \ + __attribute__(( optimize("-O1") )) + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __ICCARM__ ) + /* Enter low optimization region - place directly above function definition */ + #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define LOW_OPTIMIZATION_EXIT + + /* Enter low optimization region - place directly above function definition */ + #if defined ( ARM_MATH_CM4 ) || defined ( ARM_MATH_CM7 ) + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __TI_ARM__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __CSMC__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined ( __TASKING__ ) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#endif + + +#ifdef __cplusplus +} +#endif + +/* Compiler specific diagnostic adjustment */ +#if defined ( __CC_ARM ) + +#elif defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 ) + +#elif defined ( __GNUC__ ) +#pragma GCC diagnostic pop + +#elif defined ( __ICCARM__ ) + +#elif defined ( __TI_ARM__ ) + +#elif defined ( __CSMC__ ) + +#elif defined ( __TASKING__ ) + +#else + #error Unknown compiler +#endif + +#endif /* _ARM_MATH_H */ + +/** + * + * End of file. + */ diff --git a/CMSIS/cmsis_armcc.h b/CMSIS/cmsis_armcc.h new file mode 100644 index 0000000..093d35b --- /dev/null +++ b/CMSIS/cmsis_armcc.h @@ -0,0 +1,870 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ + (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) + #define __ARM_ARCH_6M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) + #define __ARM_ARCH_7M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) + #define __ARM_ARCH_7EM__ 1 +#endif + + /* __ARM_ARCH_8M_BASE__ not applicable */ + /* __ARM_ARCH_8M_MAIN__ not applicable */ + + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1U); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details 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 + \details 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 + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details 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() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return result; +} +#endif + + +/** + \brief Count leading zeros + \details 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 + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details 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 + \details 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 Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/CMSIS/cmsis_armclang.h b/CMSIS/cmsis_armclang.h new file mode 100644 index 0000000..5c4c20e --- /dev/null +++ b/CMSIS/cmsis_armclang.h @@ -0,0 +1,1877 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + register uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + register uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + register uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + register uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + +#endif /* ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details 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 __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details 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() __builtin_arm_isb(0xF); + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF); + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF); + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details 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 (uint8_t)__builtin_clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction 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 (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction 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 (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction 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 (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details 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 __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details 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 __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction 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 __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction 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 __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction 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 __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/CMSIS/cmsis_compiler.h b/CMSIS/cmsis_compiler.h new file mode 100644 index 0000000..94212eb --- /dev/null +++ b/CMSIS/cmsis_compiler.h @@ -0,0 +1,266 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * 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. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/CMSIS/cmsis_gcc.h b/CMSIS/cmsis_gcc.h new file mode 100644 index 0000000..5d0f07e --- /dev/null +++ b/CMSIS/cmsis_gcc.h @@ -0,0 +1,2088 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.0.3 + * @date 16. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) :: "memory"); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) :: "memory"); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + register uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + register uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + register uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + register uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + +#endif /* ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi") + + +/** + \brief Wait For Event + \details 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() __ASM volatile ("wfe") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details 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. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details 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 (uint8_t)__builtin_clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ + __extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__STATIC_FORCEINLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) +#endif + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/CMSIS/cmsis_iccarm.h b/CMSIS/cmsis_iccarm.h new file mode 100644 index 0000000..edcaee3 --- /dev/null +++ b/CMSIS/cmsis_iccarm.h @@ -0,0 +1,913 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.0.5 + * @date 10. January 2018 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2018 IAR Systems +// +// Licensed under the Apache License, Version 2.0 (the "License") +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//------------------------------------------------------------------------------ + + +#ifndef __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ +/* Macros already defined */ +#else + #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' + #if __ARM_ARCH == 6 + #define __ARM_ARCH_6M__ 1 + #elif __ARM_ARCH == 7 + #if __ARM_FEATURE_DSP + #define __ARM_ARCH_7EM__ 1 + #else + #define __ARM_ARCH_7M__ 1 + #endif + #endif /* __ARM_ARCH */ + #endif /* __ARM_ARCH_PROFILE == 'M' */ +#endif + +/* Alternativ core deduction for older ICCARM's */ +#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ + !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) + #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) + #define __ARM_ARCH_6M__ 1 + #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) + #define __ARM_ARCH_7M__ 1 + #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) + #define __ARM_ARCH_7EM__ 1 + #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #else + #error "Unknown target." + #endif +#endif + + + +#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 + #define __IAR_M0_FAMILY 1 +#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 + #define __IAR_M0_FAMILY 1 +#else + #define __IAR_M0_FAMILY 0 +#endif + + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((__noreturn__)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #define __RESTRICT restrict +#endif + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE +#endif + +#ifndef __UNALIGNED_UINT16_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint16_t __iar_uint16_read(void const *ptr) +{ + return *(__packed uint16_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) +{ + *(__packed uint16_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint32_t __iar_uint32_read(void const *ptr) +{ + return *(__packed uint32_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) +{ + *(__packed uint32_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32 /* deprecated */ +#pragma language=save +#pragma language=extended +__packed struct __iar_u32 { uint32_t v; }; +#pragma language=restore +#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __enable_irq __iar_builtin_enable_interrupt + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + + #define __get_APSR() (__arm_rsr("APSR")) + #define __get_BASEPRI() (__arm_rsr("BASEPRI")) + #define __get_CONTROL() (__arm_rsr("CONTROL")) + #define __get_FAULTMASK() (__arm_rsr("FAULTMASK")) + + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE))) + #else + #define __get_FPSCR() ( 0 ) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #define __get_IPSR() (__arm_rsr("IPSR")) + #define __get_MSP() (__arm_rsr("MSP")) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __get_MSPLIM() (0U) + #else + #define __get_MSPLIM() (__arm_rsr("MSPLIM")) + #endif + #define __get_PRIMASK() (__arm_rsr("PRIMASK")) + #define __get_PSP() (__arm_rsr("PSP")) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __get_PSPLIM() (0U) + #else + #define __get_PSPLIM() (__arm_rsr("PSPLIM")) + #endif + + #define __get_xPSR() (__arm_rsr("xPSR")) + + #define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE))) + #define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE))) + #define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE))) + #define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE))) + #define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __set_MSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE))) + #endif + #define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE))) + #define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE))) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __set_PSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE))) + #endif + + #define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS")) + #define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE))) + #define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS")) + #define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE))) + #define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS")) + #define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE))) + #define __TZ_get_SP_NS() (__arm_rsr("SP_NS")) + #define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE))) + #define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS")) + #define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE))) + #define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS")) + #define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE))) + #define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS")) + #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) + #define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS")) + #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) + #define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS")) + #define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE))) + + #define __NOP __iar_builtin_no_operation + + #define __CLZ __iar_builtin_CLZ + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int16_t __REVSH(int16_t val) + { + return (int16_t) __iar_builtin_REVSH(val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #if !__IAR_M0_FAMILY + #define __SSAT __iar_builtin_SSAT + #endif + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #if !__IAR_M0_FAMILY + #define __USAT __iar_builtin_USAT + #endif + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #if __ARM_MEDIA__ + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + #endif + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #define __CLZ __cmsis_iar_clz_not_active + #define __SSAT __cmsis_iar_ssat_not_active + #define __USAT __cmsis_iar_usat_not_active + #define __RBIT __cmsis_iar_rbit_not_active + #define __get_APSR __cmsis_iar_get_APSR_not_active + #endif + + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #define __set_FPSCR __cmsis_iar_set_FPSR_not_active + #endif + + #ifdef __INTRINSICS_INCLUDED + #error intrinsics.h is already included previously! + #endif + + #include + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #undef __CLZ + #undef __SSAT + #undef __USAT + #undef __RBIT + #undef __get_APSR + + __STATIC_INLINE uint8_t __CLZ(uint32_t data) + { + if (data == 0U) { return 32U; } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) + { + count += 1U; + mask = mask >> 1U; + } + return count; + } + + __STATIC_INLINE uint32_t __RBIT(uint32_t v) + { + uint8_t sc = 31U; + uint32_t r = v; + for (v >>= 1U; v; v >>= 1U) + { + r <<= 1U; + r |= v & 1U; + sc--; + } + return (r << sc); + } + + __STATIC_INLINE uint32_t __get_APSR(void) + { + uint32_t res; + __asm("MRS %0,APSR" : "=r" (res)); + return res; + } + + #endif + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #undef __get_FPSCR + #undef __set_FPSCR + #define __get_FPSCR() (0) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) + { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) + { + return __STREX(value, (unsigned long *)ptr); + } + #endif + + + /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + #if (__CORTEX_M >= 0x03) + + __IAR_FT uint32_t __RRX(uint32_t value) + { + uint32_t result; + __ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); + return(result); + } + + __IAR_FT void __set_BASEPRI_MAX(uint32_t value) + { + __asm volatile("MSR BASEPRI_MAX,%0"::"r" (value)); + } + + + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + + + #endif /* (__CORTEX_M >= 0x03) */ + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) + { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + __IAR_FT uint32_t __get_MSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,MSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_MSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR MSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __get_PSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_PSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,CONTROL_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) + { + __asm volatile("MSR CONTROL_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PSP_NS(uint32_t value) + { + __asm volatile("MSR PSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSP_NS(uint32_t value) + { + __asm volatile("MSR MSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_SP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,SP_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_SP_NS(uint32_t value) + { + __asm volatile("MSR SP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PRIMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) + { + __asm volatile("MSR PRIMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,BASEPRI_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) + { + __asm volatile("MSR BASEPRI_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) + { + __asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PSPLIM_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) + { + __asm volatile("MSR PSPLIM_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSPLIM_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) + { + __asm volatile("MSR MSPLIM_NS,%0" :: "r" (value)); + } + + #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + +#if __IAR_M0_FAMILY + __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) + { + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; + } + + __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) + { + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; + } +#endif + +#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + + __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) + { + uint32_t res; + __ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) + { + uint32_t res; + __ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) + { + uint32_t res; + __ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return res; + } + + __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) + { + __ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) + { + __ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) + { + __ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); + } + +#endif /* (__CORTEX_M >= 0x03) */ + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + + __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return res; + } + + __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) + { + __ASM volatile ("STLB %1, [%0]" :: "r" (*ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) + { + __ASM volatile ("STLH %1, [%0]" :: "r" (*ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) + { + __ASM volatile ("STL %1, [%0]" :: "r" (*ptr), "r" (value) : "memory"); + } + + __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (*ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (*ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (*ptr), "r" (value) : "memory"); + return res; + } + +#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#undef __IAR_FT +#undef __IAR_M0_FAMILY +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/CMSIS/cmsis_version.h b/CMSIS/cmsis_version.h new file mode 100644 index 0000000..660f612 --- /dev/null +++ b/CMSIS/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.2 + * @date 19. April 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 1U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/CMSIS/core_armv8mbl.h b/CMSIS/core_armv8mbl.h new file mode 100644 index 0000000..47a3989 --- /dev/null +++ b/CMSIS/core_armv8mbl.h @@ -0,0 +1,1896 @@ +/**************************************************************************//** + * @file core_armv8mbl.h + * @brief CMSIS Armv8-M Baseline Core Peripheral Access Layer Header File + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_ARMV8MBL_H_GENERIC +#define __CORE_ARMV8MBL_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_ARMv8MBL + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS definitions */ +#define __ARMv8MBL_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MBL_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv8MBL_CMSIS_VERSION ((__ARMv8MBL_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv8MBL_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M ( 2U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MBL_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV8MBL_H_DEPENDANT +#define __CORE_ARMV8MBL_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv8MBL_REV + #define __ARMv8MBL_REV 0x0000U + #warning "__ARMv8MBL_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif + + #ifndef __ETM_PRESENT + #define __ETM_PRESENT 0U + #warning "__ETM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MTB_PRESENT + #define __MTB_PRESENT 0U + #warning "__MTB_PRESENT not defined in device header file; using default!" + #endif + +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#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 */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group ARMv8MBL */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + 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; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \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; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + 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; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \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-pointer select */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint32_t IPR[124U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHPR[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< 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_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< 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_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< 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 4U /*!< 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 3U /*!< 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 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< 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 0U /*!< 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 0U /*!< 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 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + uint32_t RESERVED0[6U]; + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x3UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + uint32_t RESERVED0[7U]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: BASE Position */ +#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: BASE Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: EN Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: EN Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#endif +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< 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 24U /*!< 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 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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_MASKINTS_Pos 3U /*!< 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 2U /*!< 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 1U /*!< 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 0U /*!< 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 Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< 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_DWTENA_Pos 24U /*!< CoreDebug DEMCR: DWTENA Position */ +#define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< CoreDebug DEMCR: DWTENA Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< 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_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI 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 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 DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else +/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Armv8-M Baseline */ +/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Armv8-M Baseline */ + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates 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 = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[_IP_IDX(IRQn)] = ((uint32_t)(NVIC_NS->IPR[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB_NS->SHPR[_SHP_IDX(IRQn)] = ((uint32_t)(SCB_NS->SHPR[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IPR[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB_NS->SHPR[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* 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 (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MBL_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/CMSIS/core_armv8mml.h b/CMSIS/core_armv8mml.h new file mode 100644 index 0000000..0951a1f --- /dev/null +++ b/CMSIS/core_armv8mml.h @@ -0,0 +1,2960 @@ +/**************************************************************************//** + * @file core_armv8mml.h + * @brief CMSIS Armv8-M Mainline Core Peripheral Access Layer Header File + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_ARMV8MML_H_GENERIC +#define __CORE_ARMV8MML_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_ARMv8MML + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS Armv8MML definitions */ +#define __ARMv8MML_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __ARMv8MML_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __ARMv8MML_CMSIS_VERSION ((__ARMv8MML_CMSIS_VERSION_MAIN << 16U) | \ + __ARMv8MML_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (81U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + + #if defined(__ARM_FEATURE_DSP) + #if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U) + #define __DSP_USED 1U + #else + #error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)" + #define __DSP_USED 0U + #endif + #else + #define __DSP_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MML_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_ARMV8MML_H_DEPENDANT +#define __CORE_ARMV8MML_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __ARMv8MML_REV + #define __ARMv8MML_REV 0x0000U + #warning "__ARMv8MML_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __SAUREGION_PRESENT + #define __SAUREGION_PRESENT 0U + #warning "__SAUREGION_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DSP_PRESENT + #define __DSP_PRESENT 0U + #warning "__DSP_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#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 */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group ARMv8MML */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core SAU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + 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 */ + 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; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \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; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + 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 */ + 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; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \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-pointer select */ + uint32_t FPCA:1; /*!< bit: 2 Floating-point context active */ + uint32_t SFPA:1; /*!< bit: 3 Secure floating-point active */ + uint32_t _reserved1:28; /*!< bit: 4..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SFPA_Pos 3U /*!< CONTROL: SFPA Position */ +#define CONTROL_SFPA_Msk (1UL << CONTROL_SFPA_Pos) /*!< CONTROL: SFPA Mask */ + +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[16U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[16U]; + __IOM uint32_t ICER[16U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[16U]; + __IOM uint32_t ISPR[16U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[16U]; + __IOM uint32_t ICPR[16U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[16U]; + __IOM uint32_t IABR[16U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[16U]; + __IOM uint32_t ITNS[16U]; /*!< Offset: 0x280 (R/W) Interrupt Non-Secure State Register */ + uint32_t RESERVED5[16U]; + __IOM uint8_t IPR[496U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED6[580U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< 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 System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[6U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + __IOM uint32_t NSACR; /*!< Offset: 0x08C (R/W) Non-Secure Access Control Register */ + uint32_t RESERVED3[92U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< 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_PENDNMISET_Pos 31U /*!< SCB ICSR: PENDNMISET Position */ +#define SCB_ICSR_PENDNMISET_Msk (1UL << SCB_ICSR_PENDNMISET_Pos) /*!< SCB ICSR: PENDNMISET Mask */ + +#define SCB_ICSR_PENDNMICLR_Pos 30U /*!< SCB ICSR: PENDNMICLR Position */ +#define SCB_ICSR_PENDNMICLR_Msk (1UL << SCB_ICSR_PENDNMICLR_Pos) /*!< SCB ICSR: PENDNMICLR Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_STTNS_Pos 24U /*!< SCB ICSR: STTNS Position (Security Extension) */ +#define SCB_ICSR_STTNS_Msk (1UL << SCB_ICSR_STTNS_Pos) /*!< SCB ICSR: STTNS Mask (Security Extension) */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< 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 7U /*!< 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 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIS_Pos 14U /*!< SCB AIRCR: PRIS Position */ +#define SCB_AIRCR_PRIS_Msk (1UL << SCB_AIRCR_PRIS_Pos) /*!< SCB AIRCR: PRIS Mask */ + +#define SCB_AIRCR_BFHFNMINS_Pos 13U /*!< SCB AIRCR: BFHFNMINS Position */ +#define SCB_AIRCR_BFHFNMINS_Msk (1UL << SCB_AIRCR_BFHFNMINS_Pos) /*!< SCB AIRCR: BFHFNMINS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQS_Pos 3U /*!< SCB AIRCR: SYSRESETREQS Position */ +#define SCB_AIRCR_SYSRESETREQS_Msk (1UL << SCB_AIRCR_SYSRESETREQS_Pos) /*!< SCB AIRCR: SYSRESETREQS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEPS_Pos 3U /*!< SCB SCR: SLEEPDEEPS Position */ +#define SCB_SCR_SLEEPDEEPS_Msk (1UL << SCB_SCR_SLEEPDEEPS_Pos) /*!< SCB SCR: SLEEPDEEPS Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< 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_BP_Pos 18U /*!< SCB CCR: BP Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: BP Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: IC Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: IC Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: DC Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: DC Mask */ + +#define SCB_CCR_STKOFHFNMIGN_Pos 10U /*!< SCB CCR: STKOFHFNMIGN Position */ +#define SCB_CCR_STKOFHFNMIGN_Msk (1UL << SCB_CCR_STKOFHFNMIGN_Pos) /*!< SCB CCR: STKOFHFNMIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< 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 4U /*!< 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 3U /*!< 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 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_HARDFAULTPENDED_Pos 21U /*!< SCB SHCSR: HARDFAULTPENDED Position */ +#define SCB_SHCSR_HARDFAULTPENDED_Msk (1UL << SCB_SHCSR_HARDFAULTPENDED_Pos) /*!< SCB SHCSR: HARDFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTPENDED_Pos 20U /*!< SCB SHCSR: SECUREFAULTPENDED Position */ +#define SCB_SHCSR_SECUREFAULTPENDED_Msk (1UL << SCB_SHCSR_SECUREFAULTPENDED_Pos) /*!< SCB SHCSR: SECUREFAULTPENDED Mask */ + +#define SCB_SHCSR_SECUREFAULTENA_Pos 19U /*!< SCB SHCSR: SECUREFAULTENA Position */ +#define SCB_SHCSR_SECUREFAULTENA_Msk (1UL << SCB_SHCSR_SECUREFAULTENA_Pos) /*!< SCB SHCSR: SECUREFAULTENA Mask */ + +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_NMIACT_Pos 5U /*!< SCB SHCSR: NMIACT Position */ +#define SCB_SHCSR_NMIACT_Msk (1UL << SCB_SHCSR_NMIACT_Pos) /*!< SCB SHCSR: NMIACT Mask */ + +#define SCB_SHCSR_SECUREFAULTACT_Pos 4U /*!< SCB SHCSR: SECUREFAULTACT Position */ +#define SCB_SHCSR_SECUREFAULTACT_Msk (1UL << SCB_SHCSR_SECUREFAULTACT_Pos) /*!< SCB SHCSR: SECUREFAULTACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_HARDFAULTACT_Pos 2U /*!< SCB SHCSR: HARDFAULTACT Position */ +#define SCB_SHCSR_HARDFAULTACT_Msk (1UL << SCB_SHCSR_HARDFAULTACT_Pos) /*!< SCB SHCSR: HARDFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< 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 8U /*!< 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 0U /*!< 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 */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_STKOF_Pos (SCB_CFSR_USGFAULTSR_Pos + 4U) /*!< SCB CFSR (UFSR): STKOF Position */ +#define SCB_CFSR_STKOF_Msk (1UL << SCB_CFSR_STKOF_Pos) /*!< SCB CFSR (UFSR): STKOF Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< 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 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Non-Secure Access Control Register Definitions */ +#define SCB_NSACR_CP11_Pos 11U /*!< SCB NSACR: CP11 Position */ +#define SCB_NSACR_CP11_Msk (1UL << SCB_NSACR_CP11_Pos) /*!< SCB NSACR: CP11 Mask */ + +#define SCB_NSACR_CP10_Pos 10U /*!< SCB NSACR: CP10 Position */ +#define SCB_NSACR_CP10_Msk (1UL << SCB_NSACR_CP10_Pos) /*!< SCB NSACR: CP10 Mask */ + +#define SCB_NSACR_CPn_Pos 0U /*!< SCB NSACR: CPn Position */ +#define SCB_NSACR_CPn_Msk (1UL /*<< SCB_NSACR_CPn_Pos*/) /*!< SCB NSACR: CPn Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the 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[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ + __IOM uint32_t CPPWR; /*!< Offset: 0x00C (R/W) Coprocessor Power Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< 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 0U /*!< 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 0U /*!< 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 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) ITM Device Architecture Register */ + uint32_t RESERVED6[4U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Stimulus Port Register Definitions */ +#define ITM_STIM_DISABLED_Pos 1U /*!< ITM STIM: DISABLED Position */ +#define ITM_STIM_DISABLED_Msk (0x1UL << ITM_STIM_DISABLED_Pos) /*!< ITM STIM: DISABLED Mask */ + +#define ITM_STIM_FIFOREADY_Pos 0U /*!< ITM STIM: FIFOREADY Position */ +#define ITM_STIM_FIFOREADY_Msk (0x1UL /*<< ITM_STIM_FIFOREADY_Pos*/) /*!< ITM STIM: FIFOREADY Mask */ + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< 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 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TRACEBUSID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TRACEBUSID_Msk (0x7FUL << ITM_TCR_TRACEBUSID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< 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 8U /*!< ITM TCR: TSPRESCALE Position */ +#define ITM_TCR_TSPRESCALE_Msk (3UL << ITM_TCR_TSPRESCALE_Pos) /*!< ITM TCR: TSPRESCALE Mask */ + +#define ITM_TCR_STALLENA_Pos 5U /*!< ITM TCR: STALLENA Position */ +#define ITM_TCR_STALLENA_Msk (1UL << ITM_TCR_STALLENA_Pos) /*!< ITM TCR: STALLENA Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + uint32_t RESERVED3[1U]; + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED4[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + uint32_t RESERVED5[1U]; + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED6[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + uint32_t RESERVED7[1U]; + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED8[1U]; + __IOM uint32_t COMP4; /*!< Offset: 0x060 (R/W) Comparator Register 4 */ + uint32_t RESERVED9[1U]; + __IOM uint32_t FUNCTION4; /*!< Offset: 0x068 (R/W) Function Register 4 */ + uint32_t RESERVED10[1U]; + __IOM uint32_t COMP5; /*!< Offset: 0x070 (R/W) Comparator Register 5 */ + uint32_t RESERVED11[1U]; + __IOM uint32_t FUNCTION5; /*!< Offset: 0x078 (R/W) Function Register 5 */ + uint32_t RESERVED12[1U]; + __IOM uint32_t COMP6; /*!< Offset: 0x080 (R/W) Comparator Register 6 */ + uint32_t RESERVED13[1U]; + __IOM uint32_t FUNCTION6; /*!< Offset: 0x088 (R/W) Function Register 6 */ + uint32_t RESERVED14[1U]; + __IOM uint32_t COMP7; /*!< Offset: 0x090 (R/W) Comparator Register 7 */ + uint32_t RESERVED15[1U]; + __IOM uint32_t FUNCTION7; /*!< Offset: 0x098 (R/W) Function Register 7 */ + uint32_t RESERVED16[1U]; + __IOM uint32_t COMP8; /*!< Offset: 0x0A0 (R/W) Comparator Register 8 */ + uint32_t RESERVED17[1U]; + __IOM uint32_t FUNCTION8; /*!< Offset: 0x0A8 (R/W) Function Register 8 */ + uint32_t RESERVED18[1U]; + __IOM uint32_t COMP9; /*!< Offset: 0x0B0 (R/W) Comparator Register 9 */ + uint32_t RESERVED19[1U]; + __IOM uint32_t FUNCTION9; /*!< Offset: 0x0B8 (R/W) Function Register 9 */ + uint32_t RESERVED20[1U]; + __IOM uint32_t COMP10; /*!< Offset: 0x0C0 (R/W) Comparator Register 10 */ + uint32_t RESERVED21[1U]; + __IOM uint32_t FUNCTION10; /*!< Offset: 0x0C8 (R/W) Function Register 10 */ + uint32_t RESERVED22[1U]; + __IOM uint32_t COMP11; /*!< Offset: 0x0D0 (R/W) Comparator Register 11 */ + uint32_t RESERVED23[1U]; + __IOM uint32_t FUNCTION11; /*!< Offset: 0x0D8 (R/W) Function Register 11 */ + uint32_t RESERVED24[1U]; + __IOM uint32_t COMP12; /*!< Offset: 0x0E0 (R/W) Comparator Register 12 */ + uint32_t RESERVED25[1U]; + __IOM uint32_t FUNCTION12; /*!< Offset: 0x0E8 (R/W) Function Register 12 */ + uint32_t RESERVED26[1U]; + __IOM uint32_t COMP13; /*!< Offset: 0x0F0 (R/W) Comparator Register 13 */ + uint32_t RESERVED27[1U]; + __IOM uint32_t FUNCTION13; /*!< Offset: 0x0F8 (R/W) Function Register 13 */ + uint32_t RESERVED28[1U]; + __IOM uint32_t COMP14; /*!< Offset: 0x100 (R/W) Comparator Register 14 */ + uint32_t RESERVED29[1U]; + __IOM uint32_t FUNCTION14; /*!< Offset: 0x108 (R/W) Function Register 14 */ + uint32_t RESERVED30[1U]; + __IOM uint32_t COMP15; /*!< Offset: 0x110 (R/W) Comparator Register 15 */ + uint32_t RESERVED31[1U]; + __IOM uint32_t FUNCTION15; /*!< Offset: 0x118 (R/W) Function Register 15 */ + uint32_t RESERVED32[934U]; + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ + uint32_t RESERVED33[1U]; + __IM uint32_t DEVARCH; /*!< Offset: 0xFBC (R/ ) Device Architecture Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCDISS_Pos 23U /*!< DWT CTRL: CYCDISS Position */ +#define DWT_CTRL_CYCDISS_Msk (0x1UL << DWT_CTRL_CYCDISS_Pos) /*!< DWT CTRL: CYCDISS Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_ID_Pos 27U /*!< DWT FUNCTION: ID Position */ +#define DWT_FUNCTION_ID_Msk (0x1FUL << DWT_FUNCTION_ID_Pos) /*!< DWT FUNCTION: ID Mask */ + +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_ACTION_Pos 4U /*!< DWT FUNCTION: ACTION Position */ +#define DWT_FUNCTION_ACTION_Msk (0x1UL << DWT_FUNCTION_ACTION_Pos) /*!< DWT FUNCTION: ACTION Mask */ + +#define DWT_FUNCTION_MATCH_Pos 0U /*!< DWT FUNCTION: MATCH Position */ +#define DWT_FUNCTION_MATCH_Msk (0xFUL /*<< DWT_FUNCTION_MATCH_Pos*/) /*!< DWT FUNCTION: MATCH Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Region Base Address Register Alias 1 */ + __IOM uint32_t RLAR_A1; /*!< Offset: 0x018 (R/W) MPU Region Limit Address Register Alias 1 */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Region Base Address Register Alias 2 */ + __IOM uint32_t RLAR_A2; /*!< Offset: 0x020 (R/W) MPU Region Limit Address Register Alias 2 */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */ + __IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */ + uint32_t RESERVED0[1]; + union { + __IOM uint32_t MAIR[2]; + struct { + __IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */ + __IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */ + }; + }; +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */ +#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */ + +#define MPU_RBAR_AP_Pos 1U /*!< MPU RBAR: AP Position */ +#define MPU_RBAR_AP_Msk (0x3UL << MPU_RBAR_AP_Pos) /*!< MPU RBAR: AP Mask */ + +#define MPU_RBAR_XN_Pos 0U /*!< MPU RBAR: XN Position */ +#define MPU_RBAR_XN_Msk (01UL /*<< MPU_RBAR_XN_Pos*/) /*!< MPU RBAR: XN Mask */ + +/* MPU Region Limit Address Register Definitions */ +#define MPU_RLAR_LIMIT_Pos 5U /*!< MPU RLAR: LIMIT Position */ +#define MPU_RLAR_LIMIT_Msk (0x7FFFFFFUL << MPU_RLAR_LIMIT_Pos) /*!< MPU RLAR: LIMIT Mask */ + +#define MPU_RLAR_AttrIndx_Pos 1U /*!< MPU RLAR: AttrIndx Position */ +#define MPU_RLAR_AttrIndx_Msk (0x7UL << MPU_RLAR_AttrIndx_Pos) /*!< MPU RLAR: AttrIndx Mask */ + +#define MPU_RLAR_EN_Pos 0U /*!< MPU RLAR: Region enable bit Position */ +#define MPU_RLAR_EN_Msk (1UL /*<< MPU_RLAR_EN_Pos*/) /*!< MPU RLAR: Region enable bit Disable Mask */ + +/* MPU Memory Attribute Indirection Register 0 Definitions */ +#define MPU_MAIR0_Attr3_Pos 24U /*!< MPU MAIR0: Attr3 Position */ +#define MPU_MAIR0_Attr3_Msk (0xFFUL << MPU_MAIR0_Attr3_Pos) /*!< MPU MAIR0: Attr3 Mask */ + +#define MPU_MAIR0_Attr2_Pos 16U /*!< MPU MAIR0: Attr2 Position */ +#define MPU_MAIR0_Attr2_Msk (0xFFUL << MPU_MAIR0_Attr2_Pos) /*!< MPU MAIR0: Attr2 Mask */ + +#define MPU_MAIR0_Attr1_Pos 8U /*!< MPU MAIR0: Attr1 Position */ +#define MPU_MAIR0_Attr1_Msk (0xFFUL << MPU_MAIR0_Attr1_Pos) /*!< MPU MAIR0: Attr1 Mask */ + +#define MPU_MAIR0_Attr0_Pos 0U /*!< MPU MAIR0: Attr0 Position */ +#define MPU_MAIR0_Attr0_Msk (0xFFUL /*<< MPU_MAIR0_Attr0_Pos*/) /*!< MPU MAIR0: Attr0 Mask */ + +/* MPU Memory Attribute Indirection Register 1 Definitions */ +#define MPU_MAIR1_Attr7_Pos 24U /*!< MPU MAIR1: Attr7 Position */ +#define MPU_MAIR1_Attr7_Msk (0xFFUL << MPU_MAIR1_Attr7_Pos) /*!< MPU MAIR1: Attr7 Mask */ + +#define MPU_MAIR1_Attr6_Pos 16U /*!< MPU MAIR1: Attr6 Position */ +#define MPU_MAIR1_Attr6_Msk (0xFFUL << MPU_MAIR1_Attr6_Pos) /*!< MPU MAIR1: Attr6 Mask */ + +#define MPU_MAIR1_Attr5_Pos 8U /*!< MPU MAIR1: Attr5 Position */ +#define MPU_MAIR1_Attr5_Msk (0xFFUL << MPU_MAIR1_Attr5_Pos) /*!< MPU MAIR1: Attr5 Mask */ + +#define MPU_MAIR1_Attr4_Pos 0U /*!< MPU MAIR1: Attr4 Position */ +#define MPU_MAIR1_Attr4_Msk (0xFFUL /*<< MPU_MAIR1_Attr4_Pos*/) /*!< MPU MAIR1: Attr4 Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SAU Security Attribution Unit (SAU) + \brief Type definitions for the Security Attribution Unit (SAU) + @{ + */ + +/** + \brief Structure type to access the Security Attribution Unit (SAU). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SAU Control Register */ + __IM uint32_t TYPE; /*!< Offset: 0x004 (R/ ) SAU Type Register */ +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) SAU Region Number Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) SAU Region Base Address Register */ + __IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) SAU Region Limit Address Register */ +#else + uint32_t RESERVED0[3]; +#endif + __IOM uint32_t SFSR; /*!< Offset: 0x014 (R/W) Secure Fault Status Register */ + __IOM uint32_t SFAR; /*!< Offset: 0x018 (R/W) Secure Fault Address Register */ +} SAU_Type; + +/* SAU Control Register Definitions */ +#define SAU_CTRL_ALLNS_Pos 1U /*!< SAU CTRL: ALLNS Position */ +#define SAU_CTRL_ALLNS_Msk (1UL << SAU_CTRL_ALLNS_Pos) /*!< SAU CTRL: ALLNS Mask */ + +#define SAU_CTRL_ENABLE_Pos 0U /*!< SAU CTRL: ENABLE Position */ +#define SAU_CTRL_ENABLE_Msk (1UL /*<< SAU_CTRL_ENABLE_Pos*/) /*!< SAU CTRL: ENABLE Mask */ + +/* SAU Type Register Definitions */ +#define SAU_TYPE_SREGION_Pos 0U /*!< SAU TYPE: SREGION Position */ +#define SAU_TYPE_SREGION_Msk (0xFFUL /*<< SAU_TYPE_SREGION_Pos*/) /*!< SAU TYPE: SREGION Mask */ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) +/* SAU Region Number Register Definitions */ +#define SAU_RNR_REGION_Pos 0U /*!< SAU RNR: REGION Position */ +#define SAU_RNR_REGION_Msk (0xFFUL /*<< SAU_RNR_REGION_Pos*/) /*!< SAU RNR: REGION Mask */ + +/* SAU Region Base Address Register Definitions */ +#define SAU_RBAR_BADDR_Pos 5U /*!< SAU RBAR: BADDR Position */ +#define SAU_RBAR_BADDR_Msk (0x7FFFFFFUL << SAU_RBAR_BADDR_Pos) /*!< SAU RBAR: BADDR Mask */ + +/* SAU Region Limit Address Register Definitions */ +#define SAU_RLAR_LADDR_Pos 5U /*!< SAU RLAR: LADDR Position */ +#define SAU_RLAR_LADDR_Msk (0x7FFFFFFUL << SAU_RLAR_LADDR_Pos) /*!< SAU RLAR: LADDR Mask */ + +#define SAU_RLAR_NSC_Pos 1U /*!< SAU RLAR: NSC Position */ +#define SAU_RLAR_NSC_Msk (1UL << SAU_RLAR_NSC_Pos) /*!< SAU RLAR: NSC Mask */ + +#define SAU_RLAR_ENABLE_Pos 0U /*!< SAU RLAR: ENABLE Position */ +#define SAU_RLAR_ENABLE_Msk (1UL /*<< SAU_RLAR_ENABLE_Pos*/) /*!< SAU RLAR: ENABLE Mask */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + +/* Secure Fault Status Register Definitions */ +#define SAU_SFSR_LSERR_Pos 7U /*!< SAU SFSR: LSERR Position */ +#define SAU_SFSR_LSERR_Msk (1UL << SAU_SFSR_LSERR_Pos) /*!< SAU SFSR: LSERR Mask */ + +#define SAU_SFSR_SFARVALID_Pos 6U /*!< SAU SFSR: SFARVALID Position */ +#define SAU_SFSR_SFARVALID_Msk (1UL << SAU_SFSR_SFARVALID_Pos) /*!< SAU SFSR: SFARVALID Mask */ + +#define SAU_SFSR_LSPERR_Pos 5U /*!< SAU SFSR: LSPERR Position */ +#define SAU_SFSR_LSPERR_Msk (1UL << SAU_SFSR_LSPERR_Pos) /*!< SAU SFSR: LSPERR Mask */ + +#define SAU_SFSR_INVTRAN_Pos 4U /*!< SAU SFSR: INVTRAN Position */ +#define SAU_SFSR_INVTRAN_Msk (1UL << SAU_SFSR_INVTRAN_Pos) /*!< SAU SFSR: INVTRAN Mask */ + +#define SAU_SFSR_AUVIOL_Pos 3U /*!< SAU SFSR: AUVIOL Position */ +#define SAU_SFSR_AUVIOL_Msk (1UL << SAU_SFSR_AUVIOL_Pos) /*!< SAU SFSR: AUVIOL Mask */ + +#define SAU_SFSR_INVER_Pos 2U /*!< SAU SFSR: INVER Position */ +#define SAU_SFSR_INVER_Msk (1UL << SAU_SFSR_INVER_Pos) /*!< SAU SFSR: INVER Mask */ + +#define SAU_SFSR_INVIS_Pos 1U /*!< SAU SFSR: INVIS Position */ +#define SAU_SFSR_INVIS_Msk (1UL << SAU_SFSR_INVIS_Pos) /*!< SAU SFSR: INVIS Mask */ + +#define SAU_SFSR_INVEP_Pos 0U /*!< SAU SFSR: INVEP Position */ +#define SAU_SFSR_INVEP_Msk (1UL /*<< SAU_SFSR_INVEP_Pos*/) /*!< SAU SFSR: INVEP Mask */ + +/*@} end of group CMSIS_SAU */ +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_LSPENS_Pos 29U /*!< FPCCR: LSPENS Position */ +#define FPU_FPCCR_LSPENS_Msk (1UL << FPU_FPCCR_LSPENS_Pos) /*!< FPCCR: LSPENS bit Mask */ + +#define FPU_FPCCR_CLRONRET_Pos 28U /*!< FPCCR: CLRONRET Position */ +#define FPU_FPCCR_CLRONRET_Msk (1UL << FPU_FPCCR_CLRONRET_Pos) /*!< FPCCR: CLRONRET bit Mask */ + +#define FPU_FPCCR_CLRONRETS_Pos 27U /*!< FPCCR: CLRONRETS Position */ +#define FPU_FPCCR_CLRONRETS_Msk (1UL << FPU_FPCCR_CLRONRETS_Pos) /*!< FPCCR: CLRONRETS bit Mask */ + +#define FPU_FPCCR_TS_Pos 26U /*!< FPCCR: TS Position */ +#define FPU_FPCCR_TS_Msk (1UL << FPU_FPCCR_TS_Pos) /*!< FPCCR: TS bit Mask */ + +#define FPU_FPCCR_UFRDY_Pos 10U /*!< FPCCR: UFRDY Position */ +#define FPU_FPCCR_UFRDY_Msk (1UL << FPU_FPCCR_UFRDY_Pos) /*!< FPCCR: UFRDY bit Mask */ + +#define FPU_FPCCR_SPLIMVIOL_Pos 9U /*!< FPCCR: SPLIMVIOL Position */ +#define FPU_FPCCR_SPLIMVIOL_Msk (1UL << FPU_FPCCR_SPLIMVIOL_Pos) /*!< FPCCR: SPLIMVIOL bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_SFRDY_Pos 7U /*!< FPCCR: SFRDY Position */ +#define FPU_FPCCR_SFRDY_Msk (1UL << FPU_FPCCR_SFRDY_Pos) /*!< FPCCR: SFRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_S_Pos 2U /*!< FPCCR: Security status of the FP context bit Position */ +#define FPU_FPCCR_S_Msk (1UL << FPU_FPCCR_S_Pos) /*!< FPCCR: Security status of the FP context bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< 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 0U /*!< 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 Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< 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 24U /*!< 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 20U /*!< 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 16U /*!< 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 12U /*!< 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 8U /*!< 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 4U /*!< 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 0U /*!< 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 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< 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 24U /*!< 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 4U /*!< 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 0U /*!< 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 */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ + uint32_t RESERVED4[1U]; + __IOM uint32_t DAUTHCTRL; /*!< Offset: 0x014 (R/W) Debug Authentication Control Register */ + __IOM uint32_t DSCSR; /*!< Offset: 0x018 (R/W) Debug Security Control and Status Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESTART_ST_Pos 26U /*!< CoreDebug DHCSR: S_RESTART_ST Position */ +#define CoreDebug_DHCSR_S_RESTART_ST_Msk (1UL << CoreDebug_DHCSR_S_RESTART_ST_Pos) /*!< CoreDebug DHCSR: S_RESTART_ST Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< 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 24U /*!< 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 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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 5U /*!< 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 3U /*!< 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 2U /*!< 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 1U /*!< 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 0U /*!< 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 Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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 10U /*!< 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 9U /*!< 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 8U /*!< 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 7U /*!< 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 6U /*!< 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 5U /*!< 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 4U /*!< 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 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/* Debug Authentication Control Register Definitions */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos 3U /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Position */ +#define CoreDebug_DAUTHCTRL_INTSPNIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPNIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPNIDEN, Mask */ + +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos 2U /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPNIDENSEL_Msk (1UL << CoreDebug_DAUTHCTRL_SPNIDENSEL_Pos) /*!< CoreDebug DAUTHCTRL: SPNIDENSEL Mask */ + +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Pos 1U /*!< CoreDebug DAUTHCTRL: INTSPIDEN Position */ +#define CoreDebug_DAUTHCTRL_INTSPIDEN_Msk (1UL << CoreDebug_DAUTHCTRL_INTSPIDEN_Pos) /*!< CoreDebug DAUTHCTRL: INTSPIDEN Mask */ + +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Pos 0U /*!< CoreDebug DAUTHCTRL: SPIDENSEL Position */ +#define CoreDebug_DAUTHCTRL_SPIDENSEL_Msk (1UL /*<< CoreDebug_DAUTHCTRL_SPIDENSEL_Pos*/) /*!< CoreDebug DAUTHCTRL: SPIDENSEL Mask */ + +/* Debug Security Control and Status Register Definitions */ +#define CoreDebug_DSCSR_CDS_Pos 16U /*!< CoreDebug DSCSR: CDS Position */ +#define CoreDebug_DSCSR_CDS_Msk (1UL << CoreDebug_DSCSR_CDS_Pos) /*!< CoreDebug DSCSR: CDS Mask */ + +#define CoreDebug_DSCSR_SBRSEL_Pos 1U /*!< CoreDebug DSCSR: SBRSEL Position */ +#define CoreDebug_DSCSR_SBRSEL_Msk (1UL << CoreDebug_DSCSR_SBRSEL_Pos) /*!< CoreDebug DSCSR: SBRSEL Mask */ + +#define CoreDebug_DSCSR_SBRSELEN_Pos 0U /*!< CoreDebug DSCSR: SBRSELEN Position */ +#define CoreDebug_DSCSR_SBRSELEN_Msk (1UL /*<< CoreDebug_DSCSR_SBRSELEN_Pos*/) /*!< CoreDebug DSCSR: SBRSELEN Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ + #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ + #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ + #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ + #define TPI_BASE (0xE0040000UL) /*!< TPI 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 DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + #define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ + #define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE ) /*!< Core Debug configuration struct */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ + #endif + + #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SAU_BASE (SCS_BASE + 0x0DD0UL) /*!< Security Attribution Unit */ + #define SAU ((SAU_Type *) SAU_BASE ) /*!< Security Attribution Unit */ + #endif + + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #define SCS_BASE_NS (0xE002E000UL) /*!< System Control Space Base Address (non-secure address space) */ + #define CoreDebug_BASE_NS (0xE002EDF0UL) /*!< Core Debug Base Address (non-secure address space) */ + #define SysTick_BASE_NS (SCS_BASE_NS + 0x0010UL) /*!< SysTick Base Address (non-secure address space) */ + #define NVIC_BASE_NS (SCS_BASE_NS + 0x0100UL) /*!< NVIC Base Address (non-secure address space) */ + #define SCB_BASE_NS (SCS_BASE_NS + 0x0D00UL) /*!< System Control Block Base Address (non-secure address space) */ + + #define SCnSCB_NS ((SCnSCB_Type *) SCS_BASE_NS ) /*!< System control Register not in SCB(non-secure address space) */ + #define SCB_NS ((SCB_Type *) SCB_BASE_NS ) /*!< SCB configuration struct (non-secure address space) */ + #define SysTick_NS ((SysTick_Type *) SysTick_BASE_NS ) /*!< SysTick configuration struct (non-secure address space) */ + #define NVIC_NS ((NVIC_Type *) NVIC_BASE_NS ) /*!< NVIC configuration struct (non-secure address space) */ + #define CoreDebug_NS ((CoreDebug_Type *) CoreDebug_BASE_NS) /*!< Core Debug configuration struct (non-secure address space) */ + + #if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE_NS (SCS_BASE_NS + 0x0D90UL) /*!< Memory Protection Unit (non-secure address space) */ + #define MPU_NS ((MPU_Type *) MPU_BASE_NS ) /*!< Memory Protection Unit (non-secure address space) */ + #endif + + #define FPU_BASE_NS (SCS_BASE_NS + 0x0F30UL) /*!< Floating Point Unit (non-secure address space) */ + #define FPU_NS ((FPU_Type *) FPU_BASE_NS ) /*!< Floating Point Unit (non-secure address space) */ + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + + +/** + \brief Set Priority Grouping + \details 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)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Interrupt Target State + \details Reads the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + \return 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_GetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Target State + \details Sets the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_SetTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] |= ((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Clear Interrupt Target State + \details Clears the interrupt target field in the NVIC and returns the interrupt target bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 if interrupt is assigned to Secure + 1 if interrupt is assigned to Non Secure + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t NVIC_ClearTargetState(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] &= ~((uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL))); + return((uint32_t)(((NVIC->ITNS[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + 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 Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates 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 = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Grouping (non-secure) + \details Sets the non-secure priority grouping field when in secure state 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 TZ_NVIC_SetPriorityGrouping_NS(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB_NS->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB_NS->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping (non-secure) + \details Reads the priority grouping field from the non-secure NVIC when in secure state. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriorityGrouping_NS(void) +{ + return ((uint32_t)((SCB_NS->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt (non-secure) + \details Enables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_EnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status (non-secure) + \details Returns a device specific interrupt enable status from the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetEnableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt (non-secure) + \details Disables a device specific interrupt in the non-secure NVIC interrupt controller when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_DisableIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Pending Interrupt (non-secure) + \details Reads the NVIC pending register in the non-secure NVIC when in secure state and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt (non-secure) + \details Sets the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_SetPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt (non-secure) + \details Clears the pending bit of a device specific interrupt in the non-secure NVIC pending register when in secure state. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void TZ_NVIC_ClearPendingIRQ_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt (non-secure) + \details Reads the active register in non-secure NVIC when in secure state and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetActive_NS(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC_NS->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority (non-secure) + \details Sets the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every non-secure processor exception. + */ +__STATIC_INLINE void TZ_NVIC_SetPriority_NS(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC_NS->IPR[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority (non-secure) + \details Reads the priority of a non-secure device specific interrupt or a non-secure processor exception when in secure state. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC_NS->IPR[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB_NS->SHPR[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} +#endif /* defined (__ARM_FEATURE_CMSE) &&(__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv8.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x220U) + { + return 2U; /* Double + Single precision FPU */ + } + else if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## SAU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SAUFunctions SAU Functions + \brief Functions that configure the SAU. + @{ + */ + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + +/** + \brief Enable SAU + \details Enables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Enable(void) +{ + SAU->CTRL |= (SAU_CTRL_ENABLE_Msk); +} + + + +/** + \brief Disable SAU + \details Disables the Security Attribution Unit (SAU). + */ +__STATIC_INLINE void TZ_SAU_Disable(void) +{ + SAU->CTRL &= ~(SAU_CTRL_ENABLE_Msk); +} + +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +/*@} end of CMSIS_Core_SAUFunctions */ + + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* 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 (0UL); /* Function successful */ +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +/** + \brief System Tick Configuration (non-secure) + \details Initializes the non-secure System Timer and its interrupt when in secure state, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function TZ_SysTick_Config_NS is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t TZ_SysTick_Config_NS(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick_NS->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + TZ_NVIC_SetPriority_NS (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick_NS->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick_NS->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} +#endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */ + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__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 + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \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 */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_ARMV8MML_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/CMSIS/core_cm4.h b/CMSIS/core_cm4.h new file mode 100644 index 0000000..a11a381 --- /dev/null +++ b/CMSIS/core_cm4.h @@ -0,0 +1,2118 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V5.0.5 + * @date 08. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M4 + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (4U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000U + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#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 */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + 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 */ + 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; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \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; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:1; /*!< bit: 9 Reserved */ + uint32_t ICI_IT_1:6; /*!< bit: 10..15 ICI/IT part 1 */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit */ + uint32_t ICI_IT_2:2; /*!< bit: 25..26 ICI/IT part 2 */ + 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; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_ICI_IT_2_Pos 25U /*!< xPSR: ICI/IT part 2 Position */ +#define xPSR_ICI_IT_2_Msk (3UL << xPSR_ICI_IT_2_Pos) /*!< xPSR: ICI/IT part 2 Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ICI_IT_1_Pos 10U /*!< xPSR: ICI/IT part 1 Position */ +#define xPSR_ICI_IT_1_Msk (0x3FUL << xPSR_ICI_IT_1_Pos) /*!< xPSR: ICI/IT part 1 Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \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; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< 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 System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< 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 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< 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 7U /*!< 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 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< 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 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< 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 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< 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 4U /*!< 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 3U /*!< 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 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< 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 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< 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 8U /*!< 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 0U /*!< 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 */ + +/* MemManage Fault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_MMARVALID_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 7U) /*!< SCB CFSR (MMFSR): MMARVALID Position */ +#define SCB_CFSR_MMARVALID_Msk (1UL << SCB_CFSR_MMARVALID_Pos) /*!< SCB CFSR (MMFSR): MMARVALID Mask */ + +#define SCB_CFSR_MLSPERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 5U) /*!< SCB CFSR (MMFSR): MLSPERR Position */ +#define SCB_CFSR_MLSPERR_Msk (1UL << SCB_CFSR_MLSPERR_Pos) /*!< SCB CFSR (MMFSR): MLSPERR Mask */ + +#define SCB_CFSR_MSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 4U) /*!< SCB CFSR (MMFSR): MSTKERR Position */ +#define SCB_CFSR_MSTKERR_Msk (1UL << SCB_CFSR_MSTKERR_Pos) /*!< SCB CFSR (MMFSR): MSTKERR Mask */ + +#define SCB_CFSR_MUNSTKERR_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 3U) /*!< SCB CFSR (MMFSR): MUNSTKERR Position */ +#define SCB_CFSR_MUNSTKERR_Msk (1UL << SCB_CFSR_MUNSTKERR_Pos) /*!< SCB CFSR (MMFSR): MUNSTKERR Mask */ + +#define SCB_CFSR_DACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 1U) /*!< SCB CFSR (MMFSR): DACCVIOL Position */ +#define SCB_CFSR_DACCVIOL_Msk (1UL << SCB_CFSR_DACCVIOL_Pos) /*!< SCB CFSR (MMFSR): DACCVIOL Mask */ + +#define SCB_CFSR_IACCVIOL_Pos (SCB_SHCSR_MEMFAULTACT_Pos + 0U) /*!< SCB CFSR (MMFSR): IACCVIOL Position */ +#define SCB_CFSR_IACCVIOL_Msk (1UL /*<< SCB_CFSR_IACCVIOL_Pos*/) /*!< SCB CFSR (MMFSR): IACCVIOL Mask */ + +/* BusFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_BFARVALID_Pos (SCB_CFSR_BUSFAULTSR_Pos + 7U) /*!< SCB CFSR (BFSR): BFARVALID Position */ +#define SCB_CFSR_BFARVALID_Msk (1UL << SCB_CFSR_BFARVALID_Pos) /*!< SCB CFSR (BFSR): BFARVALID Mask */ + +#define SCB_CFSR_LSPERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 5U) /*!< SCB CFSR (BFSR): LSPERR Position */ +#define SCB_CFSR_LSPERR_Msk (1UL << SCB_CFSR_LSPERR_Pos) /*!< SCB CFSR (BFSR): LSPERR Mask */ + +#define SCB_CFSR_STKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 4U) /*!< SCB CFSR (BFSR): STKERR Position */ +#define SCB_CFSR_STKERR_Msk (1UL << SCB_CFSR_STKERR_Pos) /*!< SCB CFSR (BFSR): STKERR Mask */ + +#define SCB_CFSR_UNSTKERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 3U) /*!< SCB CFSR (BFSR): UNSTKERR Position */ +#define SCB_CFSR_UNSTKERR_Msk (1UL << SCB_CFSR_UNSTKERR_Pos) /*!< SCB CFSR (BFSR): UNSTKERR Mask */ + +#define SCB_CFSR_IMPRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 2U) /*!< SCB CFSR (BFSR): IMPRECISERR Position */ +#define SCB_CFSR_IMPRECISERR_Msk (1UL << SCB_CFSR_IMPRECISERR_Pos) /*!< SCB CFSR (BFSR): IMPRECISERR Mask */ + +#define SCB_CFSR_PRECISERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 1U) /*!< SCB CFSR (BFSR): PRECISERR Position */ +#define SCB_CFSR_PRECISERR_Msk (1UL << SCB_CFSR_PRECISERR_Pos) /*!< SCB CFSR (BFSR): PRECISERR Mask */ + +#define SCB_CFSR_IBUSERR_Pos (SCB_CFSR_BUSFAULTSR_Pos + 0U) /*!< SCB CFSR (BFSR): IBUSERR Position */ +#define SCB_CFSR_IBUSERR_Msk (1UL << SCB_CFSR_IBUSERR_Pos) /*!< SCB CFSR (BFSR): IBUSERR Mask */ + +/* UsageFault Status Register (part of SCB Configurable Fault Status Register) */ +#define SCB_CFSR_DIVBYZERO_Pos (SCB_CFSR_USGFAULTSR_Pos + 9U) /*!< SCB CFSR (UFSR): DIVBYZERO Position */ +#define SCB_CFSR_DIVBYZERO_Msk (1UL << SCB_CFSR_DIVBYZERO_Pos) /*!< SCB CFSR (UFSR): DIVBYZERO Mask */ + +#define SCB_CFSR_UNALIGNED_Pos (SCB_CFSR_USGFAULTSR_Pos + 8U) /*!< SCB CFSR (UFSR): UNALIGNED Position */ +#define SCB_CFSR_UNALIGNED_Msk (1UL << SCB_CFSR_UNALIGNED_Pos) /*!< SCB CFSR (UFSR): UNALIGNED Mask */ + +#define SCB_CFSR_NOCP_Pos (SCB_CFSR_USGFAULTSR_Pos + 3U) /*!< SCB CFSR (UFSR): NOCP Position */ +#define SCB_CFSR_NOCP_Msk (1UL << SCB_CFSR_NOCP_Pos) /*!< SCB CFSR (UFSR): NOCP Mask */ + +#define SCB_CFSR_INVPC_Pos (SCB_CFSR_USGFAULTSR_Pos + 2U) /*!< SCB CFSR (UFSR): INVPC Position */ +#define SCB_CFSR_INVPC_Msk (1UL << SCB_CFSR_INVPC_Pos) /*!< SCB CFSR (UFSR): INVPC Mask */ + +#define SCB_CFSR_INVSTATE_Pos (SCB_CFSR_USGFAULTSR_Pos + 1U) /*!< SCB CFSR (UFSR): INVSTATE Position */ +#define SCB_CFSR_INVSTATE_Msk (1UL << SCB_CFSR_INVSTATE_Pos) /*!< SCB CFSR (UFSR): INVSTATE Mask */ + +#define SCB_CFSR_UNDEFINSTR_Pos (SCB_CFSR_USGFAULTSR_Pos + 0U) /*!< SCB CFSR (UFSR): UNDEFINSTR Position */ +#define SCB_CFSR_UNDEFINSTR_Msk (1UL << SCB_CFSR_UNDEFINSTR_Pos) /*!< SCB CFSR (UFSR): UNDEFINSTR Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< 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 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< 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 System Controls not in SCB (SCnSCB) + \brief Type definitions for the 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[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< 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 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< 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 System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< 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 0U /*!< 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 0U /*!< 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 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFFFFFFFFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< 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 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< @Deprecated TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< @Deprecated TPI ACPR: PRESCALER Mask */ + +#define TPI_ACPR_SWOSCALER_Pos 0U /*!< TPI ACPR: SWOSCALER Position */ +#define TPI_ACPR_SWOSCALER_Msk (0xFFFFUL /*<< TPI_ACPR_SWOSCALER_Pos*/) /*!< TPI ACPR: SWOSCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 4U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< 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_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< 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 1U /*!< 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 0U /*!< 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 /* defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< 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 1U /*!< 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 0U /*!< 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 Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< 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 24U /*!< 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 20U /*!< 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 16U /*!< 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 12U /*!< 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 8U /*!< 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 4U /*!< 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 0U /*!< 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 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< 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 24U /*!< 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 4U /*!< 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 0U /*!< 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 */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< 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 25U /*!< 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 24U /*!< 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 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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 5U /*!< 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 3U /*!< 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 2U /*!< 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 1U /*!< 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 0U /*!< 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 Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< 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 18U /*!< 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 17U /*!< 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 16U /*!< 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 10U /*!< 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 9U /*!< 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 8U /*!< 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 7U /*!< 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 6U /*!< 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 5U /*!< 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 4U /*!< 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 0U /*!< 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 + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI 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 DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ +#define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ + #define NVIC_GetActive __NVIC_GetActive + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + + +/** + \brief Set Priority Grouping + \details 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)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos) ); /* Insert write key and priority group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in the NVIC and returns the active bit for the device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IABR[(((uint32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[((uint32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) >= 0) + { + return(((uint32_t)NVIC->IP[((uint32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + 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 Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ + uint32_t *vectors = (uint32_t *)SCB->VTOR; + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; +} + + +/** + \brief System Reset + \details Initiates 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 = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = FPU->MVFR0; + if ((mvfr0 & (FPU_MVFR0_Single_precision_Msk | FPU_MVFR0_Double_precision_Msk)) == 0x020U) + { + return 1U; /* Single precision FPU */ + } + else + { + return 0U; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* 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 (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY ((int32_t)0x5AA55AA5U) /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__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 + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \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 */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/CMSIS/mpu_armv7.h b/CMSIS/mpu_armv7.h new file mode 100644 index 0000000..aa180c9 --- /dev/null +++ b/CMSIS/mpu_armv7.h @@ -0,0 +1,197 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) + +#define ARM_MPU_AP_NONE 0U +#define ARM_MPU_AP_PRIV 1U +#define ARM_MPU_AP_URO 2U +#define ARM_MPU_AP_FULL 3U +#define ARM_MPU_AP_PRO 5U +#define ARM_MPU_AP_RO 6U + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ((((DisableExec ) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((TypeExtField ) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable ) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable ) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable ) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk) | \ + (((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \ + (((Size ) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \ + (MPU_RASR_ENABLE_Msk)) + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + orderedCpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + orderedCpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif diff --git a/CMSIS/mpu_armv8.h b/CMSIS/mpu_armv8.h new file mode 100644 index 0000000..0ccfc74 --- /dev/null +++ b/CMSIS/mpu_armv8.h @@ -0,0 +1,333 @@ +/****************************************************************************** + * @file mpu_armv8.h + * @brief CMSIS MPU API for Armv8-M MPU + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV8_H +#define ARM_MPU_ARMV8_H + +/** \brief Attribute for device memory (outer only) */ +#define ARM_MPU_ATTR_DEVICE ( 0U ) + +/** \brief Attribute for non-cacheable, normal memory */ +#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U ) + +/** \brief Attribute for normal memory (outer and inner) +* \param NT Non-Transient: Set to 1 for non-transient data. +* \param WB Write-Back: Set to 1 to use write-back update policy. +* \param RA Read Allocation: Set to 1 to use cache allocation on read miss. +* \param WA Write Allocation: Set to 1 to use cache allocation on write miss. +*/ +#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \ + (((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U)) + +/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U) + +/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGnRE (1U) + +/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_nGRE (2U) + +/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */ +#define ARM_MPU_ATTR_DEVICE_GRE (3U) + +/** \brief Memory Attribute +* \param O Outer memory attributes +* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes +*/ +#define ARM_MPU_ATTR(O, I) (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U))) + +/** \brief Normal memory non-shareable */ +#define ARM_MPU_SH_NON (0U) + +/** \brief Normal memory outer shareable */ +#define ARM_MPU_SH_OUTER (2U) + +/** \brief Normal memory inner shareable */ +#define ARM_MPU_SH_INNER (3U) + +/** \brief Memory access permissions +* \param RO Read-Only: Set to 1 for read-only memory. +* \param NP Non-Privileged: Set to 1 for non-privileged memory. +*/ +#define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U)) + +/** \brief Region Base Address Register value +* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned. +* \param SH Defines the Shareability domain for this memory region. +* \param RO Read-Only: Set to 1 for a read-only memory region. +* \param NP Non-Privileged: Set to 1 for a non-privileged memory region. +* \oaram XN eXecute Never: Set to 1 for a non-executable memory region. +*/ +#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \ + ((BASE & MPU_RBAR_BASE_Pos) | \ + ((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \ + ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \ + ((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk)) + +/** \brief Region Limit Address Register value +* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended. +* \param IDX The attribute index to be associated with this memory region. +*/ +#define ARM_MPU_RLAR(LIMIT, IDX) \ + ((LIMIT & MPU_RLAR_LIMIT_Msk) | \ + ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \ + (MPU_RLAR_EN_Msk)) + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; /*!< Region Base Address Register value */ + uint32_t RLAR; /*!< Region Limit Address Register value */ +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +#ifdef MPU_NS +/** Enable the Non-secure MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the Non-secure MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable_NS(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} +#endif + +/** Set the memory attribute encoding to the given MPU. +* \param mpu Pointer to the MPU to be configured. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr) +{ + const uint8_t reg = idx / 4U; + const uint32_t pos = ((idx % 4U) * 8U); + const uint32_t mask = 0xFFU << pos; + + if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) { + return; // invalid index + } + + mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask)); +} + +/** Set the memory attribute encoding. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU, idx, attr); +} + +#ifdef MPU_NS +/** Set the memory attribute encoding to the Non-secure MPU. +* \param idx The attribute index to be set [0-7] +* \param attr The attribute value to be set. +*/ +__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr) +{ + ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr); +} +#endif + +/** Clear and disable the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr) +{ + mpu->RNR = rnr; + mpu->RLAR = 0U; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU, rnr); +} + +#ifdef MPU_NS +/** Clear and disable the given Non-secure MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr) +{ + ARM_MPU_ClrRegionEx(MPU_NS, rnr); +} +#endif + +/** Configure the given MPU region of the given MPU. +* \param mpu Pointer to MPU to be used. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + mpu->RNR = rnr; + mpu->RBAR = rbar; + mpu->RLAR = rlar; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar); +} + +#ifdef MPU_NS +/** Configure the given Non-secure MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rlar Value for RLAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar) +{ + ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar); +} +#endif + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table to the given MPU. +* \param mpu Pointer to the MPU registers to be used. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + if (cnt == 1U) { + mpu->RNR = rnr; + orderedCpy(&(mpu->RBAR), &(table->RBAR), rowWordSize); + } else { + uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U); + uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES; + + mpu->RNR = rnrBase; + while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) { + uint32_t c = MPU_TYPE_RALIASES - rnrOffset; + orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize); + table += c; + cnt -= c; + rnrOffset = 0U; + rnrBase += MPU_TYPE_RALIASES; + mpu->RNR = rnrBase; + } + + orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize); + } +} + +/** Load the given number of MPU regions from a table. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU, rnr, table, cnt); +} + +#ifdef MPU_NS +/** Load the given number of MPU regions from a table to the Non-secure MPU. +* \param rnr First region number to be configured. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) +{ + ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt); +} +#endif + +#endif + diff --git a/board/board.c b/board/board.c new file mode 100644 index 0000000..4d68088 --- /dev/null +++ b/board/board.c @@ -0,0 +1,46 @@ +/* + * Copyright 2016-2018 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file board.c + * @brief Board initialization file. + */ + +/* This is a template for board specific configuration created by MCUXpresso IDE Project Wizard.*/ + +#include +#include "board.h" + +/** + * @brief Set up and initialize all required blocks and functions related to the board hardware. + */ +void BOARD_InitDebugConsole(void) { + /* The user initialization should be placed here */ +} diff --git a/board/board.h b/board/board.h new file mode 100644 index 0000000..eedde1a --- /dev/null +++ b/board/board.h @@ -0,0 +1,61 @@ +/* + * Copyright 2016-2018 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file board.h + * @brief Board initialization header file. + */ + +/* This is a template for board specific configuration created by MCUXpresso IDE Project Wizard.*/ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/** + * @brief The board name + */ +#define BOARD_NAME "board" + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief Initialize board specific settings. + */ +void BOARD_InitDebugConsole(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +#endif /* _BOARD_H_ */ + + diff --git a/board/clock_config.c b/board/clock_config.c new file mode 100644 index 0000000..465e1f3 --- /dev/null +++ b/board/clock_config.c @@ -0,0 +1,54 @@ +/* + * Copyright 2017-2018 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v4.0 +* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ + +/** + * @file clock_config.c + * @brief Board clocks initialization file. + */ + +/* This is a template for board specific configuration created by MCUXpresso IDE Project Wizard.*/ + +#include "MK64F12.h" +#include "clock_config.h" + +/** + * @brief Set up and initialize all required blocks and functions related to the board hardware. + */ +void BOARD_InitBootClocks(void) { + /* The user initialization should be placed here */ + + /* Read core clock setting. */ + SystemCoreClockUpdate(); +} diff --git a/board/clock_config.h b/board/clock_config.h new file mode 100644 index 0000000..4aec8c9 --- /dev/null +++ b/board/clock_config.h @@ -0,0 +1,56 @@ +/* + * Copyright 2017-2018 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file clock_config.h + * @brief Board clocks header file. + */ + +/* This is a template for board specific configuration created by MCUXpresso IDE Project Wizard.*/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief Initialize board clocks. + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +#endif /* _CLOCK_CONFIG_H_ */ + + diff --git a/board/peripherals.c b/board/peripherals.c new file mode 100644 index 0000000..c3d271d --- /dev/null +++ b/board/peripherals.c @@ -0,0 +1,50 @@ +/* + * Copyright 2017-2018 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Peripherals v1.0 +* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ + +/** + * @file peripherals.c + * @brief Peripherals initialization file. + */ + +/* This is a template for board specific configuration created by MCUXpresso IDE Project Wizard.*/ + +#include "peripherals.h" + +/** + * @brief Set up and initialize all required blocks and functions related to the peripherals hardware. + */ +void BOARD_InitBootPeripherals(void) { + /* The user initialization should be placed here */ +} diff --git a/board/peripherals.h b/board/peripherals.h new file mode 100644 index 0000000..cfc3b4f --- /dev/null +++ b/board/peripherals.h @@ -0,0 +1,56 @@ +/* + * Copyright 2017-2018 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file peripherals.h + * @brief Peripherals initialization header file. + */ + +/* This is a template for board specific configuration created by MCUXpresso IDE Project Wizard.*/ + +#ifndef _PERIPHERALS_H_ +#define _PERIPHERALS_H_ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief Initialize peripherals specific settings. + */ +void BOARD_InitBootPeripherals(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +#endif /* _PERIPHERALS_H_ */ + + diff --git a/board/pin_mux.c b/board/pin_mux.c new file mode 100644 index 0000000..3cd0187 --- /dev/null +++ b/board/pin_mux.c @@ -0,0 +1,50 @@ +/* + * Copyright 2017-2018 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v4.0 +* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********/ + +/** + * @file pin_mux.c + * @brief Board pins file. + */ + +/* This is a template for board specific configuration created by MCUXpresso IDE Project Wizard.*/ + +#include "pin_mux.h" + +/** + * @brief Set up and initialize all required blocks and functions related to the board hardware. + */ +void BOARD_InitBootPins(void) { + /* The user initialization should be placed here */ +} diff --git a/board/pin_mux.h b/board/pin_mux.h new file mode 100644 index 0000000..2397a34 --- /dev/null +++ b/board/pin_mux.h @@ -0,0 +1,56 @@ +/* + * Copyright 2017-2018 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file pin_mux.h + * @brief Board pins header file. + */ + +/* This is a template for board specific configuration created by MCUXpresso IDE Project Wizard.*/ + +#ifndef _PIN_MUX_H_ +#define _PIN_MUX_H_ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief Initialize board pins. + */ +void BOARD_InitBootPins(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +#endif /* _PIN_MUX_H_ */ + + diff --git a/device/MK64F12.h b/device/MK64F12.h new file mode 100644 index 0000000..0756881 --- /dev/null +++ b/device/MK64F12.h @@ -0,0 +1,22404 @@ +/* +** ################################################################### +** Processors: MK64FN1M0CAJ12 +** MK64FN1M0VDC12 +** MK64FN1M0VLL12 +** MK64FN1M0VLQ12 +** MK64FN1M0VMD12 +** MK64FX512VDC12 +** MK64FX512VLL12 +** MK64FX512VLQ12 +** MK64FX512VMD12 +** +** Compilers: Keil ARM C/C++ Compiler +** Freescale C/C++ for Embedded ARM +** GNU C Compiler +** IAR ANSI C/C++ Compiler for ARM +** MCUXpresso Compiler +** +** Reference manual: K64P144M120SF5RM, Rev.2, January 2014 +** Version: rev. 2.9, 2016-03-21 +** Build: b180801 +** +** Abstract: +** CMSIS Peripheral Access Layer for MK64F12 +** +** Copyright 1997-2016 Freescale Semiconductor, Inc. +** Copyright 2016-2018 NXP +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** Revisions: +** - rev. 1.0 (2013-08-12) +** Initial version. +** - rev. 2.0 (2013-10-29) +** Register accessor macros added to the memory map. +** Symbols for Processor Expert memory map compatibility added to the memory map. +** Startup file for gcc has been updated according to CMSIS 3.2. +** System initialization updated. +** MCG - registers updated. +** PORTA, PORTB, PORTC, PORTE - registers for digital filter removed. +** - rev. 2.1 (2013-10-30) +** Definition of BITBAND macros updated to support peripherals with 32-bit acces disabled. +** - rev. 2.2 (2013-12-09) +** DMA - EARS register removed. +** AIPS0, AIPS1 - MPRA register updated. +** - rev. 2.3 (2014-01-24) +** Update according to reference manual rev. 2 +** ENET, MCG, MCM, SIM, USB - registers updated +** - rev. 2.4 (2014-02-10) +** The declaration of clock configurations has been moved to separate header file system_MK64F12.h +** Update of SystemInit() and SystemCoreClockUpdate() functions. +** - rev. 2.5 (2014-02-10) +** The declaration of clock configurations has been moved to separate header file system_MK64F12.h +** Update of SystemInit() and SystemCoreClockUpdate() functions. +** Module access macro module_BASES replaced by module_BASE_PTRS. +** - rev. 2.6 (2014-08-28) +** Update of system files - default clock configuration changed. +** Update of startup files - possibility to override DefaultISR added. +** - rev. 2.7 (2014-10-14) +** Interrupt INT_LPTimer renamed to INT_LPTMR0, interrupt INT_Watchdog renamed to INT_WDOG_EWM. +** - rev. 2.8 (2015-02-19) +** Renamed interrupt vector LLW to LLWU. +** - rev. 2.9 (2016-03-21) +** Added MK64FN1M0CAJ12 part. +** GPIO - renamed port instances: PTx -> GPIOx. +** +** ################################################################### +*/ + +/*! + * @file MK64F12.h + * @version 2.9 + * @date 2016-03-21 + * @brief CMSIS Peripheral Access Layer for MK64F12 + * + * CMSIS Peripheral Access Layer for MK64F12 + */ + +#ifndef _MK64F12_H_ +#define _MK64F12_H_ /**< Symbol preventing repeated inclusion */ + +/** Memory map major version (memory maps with equal major version number are + * compatible) */ +#define MCU_MEM_MAP_VERSION 0x0200U +/** Memory map minor version */ +#define MCU_MEM_MAP_VERSION_MINOR 0x0009U + +/** + * @brief Macro to calculate address of an aliased word in the peripheral + * bitband area for a peripheral register and bit (bit band region 0x40000000 to + * 0x400FFFFF). + * @param Reg Register to access. + * @param Bit Bit number to access. + * @return Address of the aliased word in the peripheral bitband area. + */ +#define BITBAND_REGADDR(Reg,Bit) (0x42000000u + (32u*((uint32_t)&(Reg) - (uint32_t)0x40000000u)) + (4u*((uint32_t)(Bit)))) +/** + * @brief Macro to access a single bit of a peripheral register (bit band region + * 0x40000000 to 0x400FFFFF) using the bit-band alias region access. Can + * be used for peripherals with 32bit access allowed. + * @param Reg Register to access. + * @param Bit Bit number to access. + * @return Value of the targeted bit in the bit band region. + */ +#define BITBAND_REG32(Reg,Bit) (*((uint32_t volatile*)(BITBAND_REGADDR((Reg),(Bit))))) +#define BITBAND_REG(Reg,Bit) (BITBAND_REG32((Reg),(Bit))) +/** + * @brief Macro to access a single bit of a peripheral register (bit band region + * 0x40000000 to 0x400FFFFF) using the bit-band alias region access. Can + * be used for peripherals with 16bit access allowed. + * @param Reg Register to access. + * @param Bit Bit number to access. + * @return Value of the targeted bit in the bit band region. + */ +#define BITBAND_REG16(Reg,Bit) (*((uint16_t volatile*)(BITBAND_REGADDR((Reg),(Bit))))) +/** + * @brief Macro to access a single bit of a peripheral register (bit band region + * 0x40000000 to 0x400FFFFF) using the bit-band alias region access. Can + * be used for peripherals with 8bit access allowed. + * @param Reg Register to access. + * @param Bit Bit number to access. + * @return Value of the targeted bit in the bit band region. + */ +#define BITBAND_REG8(Reg,Bit) (*((uint8_t volatile*)(BITBAND_REGADDR((Reg),(Bit))))) + +/* ---------------------------------------------------------------------------- + -- Interrupt vector numbers + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Interrupt_vector_numbers Interrupt vector numbers + * @{ + */ + +/** Interrupt Number Definitions */ +#define NUMBER_OF_INT_VECTORS 102 /**< Number of interrupts in the Vector table */ + +typedef enum IRQn { + /* Auxiliary constants */ + NotAvail_IRQn = -128, /**< Not available device specific interrupt */ + + /* Core interrupts */ + NonMaskableInt_IRQn = -14, /**< Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< Cortex-M4 SV Hard Fault Interrupt */ + MemoryManagement_IRQn = -12, /**< Cortex-M4 Memory Management Interrupt */ + BusFault_IRQn = -11, /**< Cortex-M4 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /**< Cortex-M4 Usage Fault Interrupt */ + SVCall_IRQn = -5, /**< Cortex-M4 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /**< Cortex-M4 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /**< Cortex-M4 Pend SV Interrupt */ + SysTick_IRQn = -1, /**< Cortex-M4 System Tick Interrupt */ + + /* Device specific interrupts */ + DMA0_IRQn = 0, /**< DMA Channel 0 Transfer Complete */ + DMA1_IRQn = 1, /**< DMA Channel 1 Transfer Complete */ + DMA2_IRQn = 2, /**< DMA Channel 2 Transfer Complete */ + DMA3_IRQn = 3, /**< DMA Channel 3 Transfer Complete */ + DMA4_IRQn = 4, /**< DMA Channel 4 Transfer Complete */ + DMA5_IRQn = 5, /**< DMA Channel 5 Transfer Complete */ + DMA6_IRQn = 6, /**< DMA Channel 6 Transfer Complete */ + DMA7_IRQn = 7, /**< DMA Channel 7 Transfer Complete */ + DMA8_IRQn = 8, /**< DMA Channel 8 Transfer Complete */ + DMA9_IRQn = 9, /**< DMA Channel 9 Transfer Complete */ + DMA10_IRQn = 10, /**< DMA Channel 10 Transfer Complete */ + DMA11_IRQn = 11, /**< DMA Channel 11 Transfer Complete */ + DMA12_IRQn = 12, /**< DMA Channel 12 Transfer Complete */ + DMA13_IRQn = 13, /**< DMA Channel 13 Transfer Complete */ + DMA14_IRQn = 14, /**< DMA Channel 14 Transfer Complete */ + DMA15_IRQn = 15, /**< DMA Channel 15 Transfer Complete */ + DMA_Error_IRQn = 16, /**< DMA Error Interrupt */ + MCM_IRQn = 17, /**< Normal Interrupt */ + FTFE_IRQn = 18, /**< FTFE Command complete interrupt */ + Read_Collision_IRQn = 19, /**< Read Collision Interrupt */ + LVD_LVW_IRQn = 20, /**< Low Voltage Detect, Low Voltage Warning */ + LLWU_IRQn = 21, /**< Low Leakage Wakeup Unit */ + WDOG_EWM_IRQn = 22, /**< WDOG Interrupt */ + RNG_IRQn = 23, /**< RNG Interrupt */ + I2C0_IRQn = 24, /**< I2C0 interrupt */ + I2C1_IRQn = 25, /**< I2C1 interrupt */ + SPI0_IRQn = 26, /**< SPI0 Interrupt */ + SPI1_IRQn = 27, /**< SPI1 Interrupt */ + I2S0_Tx_IRQn = 28, /**< I2S0 transmit interrupt */ + I2S0_Rx_IRQn = 29, /**< I2S0 receive interrupt */ + UART0_LON_IRQn = 30, /**< UART0 LON interrupt */ + UART0_RX_TX_IRQn = 31, /**< UART0 Receive/Transmit interrupt */ + UART0_ERR_IRQn = 32, /**< UART0 Error interrupt */ + UART1_RX_TX_IRQn = 33, /**< UART1 Receive/Transmit interrupt */ + UART1_ERR_IRQn = 34, /**< UART1 Error interrupt */ + UART2_RX_TX_IRQn = 35, /**< UART2 Receive/Transmit interrupt */ + UART2_ERR_IRQn = 36, /**< UART2 Error interrupt */ + UART3_RX_TX_IRQn = 37, /**< UART3 Receive/Transmit interrupt */ + UART3_ERR_IRQn = 38, /**< UART3 Error interrupt */ + ADC0_IRQn = 39, /**< ADC0 interrupt */ + CMP0_IRQn = 40, /**< CMP0 interrupt */ + CMP1_IRQn = 41, /**< CMP1 interrupt */ + FTM0_IRQn = 42, /**< FTM0 fault, overflow and channels interrupt */ + FTM1_IRQn = 43, /**< FTM1 fault, overflow and channels interrupt */ + FTM2_IRQn = 44, /**< FTM2 fault, overflow and channels interrupt */ + CMT_IRQn = 45, /**< CMT interrupt */ + RTC_IRQn = 46, /**< RTC interrupt */ + RTC_Seconds_IRQn = 47, /**< RTC seconds interrupt */ + PIT0_IRQn = 48, /**< PIT timer channel 0 interrupt */ + PIT1_IRQn = 49, /**< PIT timer channel 1 interrupt */ + PIT2_IRQn = 50, /**< PIT timer channel 2 interrupt */ + PIT3_IRQn = 51, /**< PIT timer channel 3 interrupt */ + PDB0_IRQn = 52, /**< PDB0 Interrupt */ + USB0_IRQn = 53, /**< USB0 interrupt */ + USBDCD_IRQn = 54, /**< USBDCD Interrupt */ + Reserved71_IRQn = 55, /**< Reserved interrupt 71 */ + DAC0_IRQn = 56, /**< DAC0 interrupt */ + MCG_IRQn = 57, /**< MCG Interrupt */ + LPTMR0_IRQn = 58, /**< LPTimer interrupt */ + PORTA_IRQn = 59, /**< Port A interrupt */ + PORTB_IRQn = 60, /**< Port B interrupt */ + PORTC_IRQn = 61, /**< Port C interrupt */ + PORTD_IRQn = 62, /**< Port D interrupt */ + PORTE_IRQn = 63, /**< Port E interrupt */ + SWI_IRQn = 64, /**< Software interrupt */ + SPI2_IRQn = 65, /**< SPI2 Interrupt */ + UART4_RX_TX_IRQn = 66, /**< UART4 Receive/Transmit interrupt */ + UART4_ERR_IRQn = 67, /**< UART4 Error interrupt */ + UART5_RX_TX_IRQn = 68, /**< UART5 Receive/Transmit interrupt */ + UART5_ERR_IRQn = 69, /**< UART5 Error interrupt */ + CMP2_IRQn = 70, /**< CMP2 interrupt */ + FTM3_IRQn = 71, /**< FTM3 fault, overflow and channels interrupt */ + DAC1_IRQn = 72, /**< DAC1 interrupt */ + ADC1_IRQn = 73, /**< ADC1 interrupt */ + I2C2_IRQn = 74, /**< I2C2 interrupt */ + CAN0_ORed_Message_buffer_IRQn = 75, /**< CAN0 OR'd message buffers interrupt */ + CAN0_Bus_Off_IRQn = 76, /**< CAN0 bus off interrupt */ + CAN0_Error_IRQn = 77, /**< CAN0 error interrupt */ + CAN0_Tx_Warning_IRQn = 78, /**< CAN0 Tx warning interrupt */ + CAN0_Rx_Warning_IRQn = 79, /**< CAN0 Rx warning interrupt */ + CAN0_Wake_Up_IRQn = 80, /**< CAN0 wake up interrupt */ + SDHC_IRQn = 81, /**< SDHC interrupt */ + ENET_1588_Timer_IRQn = 82, /**< Ethernet MAC IEEE 1588 Timer Interrupt */ + ENET_Transmit_IRQn = 83, /**< Ethernet MAC Transmit Interrupt */ + ENET_Receive_IRQn = 84, /**< Ethernet MAC Receive Interrupt */ + ENET_Error_IRQn = 85 /**< Ethernet MAC Error and miscelaneous Interrupt */ +} IRQn_Type; + +/*! + * @} + */ /* end of group Interrupt_vector_numbers */ + + +/* ---------------------------------------------------------------------------- + -- Cortex M4 Core Configuration + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Cortex_Core_Configuration Cortex M4 Core Configuration + * @{ + */ + +#define __MPU_PRESENT 0 /**< Defines if an MPU is present or not */ +#define __NVIC_PRIO_BITS 4 /**< Number of priority bits implemented in the NVIC */ +#define __Vendor_SysTickConfig 0 /**< Vendor specific implementation of SysTickConfig is defined */ +#define __FPU_PRESENT 1 /**< Defines if an FPU is present or not */ + +#include "core_cm4.h" /* Core Peripheral Access Layer */ +#include "system_MK64F12.h" /* Device specific configuration file */ + +/*! + * @} + */ /* end of group Cortex_Core_Configuration */ + + +/* ---------------------------------------------------------------------------- + -- Mapping Information + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Mapping_Information Mapping Information + * @{ + */ + +/** Mapping Information */ +/*! + * @addtogroup edma_request + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief Structure for the DMA hardware request + * + * Defines the structure for the DMA hardware request collections. The user can configure the + * hardware request into DMAMUX to trigger the DMA transfer accordingly. The index + * of the hardware request varies according to the to SoC. + */ +typedef enum _dma_request_source +{ + kDmaRequestMux0Disable = 0|0x100U, /**< DMAMUX TriggerDisabled. */ + kDmaRequestMux0Reserved1 = 1|0x100U, /**< Reserved1 */ + kDmaRequestMux0UART0Rx = 2|0x100U, /**< UART0 Receive. */ + kDmaRequestMux0UART0Tx = 3|0x100U, /**< UART0 Transmit. */ + kDmaRequestMux0UART1Rx = 4|0x100U, /**< UART1 Receive. */ + kDmaRequestMux0UART1Tx = 5|0x100U, /**< UART1 Transmit. */ + kDmaRequestMux0UART2Rx = 6|0x100U, /**< UART2 Receive. */ + kDmaRequestMux0UART2Tx = 7|0x100U, /**< UART2 Transmit. */ + kDmaRequestMux0UART3Rx = 8|0x100U, /**< UART3 Receive. */ + kDmaRequestMux0UART3Tx = 9|0x100U, /**< UART3 Transmit. */ + kDmaRequestMux0UART4 = 10|0x100U, /**< UART4 Transmit or Receive. */ + kDmaRequestMux0UART5 = 11|0x100U, /**< UART5 Transmit or Receive. */ + kDmaRequestMux0I2S0Rx = 12|0x100U, /**< I2S0 Receive. */ + kDmaRequestMux0I2S0Tx = 13|0x100U, /**< I2S0 Transmit. */ + kDmaRequestMux0SPI0Rx = 14|0x100U, /**< SPI0 Receive. */ + kDmaRequestMux0SPI0Tx = 15|0x100U, /**< SPI0 Transmit. */ + kDmaRequestMux0SPI1 = 16|0x100U, /**< SPI1 Transmit or Receive. */ + kDmaRequestMux0SPI2 = 17|0x100U, /**< SPI2 Transmit or Receive. */ + kDmaRequestMux0I2C0 = 18|0x100U, /**< I2C0. */ + kDmaRequestMux0I2C1I2C2 = 19|0x100U, /**< I2C1 and I2C2. */ + kDmaRequestMux0I2C1 = 19|0x100U, /**< I2C1 and I2C2. */ + kDmaRequestMux0I2C2 = 19|0x100U, /**< I2C1 and I2C2. */ + kDmaRequestMux0FTM0Channel0 = 20|0x100U, /**< FTM0 C0V. */ + kDmaRequestMux0FTM0Channel1 = 21|0x100U, /**< FTM0 C1V. */ + kDmaRequestMux0FTM0Channel2 = 22|0x100U, /**< FTM0 C2V. */ + kDmaRequestMux0FTM0Channel3 = 23|0x100U, /**< FTM0 C3V. */ + kDmaRequestMux0FTM0Channel4 = 24|0x100U, /**< FTM0 C4V. */ + kDmaRequestMux0FTM0Channel5 = 25|0x100U, /**< FTM0 C5V. */ + kDmaRequestMux0FTM0Channel6 = 26|0x100U, /**< FTM0 C6V. */ + kDmaRequestMux0FTM0Channel7 = 27|0x100U, /**< FTM0 C7V. */ + kDmaRequestMux0FTM1Channel0 = 28|0x100U, /**< FTM1 C0V. */ + kDmaRequestMux0FTM1Channel1 = 29|0x100U, /**< FTM1 C1V. */ + kDmaRequestMux0FTM2Channel0 = 30|0x100U, /**< FTM2 C0V. */ + kDmaRequestMux0FTM2Channel1 = 31|0x100U, /**< FTM2 C1V. */ + kDmaRequestMux0FTM3Channel0 = 32|0x100U, /**< FTM3 C0V. */ + kDmaRequestMux0FTM3Channel1 = 33|0x100U, /**< FTM3 C1V. */ + kDmaRequestMux0FTM3Channel2 = 34|0x100U, /**< FTM3 C2V. */ + kDmaRequestMux0FTM3Channel3 = 35|0x100U, /**< FTM3 C3V. */ + kDmaRequestMux0FTM3Channel4 = 36|0x100U, /**< FTM3 C4V. */ + kDmaRequestMux0FTM3Channel5 = 37|0x100U, /**< FTM3 C5V. */ + kDmaRequestMux0FTM3Channel6 = 38|0x100U, /**< FTM3 C6V. */ + kDmaRequestMux0FTM3Channel7 = 39|0x100U, /**< FTM3 C7V. */ + kDmaRequestMux0ADC0 = 40|0x100U, /**< ADC0. */ + kDmaRequestMux0ADC1 = 41|0x100U, /**< ADC1. */ + kDmaRequestMux0CMP0 = 42|0x100U, /**< CMP0. */ + kDmaRequestMux0CMP1 = 43|0x100U, /**< CMP1. */ + kDmaRequestMux0CMP2 = 44|0x100U, /**< CMP2. */ + kDmaRequestMux0DAC0 = 45|0x100U, /**< DAC0. */ + kDmaRequestMux0DAC1 = 46|0x100U, /**< DAC1. */ + kDmaRequestMux0CMT = 47|0x100U, /**< CMT. */ + kDmaRequestMux0PDB = 48|0x100U, /**< PDB0. */ + kDmaRequestMux0PortA = 49|0x100U, /**< PTA. */ + kDmaRequestMux0PortB = 50|0x100U, /**< PTB. */ + kDmaRequestMux0PortC = 51|0x100U, /**< PTC. */ + kDmaRequestMux0PortD = 52|0x100U, /**< PTD. */ + kDmaRequestMux0PortE = 53|0x100U, /**< PTE. */ + kDmaRequestMux0IEEE1588Timer0 = 54|0x100U, /**< ENET IEEE 1588 timer 0. */ + kDmaRequestMux0IEEE1588Timer1 = 55|0x100U, /**< ENET IEEE 1588 timer 1. */ + kDmaRequestMux0IEEE1588Timer2 = 56|0x100U, /**< ENET IEEE 1588 timer 2. */ + kDmaRequestMux0IEEE1588Timer3 = 57|0x100U, /**< ENET IEEE 1588 timer 3. */ + kDmaRequestMux0AlwaysOn58 = 58|0x100U, /**< DMAMUX Always Enabled slot. */ + kDmaRequestMux0AlwaysOn59 = 59|0x100U, /**< DMAMUX Always Enabled slot. */ + kDmaRequestMux0AlwaysOn60 = 60|0x100U, /**< DMAMUX Always Enabled slot. */ + kDmaRequestMux0AlwaysOn61 = 61|0x100U, /**< DMAMUX Always Enabled slot. */ + kDmaRequestMux0AlwaysOn62 = 62|0x100U, /**< DMAMUX Always Enabled slot. */ + kDmaRequestMux0AlwaysOn63 = 63|0x100U, /**< DMAMUX Always Enabled slot. */ +} dma_request_source_t; + +/* @} */ + + +/*! + * @} + */ /* end of group Mapping_Information */ + + +/* ---------------------------------------------------------------------------- + -- Device Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Peripheral_access_layer Device Peripheral Access Layer + * @{ + */ + + +/* +** Start of section using anonymous unions +*/ + +#if defined(__ARMCC_VERSION) + #if (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic push + #else + #pragma push + #pragma anon_unions + #endif +#elif defined(__CWCC__) + #pragma push + #pragma cpp_extensions on +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma language=extended +#else + #error Not supported compiler type +#endif + +/* ---------------------------------------------------------------------------- + -- ADC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ADC_Peripheral_Access_Layer ADC Peripheral Access Layer + * @{ + */ + +/** ADC - Register Layout Typedef */ +typedef struct { + __IO uint32_t SC1[2]; /**< ADC Status and Control Registers 1, array offset: 0x0, array step: 0x4 */ + __IO uint32_t CFG1; /**< ADC Configuration Register 1, offset: 0x8 */ + __IO uint32_t CFG2; /**< ADC Configuration Register 2, offset: 0xC */ + __I uint32_t R[2]; /**< ADC Data Result Register, array offset: 0x10, array step: 0x4 */ + __IO uint32_t CV1; /**< Compare Value Registers, offset: 0x18 */ + __IO uint32_t CV2; /**< Compare Value Registers, offset: 0x1C */ + __IO uint32_t SC2; /**< Status and Control Register 2, offset: 0x20 */ + __IO uint32_t SC3; /**< Status and Control Register 3, offset: 0x24 */ + __IO uint32_t OFS; /**< ADC Offset Correction Register, offset: 0x28 */ + __IO uint32_t PG; /**< ADC Plus-Side Gain Register, offset: 0x2C */ + __IO uint32_t MG; /**< ADC Minus-Side Gain Register, offset: 0x30 */ + __IO uint32_t CLPD; /**< ADC Plus-Side General Calibration Value Register, offset: 0x34 */ + __IO uint32_t CLPS; /**< ADC Plus-Side General Calibration Value Register, offset: 0x38 */ + __IO uint32_t CLP4; /**< ADC Plus-Side General Calibration Value Register, offset: 0x3C */ + __IO uint32_t CLP3; /**< ADC Plus-Side General Calibration Value Register, offset: 0x40 */ + __IO uint32_t CLP2; /**< ADC Plus-Side General Calibration Value Register, offset: 0x44 */ + __IO uint32_t CLP1; /**< ADC Plus-Side General Calibration Value Register, offset: 0x48 */ + __IO uint32_t CLP0; /**< ADC Plus-Side General Calibration Value Register, offset: 0x4C */ + uint8_t RESERVED_0[4]; + __IO uint32_t CLMD; /**< ADC Minus-Side General Calibration Value Register, offset: 0x54 */ + __IO uint32_t CLMS; /**< ADC Minus-Side General Calibration Value Register, offset: 0x58 */ + __IO uint32_t CLM4; /**< ADC Minus-Side General Calibration Value Register, offset: 0x5C */ + __IO uint32_t CLM3; /**< ADC Minus-Side General Calibration Value Register, offset: 0x60 */ + __IO uint32_t CLM2; /**< ADC Minus-Side General Calibration Value Register, offset: 0x64 */ + __IO uint32_t CLM1; /**< ADC Minus-Side General Calibration Value Register, offset: 0x68 */ + __IO uint32_t CLM0; /**< ADC Minus-Side General Calibration Value Register, offset: 0x6C */ +} ADC_Type; + +/* ---------------------------------------------------------------------------- + -- ADC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ADC_Register_Masks ADC Register Masks + * @{ + */ + +/*! @name SC1 - ADC Status and Control Registers 1 */ +/*! @{ */ +#define ADC_SC1_ADCH_MASK (0x1FU) +#define ADC_SC1_ADCH_SHIFT (0U) +/*! ADCH - Input channel select + * 0b00000..When DIFF=0, DADP0 is selected as input; when DIFF=1, DAD0 is selected as input. + * 0b00001..When DIFF=0, DADP1 is selected as input; when DIFF=1, DAD1 is selected as input. + * 0b00010..When DIFF=0, DADP2 is selected as input; when DIFF=1, DAD2 is selected as input. + * 0b00011..When DIFF=0, DADP3 is selected as input; when DIFF=1, DAD3 is selected as input. + * 0b00100..When DIFF=0, AD4 is selected as input; when DIFF=1, it is reserved. + * 0b00101..When DIFF=0, AD5 is selected as input; when DIFF=1, it is reserved. + * 0b00110..When DIFF=0, AD6 is selected as input; when DIFF=1, it is reserved. + * 0b00111..When DIFF=0, AD7 is selected as input; when DIFF=1, it is reserved. + * 0b01000..When DIFF=0, AD8 is selected as input; when DIFF=1, it is reserved. + * 0b01001..When DIFF=0, AD9 is selected as input; when DIFF=1, it is reserved. + * 0b01010..When DIFF=0, AD10 is selected as input; when DIFF=1, it is reserved. + * 0b01011..When DIFF=0, AD11 is selected as input; when DIFF=1, it is reserved. + * 0b01100..When DIFF=0, AD12 is selected as input; when DIFF=1, it is reserved. + * 0b01101..When DIFF=0, AD13 is selected as input; when DIFF=1, it is reserved. + * 0b01110..When DIFF=0, AD14 is selected as input; when DIFF=1, it is reserved. + * 0b01111..When DIFF=0, AD15 is selected as input; when DIFF=1, it is reserved. + * 0b10000..When DIFF=0, AD16 is selected as input; when DIFF=1, it is reserved. + * 0b10001..When DIFF=0, AD17 is selected as input; when DIFF=1, it is reserved. + * 0b10010..When DIFF=0, AD18 is selected as input; when DIFF=1, it is reserved. + * 0b10011..When DIFF=0, AD19 is selected as input; when DIFF=1, it is reserved. + * 0b10100..When DIFF=0, AD20 is selected as input; when DIFF=1, it is reserved. + * 0b10101..When DIFF=0, AD21 is selected as input; when DIFF=1, it is reserved. + * 0b10110..When DIFF=0, AD22 is selected as input; when DIFF=1, it is reserved. + * 0b10111..When DIFF=0, AD23 is selected as input; when DIFF=1, it is reserved. + * 0b11000..Reserved. + * 0b11001..Reserved. + * 0b11010..When DIFF=0, Temp Sensor (single-ended) is selected as input; when DIFF=1, Temp Sensor (differential) is selected as input. + * 0b11011..When DIFF=0, Bandgap (single-ended) is selected as input; when DIFF=1, Bandgap (differential) is selected as input. + * 0b11100..Reserved. + * 0b11101..When DIFF=0,VREFSH is selected as input; when DIFF=1, -VREFSH (differential) is selected as input. Voltage reference selected is determined by SC2[REFSEL]. + * 0b11110..When DIFF=0,VREFSL is selected as input; when DIFF=1, it is reserved. Voltage reference selected is determined by SC2[REFSEL]. + * 0b11111..Module is disabled. + */ +#define ADC_SC1_ADCH(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC1_ADCH_SHIFT)) & ADC_SC1_ADCH_MASK) +#define ADC_SC1_DIFF_MASK (0x20U) +#define ADC_SC1_DIFF_SHIFT (5U) +/*! DIFF - Differential Mode Enable + * 0b0..Single-ended conversions and input channels are selected. + * 0b1..Differential conversions and input channels are selected. + */ +#define ADC_SC1_DIFF(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC1_DIFF_SHIFT)) & ADC_SC1_DIFF_MASK) +#define ADC_SC1_AIEN_MASK (0x40U) +#define ADC_SC1_AIEN_SHIFT (6U) +/*! AIEN - Interrupt Enable + * 0b0..Conversion complete interrupt is disabled. + * 0b1..Conversion complete interrupt is enabled. + */ +#define ADC_SC1_AIEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC1_AIEN_SHIFT)) & ADC_SC1_AIEN_MASK) +#define ADC_SC1_COCO_MASK (0x80U) +#define ADC_SC1_COCO_SHIFT (7U) +/*! COCO - Conversion Complete Flag + * 0b0..Conversion is not completed. + * 0b1..Conversion is completed. + */ +#define ADC_SC1_COCO(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC1_COCO_SHIFT)) & ADC_SC1_COCO_MASK) +/*! @} */ + +/* The count of ADC_SC1 */ +#define ADC_SC1_COUNT (2U) + +/*! @name CFG1 - ADC Configuration Register 1 */ +/*! @{ */ +#define ADC_CFG1_ADICLK_MASK (0x3U) +#define ADC_CFG1_ADICLK_SHIFT (0U) +/*! ADICLK - Input Clock Select + * 0b00..Bus clock + * 0b01..Alternate clock 2 (ALTCLK2) + * 0b10..Alternate clock (ALTCLK) + * 0b11..Asynchronous clock (ADACK) + */ +#define ADC_CFG1_ADICLK(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG1_ADICLK_SHIFT)) & ADC_CFG1_ADICLK_MASK) +#define ADC_CFG1_MODE_MASK (0xCU) +#define ADC_CFG1_MODE_SHIFT (2U) +/*! MODE - Conversion mode selection + * 0b00..When DIFF=0:It is single-ended 8-bit conversion; when DIFF=1, it is differential 9-bit conversion with 2's complement output. + * 0b01..When DIFF=0:It is single-ended 12-bit conversion ; when DIFF=1, it is differential 13-bit conversion with 2's complement output. + * 0b10..When DIFF=0:It is single-ended 10-bit conversion. ; when DIFF=1, it is differential 11-bit conversion with 2's complement output + * 0b11..When DIFF=0:It is single-ended 16-bit conversion..; when DIFF=1, it is differential 16-bit conversion with 2's complement output + */ +#define ADC_CFG1_MODE(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG1_MODE_SHIFT)) & ADC_CFG1_MODE_MASK) +#define ADC_CFG1_ADLSMP_MASK (0x10U) +#define ADC_CFG1_ADLSMP_SHIFT (4U) +/*! ADLSMP - Sample Time Configuration + * 0b0..Short sample time. + * 0b1..Long sample time. + */ +#define ADC_CFG1_ADLSMP(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG1_ADLSMP_SHIFT)) & ADC_CFG1_ADLSMP_MASK) +#define ADC_CFG1_ADIV_MASK (0x60U) +#define ADC_CFG1_ADIV_SHIFT (5U) +/*! ADIV - Clock Divide Select + * 0b00..The divide ratio is 1 and the clock rate is input clock. + * 0b01..The divide ratio is 2 and the clock rate is (input clock)/2. + * 0b10..The divide ratio is 4 and the clock rate is (input clock)/4. + * 0b11..The divide ratio is 8 and the clock rate is (input clock)/8. + */ +#define ADC_CFG1_ADIV(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG1_ADIV_SHIFT)) & ADC_CFG1_ADIV_MASK) +#define ADC_CFG1_ADLPC_MASK (0x80U) +#define ADC_CFG1_ADLPC_SHIFT (7U) +/*! ADLPC - Low-Power Configuration + * 0b0..Normal power configuration. + * 0b1..Low-power configuration. The power is reduced at the expense of maximum clock speed. + */ +#define ADC_CFG1_ADLPC(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG1_ADLPC_SHIFT)) & ADC_CFG1_ADLPC_MASK) +/*! @} */ + +/*! @name CFG2 - ADC Configuration Register 2 */ +/*! @{ */ +#define ADC_CFG2_ADLSTS_MASK (0x3U) +#define ADC_CFG2_ADLSTS_SHIFT (0U) +/*! ADLSTS - Long Sample Time Select + * 0b00..Default longest sample time; 20 extra ADCK cycles; 24 ADCK cycles total. + * 0b01..12 extra ADCK cycles; 16 ADCK cycles total sample time. + * 0b10..6 extra ADCK cycles; 10 ADCK cycles total sample time. + * 0b11..2 extra ADCK cycles; 6 ADCK cycles total sample time. + */ +#define ADC_CFG2_ADLSTS(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG2_ADLSTS_SHIFT)) & ADC_CFG2_ADLSTS_MASK) +#define ADC_CFG2_ADHSC_MASK (0x4U) +#define ADC_CFG2_ADHSC_SHIFT (2U) +/*! ADHSC - High-Speed Configuration + * 0b0..Normal conversion sequence selected. + * 0b1..High-speed conversion sequence selected with 2 additional ADCK cycles to total conversion time. + */ +#define ADC_CFG2_ADHSC(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG2_ADHSC_SHIFT)) & ADC_CFG2_ADHSC_MASK) +#define ADC_CFG2_ADACKEN_MASK (0x8U) +#define ADC_CFG2_ADACKEN_SHIFT (3U) +/*! ADACKEN - Asynchronous Clock Output Enable + * 0b0..Asynchronous clock output disabled; Asynchronous clock is enabled only if selected by ADICLK and a conversion is active. + * 0b1..Asynchronous clock and clock output is enabled regardless of the state of the ADC. + */ +#define ADC_CFG2_ADACKEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG2_ADACKEN_SHIFT)) & ADC_CFG2_ADACKEN_MASK) +#define ADC_CFG2_MUXSEL_MASK (0x10U) +#define ADC_CFG2_MUXSEL_SHIFT (4U) +/*! MUXSEL - ADC Mux Select + * 0b0..ADxxa channels are selected. + * 0b1..ADxxb channels are selected. + */ +#define ADC_CFG2_MUXSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CFG2_MUXSEL_SHIFT)) & ADC_CFG2_MUXSEL_MASK) +/*! @} */ + +/*! @name R - ADC Data Result Register */ +/*! @{ */ +#define ADC_R_D_MASK (0xFFFFU) +#define ADC_R_D_SHIFT (0U) +#define ADC_R_D(x) (((uint32_t)(((uint32_t)(x)) << ADC_R_D_SHIFT)) & ADC_R_D_MASK) +/*! @} */ + +/* The count of ADC_R */ +#define ADC_R_COUNT (2U) + +/*! @name CV1 - Compare Value Registers */ +/*! @{ */ +#define ADC_CV1_CV_MASK (0xFFFFU) +#define ADC_CV1_CV_SHIFT (0U) +#define ADC_CV1_CV(x) (((uint32_t)(((uint32_t)(x)) << ADC_CV1_CV_SHIFT)) & ADC_CV1_CV_MASK) +/*! @} */ + +/*! @name CV2 - Compare Value Registers */ +/*! @{ */ +#define ADC_CV2_CV_MASK (0xFFFFU) +#define ADC_CV2_CV_SHIFT (0U) +#define ADC_CV2_CV(x) (((uint32_t)(((uint32_t)(x)) << ADC_CV2_CV_SHIFT)) & ADC_CV2_CV_MASK) +/*! @} */ + +/*! @name SC2 - Status and Control Register 2 */ +/*! @{ */ +#define ADC_SC2_REFSEL_MASK (0x3U) +#define ADC_SC2_REFSEL_SHIFT (0U) +/*! REFSEL - Voltage Reference Selection + * 0b00..Default voltage reference pin pair, that is, external pins VREFH and VREFL + * 0b01..Alternate reference pair, that is, VALTH and VALTL . This pair may be additional external pins or internal sources depending on the MCU configuration. See the chip configuration information for details specific to this MCU + * 0b10..Reserved + * 0b11..Reserved + */ +#define ADC_SC2_REFSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_REFSEL_SHIFT)) & ADC_SC2_REFSEL_MASK) +#define ADC_SC2_DMAEN_MASK (0x4U) +#define ADC_SC2_DMAEN_SHIFT (2U) +/*! DMAEN - DMA Enable + * 0b0..DMA is disabled. + * 0b1..DMA is enabled and will assert the ADC DMA request during an ADC conversion complete event noted when any of the SC1n[COCO] flags is asserted. + */ +#define ADC_SC2_DMAEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_DMAEN_SHIFT)) & ADC_SC2_DMAEN_MASK) +#define ADC_SC2_ACREN_MASK (0x8U) +#define ADC_SC2_ACREN_SHIFT (3U) +/*! ACREN - Compare Function Range Enable + * 0b0..Range function disabled. Only CV1 is compared. + * 0b1..Range function enabled. Both CV1 and CV2 are compared. + */ +#define ADC_SC2_ACREN(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_ACREN_SHIFT)) & ADC_SC2_ACREN_MASK) +#define ADC_SC2_ACFGT_MASK (0x10U) +#define ADC_SC2_ACFGT_SHIFT (4U) +/*! ACFGT - Compare Function Greater Than Enable + * 0b0..Configures less than threshold, outside range not inclusive and inside range not inclusive; functionality based on the values placed in CV1 and CV2. + * 0b1..Configures greater than or equal to threshold, outside and inside ranges inclusive; functionality based on the values placed in CV1 and CV2. + */ +#define ADC_SC2_ACFGT(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_ACFGT_SHIFT)) & ADC_SC2_ACFGT_MASK) +#define ADC_SC2_ACFE_MASK (0x20U) +#define ADC_SC2_ACFE_SHIFT (5U) +/*! ACFE - Compare Function Enable + * 0b0..Compare function disabled. + * 0b1..Compare function enabled. + */ +#define ADC_SC2_ACFE(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_ACFE_SHIFT)) & ADC_SC2_ACFE_MASK) +#define ADC_SC2_ADTRG_MASK (0x40U) +#define ADC_SC2_ADTRG_SHIFT (6U) +/*! ADTRG - Conversion Trigger Select + * 0b0..Software trigger selected. + * 0b1..Hardware trigger selected. + */ +#define ADC_SC2_ADTRG(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_ADTRG_SHIFT)) & ADC_SC2_ADTRG_MASK) +#define ADC_SC2_ADACT_MASK (0x80U) +#define ADC_SC2_ADACT_SHIFT (7U) +/*! ADACT - Conversion Active + * 0b0..Conversion not in progress. + * 0b1..Conversion in progress. + */ +#define ADC_SC2_ADACT(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC2_ADACT_SHIFT)) & ADC_SC2_ADACT_MASK) +/*! @} */ + +/*! @name SC3 - Status and Control Register 3 */ +/*! @{ */ +#define ADC_SC3_AVGS_MASK (0x3U) +#define ADC_SC3_AVGS_SHIFT (0U) +/*! AVGS - Hardware Average Select + * 0b00..4 samples averaged. + * 0b01..8 samples averaged. + * 0b10..16 samples averaged. + * 0b11..32 samples averaged. + */ +#define ADC_SC3_AVGS(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC3_AVGS_SHIFT)) & ADC_SC3_AVGS_MASK) +#define ADC_SC3_AVGE_MASK (0x4U) +#define ADC_SC3_AVGE_SHIFT (2U) +/*! AVGE - Hardware Average Enable + * 0b0..Hardware average function disabled. + * 0b1..Hardware average function enabled. + */ +#define ADC_SC3_AVGE(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC3_AVGE_SHIFT)) & ADC_SC3_AVGE_MASK) +#define ADC_SC3_ADCO_MASK (0x8U) +#define ADC_SC3_ADCO_SHIFT (3U) +/*! ADCO - Continuous Conversion Enable + * 0b0..One conversion or one set of conversions if the hardware average function is enabled, that is, AVGE=1, after initiating a conversion. + * 0b1..Continuous conversions or sets of conversions if the hardware average function is enabled, that is, AVGE=1, after initiating a conversion. + */ +#define ADC_SC3_ADCO(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC3_ADCO_SHIFT)) & ADC_SC3_ADCO_MASK) +#define ADC_SC3_CALF_MASK (0x40U) +#define ADC_SC3_CALF_SHIFT (6U) +/*! CALF - Calibration Failed Flag + * 0b0..Calibration completed normally. + * 0b1..Calibration failed. ADC accuracy specifications are not guaranteed. + */ +#define ADC_SC3_CALF(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC3_CALF_SHIFT)) & ADC_SC3_CALF_MASK) +#define ADC_SC3_CAL_MASK (0x80U) +#define ADC_SC3_CAL_SHIFT (7U) +#define ADC_SC3_CAL(x) (((uint32_t)(((uint32_t)(x)) << ADC_SC3_CAL_SHIFT)) & ADC_SC3_CAL_MASK) +/*! @} */ + +/*! @name OFS - ADC Offset Correction Register */ +/*! @{ */ +#define ADC_OFS_OFS_MASK (0xFFFFU) +#define ADC_OFS_OFS_SHIFT (0U) +#define ADC_OFS_OFS(x) (((uint32_t)(((uint32_t)(x)) << ADC_OFS_OFS_SHIFT)) & ADC_OFS_OFS_MASK) +/*! @} */ + +/*! @name PG - ADC Plus-Side Gain Register */ +/*! @{ */ +#define ADC_PG_PG_MASK (0xFFFFU) +#define ADC_PG_PG_SHIFT (0U) +#define ADC_PG_PG(x) (((uint32_t)(((uint32_t)(x)) << ADC_PG_PG_SHIFT)) & ADC_PG_PG_MASK) +/*! @} */ + +/*! @name MG - ADC Minus-Side Gain Register */ +/*! @{ */ +#define ADC_MG_MG_MASK (0xFFFFU) +#define ADC_MG_MG_SHIFT (0U) +#define ADC_MG_MG(x) (((uint32_t)(((uint32_t)(x)) << ADC_MG_MG_SHIFT)) & ADC_MG_MG_MASK) +/*! @} */ + +/*! @name CLPD - ADC Plus-Side General Calibration Value Register */ +/*! @{ */ +#define ADC_CLPD_CLPD_MASK (0x3FU) +#define ADC_CLPD_CLPD_SHIFT (0U) +#define ADC_CLPD_CLPD(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLPD_CLPD_SHIFT)) & ADC_CLPD_CLPD_MASK) +/*! @} */ + +/*! @name CLPS - ADC Plus-Side General Calibration Value Register */ +/*! @{ */ +#define ADC_CLPS_CLPS_MASK (0x3FU) +#define ADC_CLPS_CLPS_SHIFT (0U) +#define ADC_CLPS_CLPS(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLPS_CLPS_SHIFT)) & ADC_CLPS_CLPS_MASK) +/*! @} */ + +/*! @name CLP4 - ADC Plus-Side General Calibration Value Register */ +/*! @{ */ +#define ADC_CLP4_CLP4_MASK (0x3FFU) +#define ADC_CLP4_CLP4_SHIFT (0U) +#define ADC_CLP4_CLP4(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLP4_CLP4_SHIFT)) & ADC_CLP4_CLP4_MASK) +/*! @} */ + +/*! @name CLP3 - ADC Plus-Side General Calibration Value Register */ +/*! @{ */ +#define ADC_CLP3_CLP3_MASK (0x1FFU) +#define ADC_CLP3_CLP3_SHIFT (0U) +#define ADC_CLP3_CLP3(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLP3_CLP3_SHIFT)) & ADC_CLP3_CLP3_MASK) +/*! @} */ + +/*! @name CLP2 - ADC Plus-Side General Calibration Value Register */ +/*! @{ */ +#define ADC_CLP2_CLP2_MASK (0xFFU) +#define ADC_CLP2_CLP2_SHIFT (0U) +#define ADC_CLP2_CLP2(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLP2_CLP2_SHIFT)) & ADC_CLP2_CLP2_MASK) +/*! @} */ + +/*! @name CLP1 - ADC Plus-Side General Calibration Value Register */ +/*! @{ */ +#define ADC_CLP1_CLP1_MASK (0x7FU) +#define ADC_CLP1_CLP1_SHIFT (0U) +#define ADC_CLP1_CLP1(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLP1_CLP1_SHIFT)) & ADC_CLP1_CLP1_MASK) +/*! @} */ + +/*! @name CLP0 - ADC Plus-Side General Calibration Value Register */ +/*! @{ */ +#define ADC_CLP0_CLP0_MASK (0x3FU) +#define ADC_CLP0_CLP0_SHIFT (0U) +#define ADC_CLP0_CLP0(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLP0_CLP0_SHIFT)) & ADC_CLP0_CLP0_MASK) +/*! @} */ + +/*! @name CLMD - ADC Minus-Side General Calibration Value Register */ +/*! @{ */ +#define ADC_CLMD_CLMD_MASK (0x3FU) +#define ADC_CLMD_CLMD_SHIFT (0U) +#define ADC_CLMD_CLMD(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLMD_CLMD_SHIFT)) & ADC_CLMD_CLMD_MASK) +/*! @} */ + +/*! @name CLMS - ADC Minus-Side General Calibration Value Register */ +/*! @{ */ +#define ADC_CLMS_CLMS_MASK (0x3FU) +#define ADC_CLMS_CLMS_SHIFT (0U) +#define ADC_CLMS_CLMS(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLMS_CLMS_SHIFT)) & ADC_CLMS_CLMS_MASK) +/*! @} */ + +/*! @name CLM4 - ADC Minus-Side General Calibration Value Register */ +/*! @{ */ +#define ADC_CLM4_CLM4_MASK (0x3FFU) +#define ADC_CLM4_CLM4_SHIFT (0U) +#define ADC_CLM4_CLM4(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLM4_CLM4_SHIFT)) & ADC_CLM4_CLM4_MASK) +/*! @} */ + +/*! @name CLM3 - ADC Minus-Side General Calibration Value Register */ +/*! @{ */ +#define ADC_CLM3_CLM3_MASK (0x1FFU) +#define ADC_CLM3_CLM3_SHIFT (0U) +#define ADC_CLM3_CLM3(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLM3_CLM3_SHIFT)) & ADC_CLM3_CLM3_MASK) +/*! @} */ + +/*! @name CLM2 - ADC Minus-Side General Calibration Value Register */ +/*! @{ */ +#define ADC_CLM2_CLM2_MASK (0xFFU) +#define ADC_CLM2_CLM2_SHIFT (0U) +#define ADC_CLM2_CLM2(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLM2_CLM2_SHIFT)) & ADC_CLM2_CLM2_MASK) +/*! @} */ + +/*! @name CLM1 - ADC Minus-Side General Calibration Value Register */ +/*! @{ */ +#define ADC_CLM1_CLM1_MASK (0x7FU) +#define ADC_CLM1_CLM1_SHIFT (0U) +#define ADC_CLM1_CLM1(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLM1_CLM1_SHIFT)) & ADC_CLM1_CLM1_MASK) +/*! @} */ + +/*! @name CLM0 - ADC Minus-Side General Calibration Value Register */ +/*! @{ */ +#define ADC_CLM0_CLM0_MASK (0x3FU) +#define ADC_CLM0_CLM0_SHIFT (0U) +#define ADC_CLM0_CLM0(x) (((uint32_t)(((uint32_t)(x)) << ADC_CLM0_CLM0_SHIFT)) & ADC_CLM0_CLM0_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group ADC_Register_Masks */ + + +/* ADC - Peripheral instance base addresses */ +/** Peripheral ADC0 base address */ +#define ADC0_BASE (0x4003B000u) +/** Peripheral ADC0 base pointer */ +#define ADC0 ((ADC_Type *)ADC0_BASE) +/** Peripheral ADC1 base address */ +#define ADC1_BASE (0x400BB000u) +/** Peripheral ADC1 base pointer */ +#define ADC1 ((ADC_Type *)ADC1_BASE) +/** Array initializer of ADC peripheral base addresses */ +#define ADC_BASE_ADDRS { ADC0_BASE, ADC1_BASE } +/** Array initializer of ADC peripheral base pointers */ +#define ADC_BASE_PTRS { ADC0, ADC1 } +/** Interrupt vectors for the ADC peripheral type */ +#define ADC_IRQS { ADC0_IRQn, ADC1_IRQn } + +/*! + * @} + */ /* end of group ADC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- AIPS Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup AIPS_Peripheral_Access_Layer AIPS Peripheral Access Layer + * @{ + */ + +/** AIPS - Register Layout Typedef */ +typedef struct { + __IO uint32_t MPRA; /**< Master Privilege Register A, offset: 0x0 */ + uint8_t RESERVED_0[28]; + __IO uint32_t PACRA; /**< Peripheral Access Control Register, offset: 0x20 */ + __IO uint32_t PACRB; /**< Peripheral Access Control Register, offset: 0x24 */ + __IO uint32_t PACRC; /**< Peripheral Access Control Register, offset: 0x28 */ + __IO uint32_t PACRD; /**< Peripheral Access Control Register, offset: 0x2C */ + uint8_t RESERVED_1[16]; + __IO uint32_t PACRE; /**< Peripheral Access Control Register, offset: 0x40 */ + __IO uint32_t PACRF; /**< Peripheral Access Control Register, offset: 0x44 */ + __IO uint32_t PACRG; /**< Peripheral Access Control Register, offset: 0x48 */ + __IO uint32_t PACRH; /**< Peripheral Access Control Register, offset: 0x4C */ + __IO uint32_t PACRI; /**< Peripheral Access Control Register, offset: 0x50 */ + __IO uint32_t PACRJ; /**< Peripheral Access Control Register, offset: 0x54 */ + __IO uint32_t PACRK; /**< Peripheral Access Control Register, offset: 0x58 */ + __IO uint32_t PACRL; /**< Peripheral Access Control Register, offset: 0x5C */ + __IO uint32_t PACRM; /**< Peripheral Access Control Register, offset: 0x60 */ + __IO uint32_t PACRN; /**< Peripheral Access Control Register, offset: 0x64 */ + __IO uint32_t PACRO; /**< Peripheral Access Control Register, offset: 0x68 */ + __IO uint32_t PACRP; /**< Peripheral Access Control Register, offset: 0x6C */ + uint8_t RESERVED_2[16]; + __IO uint32_t PACRU; /**< Peripheral Access Control Register, offset: 0x80 */ +} AIPS_Type; + +/* ---------------------------------------------------------------------------- + -- AIPS Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup AIPS_Register_Masks AIPS Register Masks + * @{ + */ + +/*! @name MPRA - Master Privilege Register A */ +/*! @{ */ +#define AIPS_MPRA_MPL5_MASK (0x100U) +#define AIPS_MPRA_MPL5_SHIFT (8U) +/*! MPL5 - Master 5 Privilege Level + * 0b0..Accesses from this master are forced to user-mode. + * 0b1..Accesses from this master are not forced to user-mode. + */ +#define AIPS_MPRA_MPL5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MPL5_SHIFT)) & AIPS_MPRA_MPL5_MASK) +#define AIPS_MPRA_MTW5_MASK (0x200U) +#define AIPS_MPRA_MTW5_SHIFT (9U) +/*! MTW5 - Master 5 Trusted For Writes + * 0b0..This master is not trusted for write accesses. + * 0b1..This master is trusted for write accesses. + */ +#define AIPS_MPRA_MTW5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTW5_SHIFT)) & AIPS_MPRA_MTW5_MASK) +#define AIPS_MPRA_MTR5_MASK (0x400U) +#define AIPS_MPRA_MTR5_SHIFT (10U) +/*! MTR5 - Master 5 Trusted For Read + * 0b0..This master is not trusted for read accesses. + * 0b1..This master is trusted for read accesses. + */ +#define AIPS_MPRA_MTR5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTR5_SHIFT)) & AIPS_MPRA_MTR5_MASK) +#define AIPS_MPRA_MPL4_MASK (0x1000U) +#define AIPS_MPRA_MPL4_SHIFT (12U) +/*! MPL4 - Master 4 Privilege Level + * 0b0..Accesses from this master are forced to user-mode. + * 0b1..Accesses from this master are not forced to user-mode. + */ +#define AIPS_MPRA_MPL4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MPL4_SHIFT)) & AIPS_MPRA_MPL4_MASK) +#define AIPS_MPRA_MTW4_MASK (0x2000U) +#define AIPS_MPRA_MTW4_SHIFT (13U) +/*! MTW4 - Master 4 Trusted For Writes + * 0b0..This master is not trusted for write accesses. + * 0b1..This master is trusted for write accesses. + */ +#define AIPS_MPRA_MTW4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTW4_SHIFT)) & AIPS_MPRA_MTW4_MASK) +#define AIPS_MPRA_MTR4_MASK (0x4000U) +#define AIPS_MPRA_MTR4_SHIFT (14U) +/*! MTR4 - Master 4 Trusted For Read + * 0b0..This master is not trusted for read accesses. + * 0b1..This master is trusted for read accesses. + */ +#define AIPS_MPRA_MTR4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTR4_SHIFT)) & AIPS_MPRA_MTR4_MASK) +#define AIPS_MPRA_MPL3_MASK (0x10000U) +#define AIPS_MPRA_MPL3_SHIFT (16U) +/*! MPL3 - Master 3 Privilege Level + * 0b0..Accesses from this master are forced to user-mode. + * 0b1..Accesses from this master are not forced to user-mode. + */ +#define AIPS_MPRA_MPL3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MPL3_SHIFT)) & AIPS_MPRA_MPL3_MASK) +#define AIPS_MPRA_MTW3_MASK (0x20000U) +#define AIPS_MPRA_MTW3_SHIFT (17U) +/*! MTW3 - Master 3 Trusted For Writes + * 0b0..This master is not trusted for write accesses. + * 0b1..This master is trusted for write accesses. + */ +#define AIPS_MPRA_MTW3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTW3_SHIFT)) & AIPS_MPRA_MTW3_MASK) +#define AIPS_MPRA_MTR3_MASK (0x40000U) +#define AIPS_MPRA_MTR3_SHIFT (18U) +/*! MTR3 - Master 3 Trusted For Read + * 0b0..This master is not trusted for read accesses. + * 0b1..This master is trusted for read accesses. + */ +#define AIPS_MPRA_MTR3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTR3_SHIFT)) & AIPS_MPRA_MTR3_MASK) +#define AIPS_MPRA_MPL2_MASK (0x100000U) +#define AIPS_MPRA_MPL2_SHIFT (20U) +/*! MPL2 - Master 2 Privilege Level + * 0b0..Accesses from this master are forced to user-mode. + * 0b1..Accesses from this master are not forced to user-mode. + */ +#define AIPS_MPRA_MPL2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MPL2_SHIFT)) & AIPS_MPRA_MPL2_MASK) +#define AIPS_MPRA_MTW2_MASK (0x200000U) +#define AIPS_MPRA_MTW2_SHIFT (21U) +/*! MTW2 - Master 2 Trusted For Writes + * 0b0..This master is not trusted for write accesses. + * 0b1..This master is trusted for write accesses. + */ +#define AIPS_MPRA_MTW2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTW2_SHIFT)) & AIPS_MPRA_MTW2_MASK) +#define AIPS_MPRA_MTR2_MASK (0x400000U) +#define AIPS_MPRA_MTR2_SHIFT (22U) +/*! MTR2 - Master 2 Trusted For Read + * 0b0..This master is not trusted for read accesses. + * 0b1..This master is trusted for read accesses. + */ +#define AIPS_MPRA_MTR2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTR2_SHIFT)) & AIPS_MPRA_MTR2_MASK) +#define AIPS_MPRA_MPL1_MASK (0x1000000U) +#define AIPS_MPRA_MPL1_SHIFT (24U) +/*! MPL1 - Master 1 Privilege Level + * 0b0..Accesses from this master are forced to user-mode. + * 0b1..Accesses from this master are not forced to user-mode. + */ +#define AIPS_MPRA_MPL1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MPL1_SHIFT)) & AIPS_MPRA_MPL1_MASK) +#define AIPS_MPRA_MTW1_MASK (0x2000000U) +#define AIPS_MPRA_MTW1_SHIFT (25U) +/*! MTW1 - Master 1 Trusted for Writes + * 0b0..This master is not trusted for write accesses. + * 0b1..This master is trusted for write accesses. + */ +#define AIPS_MPRA_MTW1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTW1_SHIFT)) & AIPS_MPRA_MTW1_MASK) +#define AIPS_MPRA_MTR1_MASK (0x4000000U) +#define AIPS_MPRA_MTR1_SHIFT (26U) +/*! MTR1 - Master 1 Trusted for Read + * 0b0..This master is not trusted for read accesses. + * 0b1..This master is trusted for read accesses. + */ +#define AIPS_MPRA_MTR1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTR1_SHIFT)) & AIPS_MPRA_MTR1_MASK) +#define AIPS_MPRA_MPL0_MASK (0x10000000U) +#define AIPS_MPRA_MPL0_SHIFT (28U) +/*! MPL0 - Master 0 Privilege Level + * 0b0..Accesses from this master are forced to user-mode. + * 0b1..Accesses from this master are not forced to user-mode. + */ +#define AIPS_MPRA_MPL0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MPL0_SHIFT)) & AIPS_MPRA_MPL0_MASK) +#define AIPS_MPRA_MTW0_MASK (0x20000000U) +#define AIPS_MPRA_MTW0_SHIFT (29U) +/*! MTW0 - Master 0 Trusted For Writes + * 0b0..This master is not trusted for write accesses. + * 0b1..This master is trusted for write accesses. + */ +#define AIPS_MPRA_MTW0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTW0_SHIFT)) & AIPS_MPRA_MTW0_MASK) +#define AIPS_MPRA_MTR0_MASK (0x40000000U) +#define AIPS_MPRA_MTR0_SHIFT (30U) +/*! MTR0 - Master 0 Trusted For Read + * 0b0..This master is not trusted for read accesses. + * 0b1..This master is trusted for read accesses. + */ +#define AIPS_MPRA_MTR0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_MPRA_MTR0_SHIFT)) & AIPS_MPRA_MTR0_MASK) +/*! @} */ + +/*! @name PACRA - Peripheral Access Control Register */ +/*! @{ */ +#define AIPS_PACRA_TP7_MASK (0x1U) +#define AIPS_PACRA_TP7_SHIFT (0U) +/*! TP7 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRA_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_TP7_SHIFT)) & AIPS_PACRA_TP7_MASK) +#define AIPS_PACRA_WP7_MASK (0x2U) +#define AIPS_PACRA_WP7_SHIFT (1U) +/*! WP7 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRA_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_WP7_SHIFT)) & AIPS_PACRA_WP7_MASK) +#define AIPS_PACRA_SP7_MASK (0x4U) +#define AIPS_PACRA_SP7_SHIFT (2U) +/*! SP7 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRA_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_SP7_SHIFT)) & AIPS_PACRA_SP7_MASK) +#define AIPS_PACRA_TP6_MASK (0x10U) +#define AIPS_PACRA_TP6_SHIFT (4U) +/*! TP6 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRA_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_TP6_SHIFT)) & AIPS_PACRA_TP6_MASK) +#define AIPS_PACRA_WP6_MASK (0x20U) +#define AIPS_PACRA_WP6_SHIFT (5U) +/*! WP6 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRA_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_WP6_SHIFT)) & AIPS_PACRA_WP6_MASK) +#define AIPS_PACRA_SP6_MASK (0x40U) +#define AIPS_PACRA_SP6_SHIFT (6U) +/*! SP6 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRA_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_SP6_SHIFT)) & AIPS_PACRA_SP6_MASK) +#define AIPS_PACRA_TP5_MASK (0x100U) +#define AIPS_PACRA_TP5_SHIFT (8U) +/*! TP5 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRA_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_TP5_SHIFT)) & AIPS_PACRA_TP5_MASK) +#define AIPS_PACRA_WP5_MASK (0x200U) +#define AIPS_PACRA_WP5_SHIFT (9U) +/*! WP5 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRA_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_WP5_SHIFT)) & AIPS_PACRA_WP5_MASK) +#define AIPS_PACRA_SP5_MASK (0x400U) +#define AIPS_PACRA_SP5_SHIFT (10U) +/*! SP5 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRA_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_SP5_SHIFT)) & AIPS_PACRA_SP5_MASK) +#define AIPS_PACRA_TP4_MASK (0x1000U) +#define AIPS_PACRA_TP4_SHIFT (12U) +/*! TP4 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRA_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_TP4_SHIFT)) & AIPS_PACRA_TP4_MASK) +#define AIPS_PACRA_WP4_MASK (0x2000U) +#define AIPS_PACRA_WP4_SHIFT (13U) +/*! WP4 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRA_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_WP4_SHIFT)) & AIPS_PACRA_WP4_MASK) +#define AIPS_PACRA_SP4_MASK (0x4000U) +#define AIPS_PACRA_SP4_SHIFT (14U) +/*! SP4 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRA_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_SP4_SHIFT)) & AIPS_PACRA_SP4_MASK) +#define AIPS_PACRA_TP3_MASK (0x10000U) +#define AIPS_PACRA_TP3_SHIFT (16U) +/*! TP3 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRA_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_TP3_SHIFT)) & AIPS_PACRA_TP3_MASK) +#define AIPS_PACRA_WP3_MASK (0x20000U) +#define AIPS_PACRA_WP3_SHIFT (17U) +/*! WP3 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRA_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_WP3_SHIFT)) & AIPS_PACRA_WP3_MASK) +#define AIPS_PACRA_SP3_MASK (0x40000U) +#define AIPS_PACRA_SP3_SHIFT (18U) +/*! SP3 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRA_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_SP3_SHIFT)) & AIPS_PACRA_SP3_MASK) +#define AIPS_PACRA_TP2_MASK (0x100000U) +#define AIPS_PACRA_TP2_SHIFT (20U) +/*! TP2 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRA_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_TP2_SHIFT)) & AIPS_PACRA_TP2_MASK) +#define AIPS_PACRA_WP2_MASK (0x200000U) +#define AIPS_PACRA_WP2_SHIFT (21U) +/*! WP2 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRA_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_WP2_SHIFT)) & AIPS_PACRA_WP2_MASK) +#define AIPS_PACRA_SP2_MASK (0x400000U) +#define AIPS_PACRA_SP2_SHIFT (22U) +/*! SP2 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRA_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_SP2_SHIFT)) & AIPS_PACRA_SP2_MASK) +#define AIPS_PACRA_TP1_MASK (0x1000000U) +#define AIPS_PACRA_TP1_SHIFT (24U) +/*! TP1 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRA_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_TP1_SHIFT)) & AIPS_PACRA_TP1_MASK) +#define AIPS_PACRA_WP1_MASK (0x2000000U) +#define AIPS_PACRA_WP1_SHIFT (25U) +/*! WP1 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRA_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_WP1_SHIFT)) & AIPS_PACRA_WP1_MASK) +#define AIPS_PACRA_SP1_MASK (0x4000000U) +#define AIPS_PACRA_SP1_SHIFT (26U) +/*! SP1 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRA_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_SP1_SHIFT)) & AIPS_PACRA_SP1_MASK) +#define AIPS_PACRA_TP0_MASK (0x10000000U) +#define AIPS_PACRA_TP0_SHIFT (28U) +/*! TP0 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRA_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_TP0_SHIFT)) & AIPS_PACRA_TP0_MASK) +#define AIPS_PACRA_WP0_MASK (0x20000000U) +#define AIPS_PACRA_WP0_SHIFT (29U) +/*! WP0 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRA_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_WP0_SHIFT)) & AIPS_PACRA_WP0_MASK) +#define AIPS_PACRA_SP0_MASK (0x40000000U) +#define AIPS_PACRA_SP0_SHIFT (30U) +/*! SP0 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRA_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRA_SP0_SHIFT)) & AIPS_PACRA_SP0_MASK) +/*! @} */ + +/*! @name PACRB - Peripheral Access Control Register */ +/*! @{ */ +#define AIPS_PACRB_TP7_MASK (0x1U) +#define AIPS_PACRB_TP7_SHIFT (0U) +/*! TP7 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRB_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_TP7_SHIFT)) & AIPS_PACRB_TP7_MASK) +#define AIPS_PACRB_WP7_MASK (0x2U) +#define AIPS_PACRB_WP7_SHIFT (1U) +/*! WP7 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRB_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_WP7_SHIFT)) & AIPS_PACRB_WP7_MASK) +#define AIPS_PACRB_SP7_MASK (0x4U) +#define AIPS_PACRB_SP7_SHIFT (2U) +/*! SP7 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRB_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_SP7_SHIFT)) & AIPS_PACRB_SP7_MASK) +#define AIPS_PACRB_TP6_MASK (0x10U) +#define AIPS_PACRB_TP6_SHIFT (4U) +/*! TP6 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRB_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_TP6_SHIFT)) & AIPS_PACRB_TP6_MASK) +#define AIPS_PACRB_WP6_MASK (0x20U) +#define AIPS_PACRB_WP6_SHIFT (5U) +/*! WP6 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRB_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_WP6_SHIFT)) & AIPS_PACRB_WP6_MASK) +#define AIPS_PACRB_SP6_MASK (0x40U) +#define AIPS_PACRB_SP6_SHIFT (6U) +/*! SP6 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRB_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_SP6_SHIFT)) & AIPS_PACRB_SP6_MASK) +#define AIPS_PACRB_TP5_MASK (0x100U) +#define AIPS_PACRB_TP5_SHIFT (8U) +/*! TP5 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRB_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_TP5_SHIFT)) & AIPS_PACRB_TP5_MASK) +#define AIPS_PACRB_WP5_MASK (0x200U) +#define AIPS_PACRB_WP5_SHIFT (9U) +/*! WP5 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRB_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_WP5_SHIFT)) & AIPS_PACRB_WP5_MASK) +#define AIPS_PACRB_SP5_MASK (0x400U) +#define AIPS_PACRB_SP5_SHIFT (10U) +/*! SP5 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRB_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_SP5_SHIFT)) & AIPS_PACRB_SP5_MASK) +#define AIPS_PACRB_TP4_MASK (0x1000U) +#define AIPS_PACRB_TP4_SHIFT (12U) +/*! TP4 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRB_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_TP4_SHIFT)) & AIPS_PACRB_TP4_MASK) +#define AIPS_PACRB_WP4_MASK (0x2000U) +#define AIPS_PACRB_WP4_SHIFT (13U) +/*! WP4 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRB_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_WP4_SHIFT)) & AIPS_PACRB_WP4_MASK) +#define AIPS_PACRB_SP4_MASK (0x4000U) +#define AIPS_PACRB_SP4_SHIFT (14U) +/*! SP4 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRB_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_SP4_SHIFT)) & AIPS_PACRB_SP4_MASK) +#define AIPS_PACRB_TP3_MASK (0x10000U) +#define AIPS_PACRB_TP3_SHIFT (16U) +/*! TP3 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRB_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_TP3_SHIFT)) & AIPS_PACRB_TP3_MASK) +#define AIPS_PACRB_WP3_MASK (0x20000U) +#define AIPS_PACRB_WP3_SHIFT (17U) +/*! WP3 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRB_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_WP3_SHIFT)) & AIPS_PACRB_WP3_MASK) +#define AIPS_PACRB_SP3_MASK (0x40000U) +#define AIPS_PACRB_SP3_SHIFT (18U) +/*! SP3 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRB_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_SP3_SHIFT)) & AIPS_PACRB_SP3_MASK) +#define AIPS_PACRB_TP2_MASK (0x100000U) +#define AIPS_PACRB_TP2_SHIFT (20U) +/*! TP2 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRB_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_TP2_SHIFT)) & AIPS_PACRB_TP2_MASK) +#define AIPS_PACRB_WP2_MASK (0x200000U) +#define AIPS_PACRB_WP2_SHIFT (21U) +/*! WP2 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRB_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_WP2_SHIFT)) & AIPS_PACRB_WP2_MASK) +#define AIPS_PACRB_SP2_MASK (0x400000U) +#define AIPS_PACRB_SP2_SHIFT (22U) +/*! SP2 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRB_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_SP2_SHIFT)) & AIPS_PACRB_SP2_MASK) +#define AIPS_PACRB_TP1_MASK (0x1000000U) +#define AIPS_PACRB_TP1_SHIFT (24U) +/*! TP1 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRB_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_TP1_SHIFT)) & AIPS_PACRB_TP1_MASK) +#define AIPS_PACRB_WP1_MASK (0x2000000U) +#define AIPS_PACRB_WP1_SHIFT (25U) +/*! WP1 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRB_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_WP1_SHIFT)) & AIPS_PACRB_WP1_MASK) +#define AIPS_PACRB_SP1_MASK (0x4000000U) +#define AIPS_PACRB_SP1_SHIFT (26U) +/*! SP1 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRB_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_SP1_SHIFT)) & AIPS_PACRB_SP1_MASK) +#define AIPS_PACRB_TP0_MASK (0x10000000U) +#define AIPS_PACRB_TP0_SHIFT (28U) +/*! TP0 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRB_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_TP0_SHIFT)) & AIPS_PACRB_TP0_MASK) +#define AIPS_PACRB_WP0_MASK (0x20000000U) +#define AIPS_PACRB_WP0_SHIFT (29U) +/*! WP0 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRB_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_WP0_SHIFT)) & AIPS_PACRB_WP0_MASK) +#define AIPS_PACRB_SP0_MASK (0x40000000U) +#define AIPS_PACRB_SP0_SHIFT (30U) +/*! SP0 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRB_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRB_SP0_SHIFT)) & AIPS_PACRB_SP0_MASK) +/*! @} */ + +/*! @name PACRC - Peripheral Access Control Register */ +/*! @{ */ +#define AIPS_PACRC_TP7_MASK (0x1U) +#define AIPS_PACRC_TP7_SHIFT (0U) +/*! TP7 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRC_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_TP7_SHIFT)) & AIPS_PACRC_TP7_MASK) +#define AIPS_PACRC_WP7_MASK (0x2U) +#define AIPS_PACRC_WP7_SHIFT (1U) +/*! WP7 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRC_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_WP7_SHIFT)) & AIPS_PACRC_WP7_MASK) +#define AIPS_PACRC_SP7_MASK (0x4U) +#define AIPS_PACRC_SP7_SHIFT (2U) +/*! SP7 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRC_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_SP7_SHIFT)) & AIPS_PACRC_SP7_MASK) +#define AIPS_PACRC_TP6_MASK (0x10U) +#define AIPS_PACRC_TP6_SHIFT (4U) +/*! TP6 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRC_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_TP6_SHIFT)) & AIPS_PACRC_TP6_MASK) +#define AIPS_PACRC_WP6_MASK (0x20U) +#define AIPS_PACRC_WP6_SHIFT (5U) +/*! WP6 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRC_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_WP6_SHIFT)) & AIPS_PACRC_WP6_MASK) +#define AIPS_PACRC_SP6_MASK (0x40U) +#define AIPS_PACRC_SP6_SHIFT (6U) +/*! SP6 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRC_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_SP6_SHIFT)) & AIPS_PACRC_SP6_MASK) +#define AIPS_PACRC_TP5_MASK (0x100U) +#define AIPS_PACRC_TP5_SHIFT (8U) +/*! TP5 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRC_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_TP5_SHIFT)) & AIPS_PACRC_TP5_MASK) +#define AIPS_PACRC_WP5_MASK (0x200U) +#define AIPS_PACRC_WP5_SHIFT (9U) +/*! WP5 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRC_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_WP5_SHIFT)) & AIPS_PACRC_WP5_MASK) +#define AIPS_PACRC_SP5_MASK (0x400U) +#define AIPS_PACRC_SP5_SHIFT (10U) +/*! SP5 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRC_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_SP5_SHIFT)) & AIPS_PACRC_SP5_MASK) +#define AIPS_PACRC_TP4_MASK (0x1000U) +#define AIPS_PACRC_TP4_SHIFT (12U) +/*! TP4 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRC_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_TP4_SHIFT)) & AIPS_PACRC_TP4_MASK) +#define AIPS_PACRC_WP4_MASK (0x2000U) +#define AIPS_PACRC_WP4_SHIFT (13U) +/*! WP4 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRC_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_WP4_SHIFT)) & AIPS_PACRC_WP4_MASK) +#define AIPS_PACRC_SP4_MASK (0x4000U) +#define AIPS_PACRC_SP4_SHIFT (14U) +/*! SP4 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRC_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_SP4_SHIFT)) & AIPS_PACRC_SP4_MASK) +#define AIPS_PACRC_TP3_MASK (0x10000U) +#define AIPS_PACRC_TP3_SHIFT (16U) +/*! TP3 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRC_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_TP3_SHIFT)) & AIPS_PACRC_TP3_MASK) +#define AIPS_PACRC_WP3_MASK (0x20000U) +#define AIPS_PACRC_WP3_SHIFT (17U) +/*! WP3 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRC_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_WP3_SHIFT)) & AIPS_PACRC_WP3_MASK) +#define AIPS_PACRC_SP3_MASK (0x40000U) +#define AIPS_PACRC_SP3_SHIFT (18U) +/*! SP3 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRC_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_SP3_SHIFT)) & AIPS_PACRC_SP3_MASK) +#define AIPS_PACRC_TP2_MASK (0x100000U) +#define AIPS_PACRC_TP2_SHIFT (20U) +/*! TP2 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRC_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_TP2_SHIFT)) & AIPS_PACRC_TP2_MASK) +#define AIPS_PACRC_WP2_MASK (0x200000U) +#define AIPS_PACRC_WP2_SHIFT (21U) +/*! WP2 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRC_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_WP2_SHIFT)) & AIPS_PACRC_WP2_MASK) +#define AIPS_PACRC_SP2_MASK (0x400000U) +#define AIPS_PACRC_SP2_SHIFT (22U) +/*! SP2 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRC_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_SP2_SHIFT)) & AIPS_PACRC_SP2_MASK) +#define AIPS_PACRC_TP1_MASK (0x1000000U) +#define AIPS_PACRC_TP1_SHIFT (24U) +/*! TP1 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRC_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_TP1_SHIFT)) & AIPS_PACRC_TP1_MASK) +#define AIPS_PACRC_WP1_MASK (0x2000000U) +#define AIPS_PACRC_WP1_SHIFT (25U) +/*! WP1 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRC_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_WP1_SHIFT)) & AIPS_PACRC_WP1_MASK) +#define AIPS_PACRC_SP1_MASK (0x4000000U) +#define AIPS_PACRC_SP1_SHIFT (26U) +/*! SP1 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRC_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_SP1_SHIFT)) & AIPS_PACRC_SP1_MASK) +#define AIPS_PACRC_TP0_MASK (0x10000000U) +#define AIPS_PACRC_TP0_SHIFT (28U) +/*! TP0 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRC_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_TP0_SHIFT)) & AIPS_PACRC_TP0_MASK) +#define AIPS_PACRC_WP0_MASK (0x20000000U) +#define AIPS_PACRC_WP0_SHIFT (29U) +/*! WP0 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRC_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_WP0_SHIFT)) & AIPS_PACRC_WP0_MASK) +#define AIPS_PACRC_SP0_MASK (0x40000000U) +#define AIPS_PACRC_SP0_SHIFT (30U) +/*! SP0 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRC_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRC_SP0_SHIFT)) & AIPS_PACRC_SP0_MASK) +/*! @} */ + +/*! @name PACRD - Peripheral Access Control Register */ +/*! @{ */ +#define AIPS_PACRD_TP7_MASK (0x1U) +#define AIPS_PACRD_TP7_SHIFT (0U) +/*! TP7 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRD_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_TP7_SHIFT)) & AIPS_PACRD_TP7_MASK) +#define AIPS_PACRD_WP7_MASK (0x2U) +#define AIPS_PACRD_WP7_SHIFT (1U) +/*! WP7 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRD_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_WP7_SHIFT)) & AIPS_PACRD_WP7_MASK) +#define AIPS_PACRD_SP7_MASK (0x4U) +#define AIPS_PACRD_SP7_SHIFT (2U) +/*! SP7 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRD_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_SP7_SHIFT)) & AIPS_PACRD_SP7_MASK) +#define AIPS_PACRD_TP6_MASK (0x10U) +#define AIPS_PACRD_TP6_SHIFT (4U) +/*! TP6 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRD_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_TP6_SHIFT)) & AIPS_PACRD_TP6_MASK) +#define AIPS_PACRD_WP6_MASK (0x20U) +#define AIPS_PACRD_WP6_SHIFT (5U) +/*! WP6 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRD_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_WP6_SHIFT)) & AIPS_PACRD_WP6_MASK) +#define AIPS_PACRD_SP6_MASK (0x40U) +#define AIPS_PACRD_SP6_SHIFT (6U) +/*! SP6 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRD_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_SP6_SHIFT)) & AIPS_PACRD_SP6_MASK) +#define AIPS_PACRD_TP5_MASK (0x100U) +#define AIPS_PACRD_TP5_SHIFT (8U) +/*! TP5 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRD_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_TP5_SHIFT)) & AIPS_PACRD_TP5_MASK) +#define AIPS_PACRD_WP5_MASK (0x200U) +#define AIPS_PACRD_WP5_SHIFT (9U) +/*! WP5 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRD_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_WP5_SHIFT)) & AIPS_PACRD_WP5_MASK) +#define AIPS_PACRD_SP5_MASK (0x400U) +#define AIPS_PACRD_SP5_SHIFT (10U) +/*! SP5 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRD_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_SP5_SHIFT)) & AIPS_PACRD_SP5_MASK) +#define AIPS_PACRD_TP4_MASK (0x1000U) +#define AIPS_PACRD_TP4_SHIFT (12U) +/*! TP4 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRD_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_TP4_SHIFT)) & AIPS_PACRD_TP4_MASK) +#define AIPS_PACRD_WP4_MASK (0x2000U) +#define AIPS_PACRD_WP4_SHIFT (13U) +/*! WP4 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRD_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_WP4_SHIFT)) & AIPS_PACRD_WP4_MASK) +#define AIPS_PACRD_SP4_MASK (0x4000U) +#define AIPS_PACRD_SP4_SHIFT (14U) +/*! SP4 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRD_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_SP4_SHIFT)) & AIPS_PACRD_SP4_MASK) +#define AIPS_PACRD_TP3_MASK (0x10000U) +#define AIPS_PACRD_TP3_SHIFT (16U) +/*! TP3 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRD_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_TP3_SHIFT)) & AIPS_PACRD_TP3_MASK) +#define AIPS_PACRD_WP3_MASK (0x20000U) +#define AIPS_PACRD_WP3_SHIFT (17U) +/*! WP3 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRD_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_WP3_SHIFT)) & AIPS_PACRD_WP3_MASK) +#define AIPS_PACRD_SP3_MASK (0x40000U) +#define AIPS_PACRD_SP3_SHIFT (18U) +/*! SP3 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRD_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_SP3_SHIFT)) & AIPS_PACRD_SP3_MASK) +#define AIPS_PACRD_TP2_MASK (0x100000U) +#define AIPS_PACRD_TP2_SHIFT (20U) +/*! TP2 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRD_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_TP2_SHIFT)) & AIPS_PACRD_TP2_MASK) +#define AIPS_PACRD_WP2_MASK (0x200000U) +#define AIPS_PACRD_WP2_SHIFT (21U) +/*! WP2 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRD_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_WP2_SHIFT)) & AIPS_PACRD_WP2_MASK) +#define AIPS_PACRD_SP2_MASK (0x400000U) +#define AIPS_PACRD_SP2_SHIFT (22U) +/*! SP2 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRD_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_SP2_SHIFT)) & AIPS_PACRD_SP2_MASK) +#define AIPS_PACRD_TP1_MASK (0x1000000U) +#define AIPS_PACRD_TP1_SHIFT (24U) +/*! TP1 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRD_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_TP1_SHIFT)) & AIPS_PACRD_TP1_MASK) +#define AIPS_PACRD_WP1_MASK (0x2000000U) +#define AIPS_PACRD_WP1_SHIFT (25U) +/*! WP1 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRD_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_WP1_SHIFT)) & AIPS_PACRD_WP1_MASK) +#define AIPS_PACRD_SP1_MASK (0x4000000U) +#define AIPS_PACRD_SP1_SHIFT (26U) +/*! SP1 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRD_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_SP1_SHIFT)) & AIPS_PACRD_SP1_MASK) +#define AIPS_PACRD_TP0_MASK (0x10000000U) +#define AIPS_PACRD_TP0_SHIFT (28U) +/*! TP0 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRD_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_TP0_SHIFT)) & AIPS_PACRD_TP0_MASK) +#define AIPS_PACRD_WP0_MASK (0x20000000U) +#define AIPS_PACRD_WP0_SHIFT (29U) +/*! WP0 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRD_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_WP0_SHIFT)) & AIPS_PACRD_WP0_MASK) +#define AIPS_PACRD_SP0_MASK (0x40000000U) +#define AIPS_PACRD_SP0_SHIFT (30U) +/*! SP0 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRD_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRD_SP0_SHIFT)) & AIPS_PACRD_SP0_MASK) +/*! @} */ + +/*! @name PACRE - Peripheral Access Control Register */ +/*! @{ */ +#define AIPS_PACRE_TP7_MASK (0x1U) +#define AIPS_PACRE_TP7_SHIFT (0U) +/*! TP7 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRE_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_TP7_SHIFT)) & AIPS_PACRE_TP7_MASK) +#define AIPS_PACRE_WP7_MASK (0x2U) +#define AIPS_PACRE_WP7_SHIFT (1U) +/*! WP7 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRE_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_WP7_SHIFT)) & AIPS_PACRE_WP7_MASK) +#define AIPS_PACRE_SP7_MASK (0x4U) +#define AIPS_PACRE_SP7_SHIFT (2U) +/*! SP7 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRE_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_SP7_SHIFT)) & AIPS_PACRE_SP7_MASK) +#define AIPS_PACRE_TP6_MASK (0x10U) +#define AIPS_PACRE_TP6_SHIFT (4U) +/*! TP6 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRE_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_TP6_SHIFT)) & AIPS_PACRE_TP6_MASK) +#define AIPS_PACRE_WP6_MASK (0x20U) +#define AIPS_PACRE_WP6_SHIFT (5U) +/*! WP6 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRE_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_WP6_SHIFT)) & AIPS_PACRE_WP6_MASK) +#define AIPS_PACRE_SP6_MASK (0x40U) +#define AIPS_PACRE_SP6_SHIFT (6U) +/*! SP6 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRE_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_SP6_SHIFT)) & AIPS_PACRE_SP6_MASK) +#define AIPS_PACRE_TP5_MASK (0x100U) +#define AIPS_PACRE_TP5_SHIFT (8U) +/*! TP5 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRE_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_TP5_SHIFT)) & AIPS_PACRE_TP5_MASK) +#define AIPS_PACRE_WP5_MASK (0x200U) +#define AIPS_PACRE_WP5_SHIFT (9U) +/*! WP5 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRE_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_WP5_SHIFT)) & AIPS_PACRE_WP5_MASK) +#define AIPS_PACRE_SP5_MASK (0x400U) +#define AIPS_PACRE_SP5_SHIFT (10U) +/*! SP5 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRE_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_SP5_SHIFT)) & AIPS_PACRE_SP5_MASK) +#define AIPS_PACRE_TP4_MASK (0x1000U) +#define AIPS_PACRE_TP4_SHIFT (12U) +/*! TP4 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRE_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_TP4_SHIFT)) & AIPS_PACRE_TP4_MASK) +#define AIPS_PACRE_WP4_MASK (0x2000U) +#define AIPS_PACRE_WP4_SHIFT (13U) +/*! WP4 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRE_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_WP4_SHIFT)) & AIPS_PACRE_WP4_MASK) +#define AIPS_PACRE_SP4_MASK (0x4000U) +#define AIPS_PACRE_SP4_SHIFT (14U) +/*! SP4 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRE_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_SP4_SHIFT)) & AIPS_PACRE_SP4_MASK) +#define AIPS_PACRE_TP3_MASK (0x10000U) +#define AIPS_PACRE_TP3_SHIFT (16U) +/*! TP3 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRE_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_TP3_SHIFT)) & AIPS_PACRE_TP3_MASK) +#define AIPS_PACRE_WP3_MASK (0x20000U) +#define AIPS_PACRE_WP3_SHIFT (17U) +/*! WP3 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRE_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_WP3_SHIFT)) & AIPS_PACRE_WP3_MASK) +#define AIPS_PACRE_SP3_MASK (0x40000U) +#define AIPS_PACRE_SP3_SHIFT (18U) +/*! SP3 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRE_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_SP3_SHIFT)) & AIPS_PACRE_SP3_MASK) +#define AIPS_PACRE_TP2_MASK (0x100000U) +#define AIPS_PACRE_TP2_SHIFT (20U) +/*! TP2 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRE_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_TP2_SHIFT)) & AIPS_PACRE_TP2_MASK) +#define AIPS_PACRE_WP2_MASK (0x200000U) +#define AIPS_PACRE_WP2_SHIFT (21U) +/*! WP2 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRE_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_WP2_SHIFT)) & AIPS_PACRE_WP2_MASK) +#define AIPS_PACRE_SP2_MASK (0x400000U) +#define AIPS_PACRE_SP2_SHIFT (22U) +/*! SP2 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRE_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_SP2_SHIFT)) & AIPS_PACRE_SP2_MASK) +#define AIPS_PACRE_TP1_MASK (0x1000000U) +#define AIPS_PACRE_TP1_SHIFT (24U) +/*! TP1 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRE_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_TP1_SHIFT)) & AIPS_PACRE_TP1_MASK) +#define AIPS_PACRE_WP1_MASK (0x2000000U) +#define AIPS_PACRE_WP1_SHIFT (25U) +/*! WP1 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRE_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_WP1_SHIFT)) & AIPS_PACRE_WP1_MASK) +#define AIPS_PACRE_SP1_MASK (0x4000000U) +#define AIPS_PACRE_SP1_SHIFT (26U) +/*! SP1 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRE_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_SP1_SHIFT)) & AIPS_PACRE_SP1_MASK) +#define AIPS_PACRE_TP0_MASK (0x10000000U) +#define AIPS_PACRE_TP0_SHIFT (28U) +/*! TP0 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRE_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_TP0_SHIFT)) & AIPS_PACRE_TP0_MASK) +#define AIPS_PACRE_WP0_MASK (0x20000000U) +#define AIPS_PACRE_WP0_SHIFT (29U) +/*! WP0 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRE_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_WP0_SHIFT)) & AIPS_PACRE_WP0_MASK) +#define AIPS_PACRE_SP0_MASK (0x40000000U) +#define AIPS_PACRE_SP0_SHIFT (30U) +/*! SP0 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRE_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRE_SP0_SHIFT)) & AIPS_PACRE_SP0_MASK) +/*! @} */ + +/*! @name PACRF - Peripheral Access Control Register */ +/*! @{ */ +#define AIPS_PACRF_TP7_MASK (0x1U) +#define AIPS_PACRF_TP7_SHIFT (0U) +/*! TP7 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRF_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_TP7_SHIFT)) & AIPS_PACRF_TP7_MASK) +#define AIPS_PACRF_WP7_MASK (0x2U) +#define AIPS_PACRF_WP7_SHIFT (1U) +/*! WP7 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRF_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_WP7_SHIFT)) & AIPS_PACRF_WP7_MASK) +#define AIPS_PACRF_SP7_MASK (0x4U) +#define AIPS_PACRF_SP7_SHIFT (2U) +/*! SP7 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRF_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_SP7_SHIFT)) & AIPS_PACRF_SP7_MASK) +#define AIPS_PACRF_TP6_MASK (0x10U) +#define AIPS_PACRF_TP6_SHIFT (4U) +/*! TP6 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRF_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_TP6_SHIFT)) & AIPS_PACRF_TP6_MASK) +#define AIPS_PACRF_WP6_MASK (0x20U) +#define AIPS_PACRF_WP6_SHIFT (5U) +/*! WP6 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRF_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_WP6_SHIFT)) & AIPS_PACRF_WP6_MASK) +#define AIPS_PACRF_SP6_MASK (0x40U) +#define AIPS_PACRF_SP6_SHIFT (6U) +/*! SP6 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRF_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_SP6_SHIFT)) & AIPS_PACRF_SP6_MASK) +#define AIPS_PACRF_TP5_MASK (0x100U) +#define AIPS_PACRF_TP5_SHIFT (8U) +/*! TP5 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRF_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_TP5_SHIFT)) & AIPS_PACRF_TP5_MASK) +#define AIPS_PACRF_WP5_MASK (0x200U) +#define AIPS_PACRF_WP5_SHIFT (9U) +/*! WP5 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRF_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_WP5_SHIFT)) & AIPS_PACRF_WP5_MASK) +#define AIPS_PACRF_SP5_MASK (0x400U) +#define AIPS_PACRF_SP5_SHIFT (10U) +/*! SP5 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRF_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_SP5_SHIFT)) & AIPS_PACRF_SP5_MASK) +#define AIPS_PACRF_TP4_MASK (0x1000U) +#define AIPS_PACRF_TP4_SHIFT (12U) +/*! TP4 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRF_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_TP4_SHIFT)) & AIPS_PACRF_TP4_MASK) +#define AIPS_PACRF_WP4_MASK (0x2000U) +#define AIPS_PACRF_WP4_SHIFT (13U) +/*! WP4 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRF_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_WP4_SHIFT)) & AIPS_PACRF_WP4_MASK) +#define AIPS_PACRF_SP4_MASK (0x4000U) +#define AIPS_PACRF_SP4_SHIFT (14U) +/*! SP4 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRF_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_SP4_SHIFT)) & AIPS_PACRF_SP4_MASK) +#define AIPS_PACRF_TP3_MASK (0x10000U) +#define AIPS_PACRF_TP3_SHIFT (16U) +/*! TP3 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRF_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_TP3_SHIFT)) & AIPS_PACRF_TP3_MASK) +#define AIPS_PACRF_WP3_MASK (0x20000U) +#define AIPS_PACRF_WP3_SHIFT (17U) +/*! WP3 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRF_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_WP3_SHIFT)) & AIPS_PACRF_WP3_MASK) +#define AIPS_PACRF_SP3_MASK (0x40000U) +#define AIPS_PACRF_SP3_SHIFT (18U) +/*! SP3 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRF_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_SP3_SHIFT)) & AIPS_PACRF_SP3_MASK) +#define AIPS_PACRF_TP2_MASK (0x100000U) +#define AIPS_PACRF_TP2_SHIFT (20U) +/*! TP2 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRF_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_TP2_SHIFT)) & AIPS_PACRF_TP2_MASK) +#define AIPS_PACRF_WP2_MASK (0x200000U) +#define AIPS_PACRF_WP2_SHIFT (21U) +/*! WP2 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRF_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_WP2_SHIFT)) & AIPS_PACRF_WP2_MASK) +#define AIPS_PACRF_SP2_MASK (0x400000U) +#define AIPS_PACRF_SP2_SHIFT (22U) +/*! SP2 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRF_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_SP2_SHIFT)) & AIPS_PACRF_SP2_MASK) +#define AIPS_PACRF_TP1_MASK (0x1000000U) +#define AIPS_PACRF_TP1_SHIFT (24U) +/*! TP1 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRF_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_TP1_SHIFT)) & AIPS_PACRF_TP1_MASK) +#define AIPS_PACRF_WP1_MASK (0x2000000U) +#define AIPS_PACRF_WP1_SHIFT (25U) +/*! WP1 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRF_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_WP1_SHIFT)) & AIPS_PACRF_WP1_MASK) +#define AIPS_PACRF_SP1_MASK (0x4000000U) +#define AIPS_PACRF_SP1_SHIFT (26U) +/*! SP1 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRF_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_SP1_SHIFT)) & AIPS_PACRF_SP1_MASK) +#define AIPS_PACRF_TP0_MASK (0x10000000U) +#define AIPS_PACRF_TP0_SHIFT (28U) +/*! TP0 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRF_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_TP0_SHIFT)) & AIPS_PACRF_TP0_MASK) +#define AIPS_PACRF_WP0_MASK (0x20000000U) +#define AIPS_PACRF_WP0_SHIFT (29U) +/*! WP0 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRF_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_WP0_SHIFT)) & AIPS_PACRF_WP0_MASK) +#define AIPS_PACRF_SP0_MASK (0x40000000U) +#define AIPS_PACRF_SP0_SHIFT (30U) +/*! SP0 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRF_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRF_SP0_SHIFT)) & AIPS_PACRF_SP0_MASK) +/*! @} */ + +/*! @name PACRG - Peripheral Access Control Register */ +/*! @{ */ +#define AIPS_PACRG_TP7_MASK (0x1U) +#define AIPS_PACRG_TP7_SHIFT (0U) +/*! TP7 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRG_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_TP7_SHIFT)) & AIPS_PACRG_TP7_MASK) +#define AIPS_PACRG_WP7_MASK (0x2U) +#define AIPS_PACRG_WP7_SHIFT (1U) +/*! WP7 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRG_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_WP7_SHIFT)) & AIPS_PACRG_WP7_MASK) +#define AIPS_PACRG_SP7_MASK (0x4U) +#define AIPS_PACRG_SP7_SHIFT (2U) +/*! SP7 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRG_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_SP7_SHIFT)) & AIPS_PACRG_SP7_MASK) +#define AIPS_PACRG_TP6_MASK (0x10U) +#define AIPS_PACRG_TP6_SHIFT (4U) +/*! TP6 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRG_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_TP6_SHIFT)) & AIPS_PACRG_TP6_MASK) +#define AIPS_PACRG_WP6_MASK (0x20U) +#define AIPS_PACRG_WP6_SHIFT (5U) +/*! WP6 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRG_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_WP6_SHIFT)) & AIPS_PACRG_WP6_MASK) +#define AIPS_PACRG_SP6_MASK (0x40U) +#define AIPS_PACRG_SP6_SHIFT (6U) +/*! SP6 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRG_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_SP6_SHIFT)) & AIPS_PACRG_SP6_MASK) +#define AIPS_PACRG_TP5_MASK (0x100U) +#define AIPS_PACRG_TP5_SHIFT (8U) +/*! TP5 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRG_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_TP5_SHIFT)) & AIPS_PACRG_TP5_MASK) +#define AIPS_PACRG_WP5_MASK (0x200U) +#define AIPS_PACRG_WP5_SHIFT (9U) +/*! WP5 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRG_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_WP5_SHIFT)) & AIPS_PACRG_WP5_MASK) +#define AIPS_PACRG_SP5_MASK (0x400U) +#define AIPS_PACRG_SP5_SHIFT (10U) +/*! SP5 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRG_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_SP5_SHIFT)) & AIPS_PACRG_SP5_MASK) +#define AIPS_PACRG_TP4_MASK (0x1000U) +#define AIPS_PACRG_TP4_SHIFT (12U) +/*! TP4 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRG_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_TP4_SHIFT)) & AIPS_PACRG_TP4_MASK) +#define AIPS_PACRG_WP4_MASK (0x2000U) +#define AIPS_PACRG_WP4_SHIFT (13U) +/*! WP4 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRG_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_WP4_SHIFT)) & AIPS_PACRG_WP4_MASK) +#define AIPS_PACRG_SP4_MASK (0x4000U) +#define AIPS_PACRG_SP4_SHIFT (14U) +/*! SP4 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRG_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_SP4_SHIFT)) & AIPS_PACRG_SP4_MASK) +#define AIPS_PACRG_TP3_MASK (0x10000U) +#define AIPS_PACRG_TP3_SHIFT (16U) +/*! TP3 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRG_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_TP3_SHIFT)) & AIPS_PACRG_TP3_MASK) +#define AIPS_PACRG_WP3_MASK (0x20000U) +#define AIPS_PACRG_WP3_SHIFT (17U) +/*! WP3 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRG_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_WP3_SHIFT)) & AIPS_PACRG_WP3_MASK) +#define AIPS_PACRG_SP3_MASK (0x40000U) +#define AIPS_PACRG_SP3_SHIFT (18U) +/*! SP3 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRG_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_SP3_SHIFT)) & AIPS_PACRG_SP3_MASK) +#define AIPS_PACRG_TP2_MASK (0x100000U) +#define AIPS_PACRG_TP2_SHIFT (20U) +/*! TP2 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRG_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_TP2_SHIFT)) & AIPS_PACRG_TP2_MASK) +#define AIPS_PACRG_WP2_MASK (0x200000U) +#define AIPS_PACRG_WP2_SHIFT (21U) +/*! WP2 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRG_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_WP2_SHIFT)) & AIPS_PACRG_WP2_MASK) +#define AIPS_PACRG_SP2_MASK (0x400000U) +#define AIPS_PACRG_SP2_SHIFT (22U) +/*! SP2 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRG_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_SP2_SHIFT)) & AIPS_PACRG_SP2_MASK) +#define AIPS_PACRG_TP1_MASK (0x1000000U) +#define AIPS_PACRG_TP1_SHIFT (24U) +/*! TP1 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRG_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_TP1_SHIFT)) & AIPS_PACRG_TP1_MASK) +#define AIPS_PACRG_WP1_MASK (0x2000000U) +#define AIPS_PACRG_WP1_SHIFT (25U) +/*! WP1 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRG_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_WP1_SHIFT)) & AIPS_PACRG_WP1_MASK) +#define AIPS_PACRG_SP1_MASK (0x4000000U) +#define AIPS_PACRG_SP1_SHIFT (26U) +/*! SP1 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRG_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_SP1_SHIFT)) & AIPS_PACRG_SP1_MASK) +#define AIPS_PACRG_TP0_MASK (0x10000000U) +#define AIPS_PACRG_TP0_SHIFT (28U) +/*! TP0 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRG_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_TP0_SHIFT)) & AIPS_PACRG_TP0_MASK) +#define AIPS_PACRG_WP0_MASK (0x20000000U) +#define AIPS_PACRG_WP0_SHIFT (29U) +/*! WP0 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRG_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_WP0_SHIFT)) & AIPS_PACRG_WP0_MASK) +#define AIPS_PACRG_SP0_MASK (0x40000000U) +#define AIPS_PACRG_SP0_SHIFT (30U) +/*! SP0 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRG_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRG_SP0_SHIFT)) & AIPS_PACRG_SP0_MASK) +/*! @} */ + +/*! @name PACRH - Peripheral Access Control Register */ +/*! @{ */ +#define AIPS_PACRH_TP7_MASK (0x1U) +#define AIPS_PACRH_TP7_SHIFT (0U) +/*! TP7 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRH_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_TP7_SHIFT)) & AIPS_PACRH_TP7_MASK) +#define AIPS_PACRH_WP7_MASK (0x2U) +#define AIPS_PACRH_WP7_SHIFT (1U) +/*! WP7 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRH_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_WP7_SHIFT)) & AIPS_PACRH_WP7_MASK) +#define AIPS_PACRH_SP7_MASK (0x4U) +#define AIPS_PACRH_SP7_SHIFT (2U) +/*! SP7 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRH_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_SP7_SHIFT)) & AIPS_PACRH_SP7_MASK) +#define AIPS_PACRH_TP6_MASK (0x10U) +#define AIPS_PACRH_TP6_SHIFT (4U) +/*! TP6 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRH_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_TP6_SHIFT)) & AIPS_PACRH_TP6_MASK) +#define AIPS_PACRH_WP6_MASK (0x20U) +#define AIPS_PACRH_WP6_SHIFT (5U) +/*! WP6 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRH_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_WP6_SHIFT)) & AIPS_PACRH_WP6_MASK) +#define AIPS_PACRH_SP6_MASK (0x40U) +#define AIPS_PACRH_SP6_SHIFT (6U) +/*! SP6 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRH_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_SP6_SHIFT)) & AIPS_PACRH_SP6_MASK) +#define AIPS_PACRH_TP5_MASK (0x100U) +#define AIPS_PACRH_TP5_SHIFT (8U) +/*! TP5 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRH_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_TP5_SHIFT)) & AIPS_PACRH_TP5_MASK) +#define AIPS_PACRH_WP5_MASK (0x200U) +#define AIPS_PACRH_WP5_SHIFT (9U) +/*! WP5 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRH_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_WP5_SHIFT)) & AIPS_PACRH_WP5_MASK) +#define AIPS_PACRH_SP5_MASK (0x400U) +#define AIPS_PACRH_SP5_SHIFT (10U) +/*! SP5 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRH_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_SP5_SHIFT)) & AIPS_PACRH_SP5_MASK) +#define AIPS_PACRH_TP4_MASK (0x1000U) +#define AIPS_PACRH_TP4_SHIFT (12U) +/*! TP4 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRH_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_TP4_SHIFT)) & AIPS_PACRH_TP4_MASK) +#define AIPS_PACRH_WP4_MASK (0x2000U) +#define AIPS_PACRH_WP4_SHIFT (13U) +/*! WP4 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRH_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_WP4_SHIFT)) & AIPS_PACRH_WP4_MASK) +#define AIPS_PACRH_SP4_MASK (0x4000U) +#define AIPS_PACRH_SP4_SHIFT (14U) +/*! SP4 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRH_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_SP4_SHIFT)) & AIPS_PACRH_SP4_MASK) +#define AIPS_PACRH_TP3_MASK (0x10000U) +#define AIPS_PACRH_TP3_SHIFT (16U) +/*! TP3 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRH_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_TP3_SHIFT)) & AIPS_PACRH_TP3_MASK) +#define AIPS_PACRH_WP3_MASK (0x20000U) +#define AIPS_PACRH_WP3_SHIFT (17U) +/*! WP3 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRH_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_WP3_SHIFT)) & AIPS_PACRH_WP3_MASK) +#define AIPS_PACRH_SP3_MASK (0x40000U) +#define AIPS_PACRH_SP3_SHIFT (18U) +/*! SP3 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRH_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_SP3_SHIFT)) & AIPS_PACRH_SP3_MASK) +#define AIPS_PACRH_TP2_MASK (0x100000U) +#define AIPS_PACRH_TP2_SHIFT (20U) +/*! TP2 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRH_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_TP2_SHIFT)) & AIPS_PACRH_TP2_MASK) +#define AIPS_PACRH_WP2_MASK (0x200000U) +#define AIPS_PACRH_WP2_SHIFT (21U) +/*! WP2 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRH_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_WP2_SHIFT)) & AIPS_PACRH_WP2_MASK) +#define AIPS_PACRH_SP2_MASK (0x400000U) +#define AIPS_PACRH_SP2_SHIFT (22U) +/*! SP2 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRH_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_SP2_SHIFT)) & AIPS_PACRH_SP2_MASK) +#define AIPS_PACRH_TP1_MASK (0x1000000U) +#define AIPS_PACRH_TP1_SHIFT (24U) +/*! TP1 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRH_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_TP1_SHIFT)) & AIPS_PACRH_TP1_MASK) +#define AIPS_PACRH_WP1_MASK (0x2000000U) +#define AIPS_PACRH_WP1_SHIFT (25U) +/*! WP1 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRH_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_WP1_SHIFT)) & AIPS_PACRH_WP1_MASK) +#define AIPS_PACRH_SP1_MASK (0x4000000U) +#define AIPS_PACRH_SP1_SHIFT (26U) +/*! SP1 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRH_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_SP1_SHIFT)) & AIPS_PACRH_SP1_MASK) +#define AIPS_PACRH_TP0_MASK (0x10000000U) +#define AIPS_PACRH_TP0_SHIFT (28U) +/*! TP0 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRH_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_TP0_SHIFT)) & AIPS_PACRH_TP0_MASK) +#define AIPS_PACRH_WP0_MASK (0x20000000U) +#define AIPS_PACRH_WP0_SHIFT (29U) +/*! WP0 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRH_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_WP0_SHIFT)) & AIPS_PACRH_WP0_MASK) +#define AIPS_PACRH_SP0_MASK (0x40000000U) +#define AIPS_PACRH_SP0_SHIFT (30U) +/*! SP0 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRH_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRH_SP0_SHIFT)) & AIPS_PACRH_SP0_MASK) +/*! @} */ + +/*! @name PACRI - Peripheral Access Control Register */ +/*! @{ */ +#define AIPS_PACRI_TP7_MASK (0x1U) +#define AIPS_PACRI_TP7_SHIFT (0U) +/*! TP7 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRI_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_TP7_SHIFT)) & AIPS_PACRI_TP7_MASK) +#define AIPS_PACRI_WP7_MASK (0x2U) +#define AIPS_PACRI_WP7_SHIFT (1U) +/*! WP7 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRI_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_WP7_SHIFT)) & AIPS_PACRI_WP7_MASK) +#define AIPS_PACRI_SP7_MASK (0x4U) +#define AIPS_PACRI_SP7_SHIFT (2U) +/*! SP7 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRI_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_SP7_SHIFT)) & AIPS_PACRI_SP7_MASK) +#define AIPS_PACRI_TP6_MASK (0x10U) +#define AIPS_PACRI_TP6_SHIFT (4U) +/*! TP6 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRI_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_TP6_SHIFT)) & AIPS_PACRI_TP6_MASK) +#define AIPS_PACRI_WP6_MASK (0x20U) +#define AIPS_PACRI_WP6_SHIFT (5U) +/*! WP6 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRI_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_WP6_SHIFT)) & AIPS_PACRI_WP6_MASK) +#define AIPS_PACRI_SP6_MASK (0x40U) +#define AIPS_PACRI_SP6_SHIFT (6U) +/*! SP6 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRI_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_SP6_SHIFT)) & AIPS_PACRI_SP6_MASK) +#define AIPS_PACRI_TP5_MASK (0x100U) +#define AIPS_PACRI_TP5_SHIFT (8U) +/*! TP5 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRI_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_TP5_SHIFT)) & AIPS_PACRI_TP5_MASK) +#define AIPS_PACRI_WP5_MASK (0x200U) +#define AIPS_PACRI_WP5_SHIFT (9U) +/*! WP5 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRI_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_WP5_SHIFT)) & AIPS_PACRI_WP5_MASK) +#define AIPS_PACRI_SP5_MASK (0x400U) +#define AIPS_PACRI_SP5_SHIFT (10U) +/*! SP5 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRI_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_SP5_SHIFT)) & AIPS_PACRI_SP5_MASK) +#define AIPS_PACRI_TP4_MASK (0x1000U) +#define AIPS_PACRI_TP4_SHIFT (12U) +/*! TP4 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRI_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_TP4_SHIFT)) & AIPS_PACRI_TP4_MASK) +#define AIPS_PACRI_WP4_MASK (0x2000U) +#define AIPS_PACRI_WP4_SHIFT (13U) +/*! WP4 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRI_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_WP4_SHIFT)) & AIPS_PACRI_WP4_MASK) +#define AIPS_PACRI_SP4_MASK (0x4000U) +#define AIPS_PACRI_SP4_SHIFT (14U) +/*! SP4 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRI_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_SP4_SHIFT)) & AIPS_PACRI_SP4_MASK) +#define AIPS_PACRI_TP3_MASK (0x10000U) +#define AIPS_PACRI_TP3_SHIFT (16U) +/*! TP3 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRI_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_TP3_SHIFT)) & AIPS_PACRI_TP3_MASK) +#define AIPS_PACRI_WP3_MASK (0x20000U) +#define AIPS_PACRI_WP3_SHIFT (17U) +/*! WP3 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRI_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_WP3_SHIFT)) & AIPS_PACRI_WP3_MASK) +#define AIPS_PACRI_SP3_MASK (0x40000U) +#define AIPS_PACRI_SP3_SHIFT (18U) +/*! SP3 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRI_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_SP3_SHIFT)) & AIPS_PACRI_SP3_MASK) +#define AIPS_PACRI_TP2_MASK (0x100000U) +#define AIPS_PACRI_TP2_SHIFT (20U) +/*! TP2 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRI_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_TP2_SHIFT)) & AIPS_PACRI_TP2_MASK) +#define AIPS_PACRI_WP2_MASK (0x200000U) +#define AIPS_PACRI_WP2_SHIFT (21U) +/*! WP2 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRI_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_WP2_SHIFT)) & AIPS_PACRI_WP2_MASK) +#define AIPS_PACRI_SP2_MASK (0x400000U) +#define AIPS_PACRI_SP2_SHIFT (22U) +/*! SP2 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRI_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_SP2_SHIFT)) & AIPS_PACRI_SP2_MASK) +#define AIPS_PACRI_TP1_MASK (0x1000000U) +#define AIPS_PACRI_TP1_SHIFT (24U) +/*! TP1 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRI_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_TP1_SHIFT)) & AIPS_PACRI_TP1_MASK) +#define AIPS_PACRI_WP1_MASK (0x2000000U) +#define AIPS_PACRI_WP1_SHIFT (25U) +/*! WP1 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRI_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_WP1_SHIFT)) & AIPS_PACRI_WP1_MASK) +#define AIPS_PACRI_SP1_MASK (0x4000000U) +#define AIPS_PACRI_SP1_SHIFT (26U) +/*! SP1 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRI_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_SP1_SHIFT)) & AIPS_PACRI_SP1_MASK) +#define AIPS_PACRI_TP0_MASK (0x10000000U) +#define AIPS_PACRI_TP0_SHIFT (28U) +/*! TP0 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRI_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_TP0_SHIFT)) & AIPS_PACRI_TP0_MASK) +#define AIPS_PACRI_WP0_MASK (0x20000000U) +#define AIPS_PACRI_WP0_SHIFT (29U) +/*! WP0 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRI_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_WP0_SHIFT)) & AIPS_PACRI_WP0_MASK) +#define AIPS_PACRI_SP0_MASK (0x40000000U) +#define AIPS_PACRI_SP0_SHIFT (30U) +/*! SP0 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRI_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRI_SP0_SHIFT)) & AIPS_PACRI_SP0_MASK) +/*! @} */ + +/*! @name PACRJ - Peripheral Access Control Register */ +/*! @{ */ +#define AIPS_PACRJ_TP7_MASK (0x1U) +#define AIPS_PACRJ_TP7_SHIFT (0U) +/*! TP7 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRJ_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_TP7_SHIFT)) & AIPS_PACRJ_TP7_MASK) +#define AIPS_PACRJ_WP7_MASK (0x2U) +#define AIPS_PACRJ_WP7_SHIFT (1U) +/*! WP7 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRJ_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_WP7_SHIFT)) & AIPS_PACRJ_WP7_MASK) +#define AIPS_PACRJ_SP7_MASK (0x4U) +#define AIPS_PACRJ_SP7_SHIFT (2U) +/*! SP7 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRJ_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_SP7_SHIFT)) & AIPS_PACRJ_SP7_MASK) +#define AIPS_PACRJ_TP6_MASK (0x10U) +#define AIPS_PACRJ_TP6_SHIFT (4U) +/*! TP6 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRJ_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_TP6_SHIFT)) & AIPS_PACRJ_TP6_MASK) +#define AIPS_PACRJ_WP6_MASK (0x20U) +#define AIPS_PACRJ_WP6_SHIFT (5U) +/*! WP6 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRJ_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_WP6_SHIFT)) & AIPS_PACRJ_WP6_MASK) +#define AIPS_PACRJ_SP6_MASK (0x40U) +#define AIPS_PACRJ_SP6_SHIFT (6U) +/*! SP6 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRJ_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_SP6_SHIFT)) & AIPS_PACRJ_SP6_MASK) +#define AIPS_PACRJ_TP5_MASK (0x100U) +#define AIPS_PACRJ_TP5_SHIFT (8U) +/*! TP5 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRJ_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_TP5_SHIFT)) & AIPS_PACRJ_TP5_MASK) +#define AIPS_PACRJ_WP5_MASK (0x200U) +#define AIPS_PACRJ_WP5_SHIFT (9U) +/*! WP5 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRJ_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_WP5_SHIFT)) & AIPS_PACRJ_WP5_MASK) +#define AIPS_PACRJ_SP5_MASK (0x400U) +#define AIPS_PACRJ_SP5_SHIFT (10U) +/*! SP5 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRJ_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_SP5_SHIFT)) & AIPS_PACRJ_SP5_MASK) +#define AIPS_PACRJ_TP4_MASK (0x1000U) +#define AIPS_PACRJ_TP4_SHIFT (12U) +/*! TP4 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRJ_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_TP4_SHIFT)) & AIPS_PACRJ_TP4_MASK) +#define AIPS_PACRJ_WP4_MASK (0x2000U) +#define AIPS_PACRJ_WP4_SHIFT (13U) +/*! WP4 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRJ_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_WP4_SHIFT)) & AIPS_PACRJ_WP4_MASK) +#define AIPS_PACRJ_SP4_MASK (0x4000U) +#define AIPS_PACRJ_SP4_SHIFT (14U) +/*! SP4 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRJ_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_SP4_SHIFT)) & AIPS_PACRJ_SP4_MASK) +#define AIPS_PACRJ_TP3_MASK (0x10000U) +#define AIPS_PACRJ_TP3_SHIFT (16U) +/*! TP3 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRJ_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_TP3_SHIFT)) & AIPS_PACRJ_TP3_MASK) +#define AIPS_PACRJ_WP3_MASK (0x20000U) +#define AIPS_PACRJ_WP3_SHIFT (17U) +/*! WP3 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRJ_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_WP3_SHIFT)) & AIPS_PACRJ_WP3_MASK) +#define AIPS_PACRJ_SP3_MASK (0x40000U) +#define AIPS_PACRJ_SP3_SHIFT (18U) +/*! SP3 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRJ_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_SP3_SHIFT)) & AIPS_PACRJ_SP3_MASK) +#define AIPS_PACRJ_TP2_MASK (0x100000U) +#define AIPS_PACRJ_TP2_SHIFT (20U) +/*! TP2 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRJ_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_TP2_SHIFT)) & AIPS_PACRJ_TP2_MASK) +#define AIPS_PACRJ_WP2_MASK (0x200000U) +#define AIPS_PACRJ_WP2_SHIFT (21U) +/*! WP2 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRJ_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_WP2_SHIFT)) & AIPS_PACRJ_WP2_MASK) +#define AIPS_PACRJ_SP2_MASK (0x400000U) +#define AIPS_PACRJ_SP2_SHIFT (22U) +/*! SP2 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRJ_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_SP2_SHIFT)) & AIPS_PACRJ_SP2_MASK) +#define AIPS_PACRJ_TP1_MASK (0x1000000U) +#define AIPS_PACRJ_TP1_SHIFT (24U) +/*! TP1 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRJ_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_TP1_SHIFT)) & AIPS_PACRJ_TP1_MASK) +#define AIPS_PACRJ_WP1_MASK (0x2000000U) +#define AIPS_PACRJ_WP1_SHIFT (25U) +/*! WP1 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRJ_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_WP1_SHIFT)) & AIPS_PACRJ_WP1_MASK) +#define AIPS_PACRJ_SP1_MASK (0x4000000U) +#define AIPS_PACRJ_SP1_SHIFT (26U) +/*! SP1 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRJ_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_SP1_SHIFT)) & AIPS_PACRJ_SP1_MASK) +#define AIPS_PACRJ_TP0_MASK (0x10000000U) +#define AIPS_PACRJ_TP0_SHIFT (28U) +/*! TP0 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRJ_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_TP0_SHIFT)) & AIPS_PACRJ_TP0_MASK) +#define AIPS_PACRJ_WP0_MASK (0x20000000U) +#define AIPS_PACRJ_WP0_SHIFT (29U) +/*! WP0 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRJ_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_WP0_SHIFT)) & AIPS_PACRJ_WP0_MASK) +#define AIPS_PACRJ_SP0_MASK (0x40000000U) +#define AIPS_PACRJ_SP0_SHIFT (30U) +/*! SP0 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRJ_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRJ_SP0_SHIFT)) & AIPS_PACRJ_SP0_MASK) +/*! @} */ + +/*! @name PACRK - Peripheral Access Control Register */ +/*! @{ */ +#define AIPS_PACRK_TP7_MASK (0x1U) +#define AIPS_PACRK_TP7_SHIFT (0U) +/*! TP7 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRK_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_TP7_SHIFT)) & AIPS_PACRK_TP7_MASK) +#define AIPS_PACRK_WP7_MASK (0x2U) +#define AIPS_PACRK_WP7_SHIFT (1U) +/*! WP7 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRK_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_WP7_SHIFT)) & AIPS_PACRK_WP7_MASK) +#define AIPS_PACRK_SP7_MASK (0x4U) +#define AIPS_PACRK_SP7_SHIFT (2U) +/*! SP7 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRK_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_SP7_SHIFT)) & AIPS_PACRK_SP7_MASK) +#define AIPS_PACRK_TP6_MASK (0x10U) +#define AIPS_PACRK_TP6_SHIFT (4U) +/*! TP6 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRK_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_TP6_SHIFT)) & AIPS_PACRK_TP6_MASK) +#define AIPS_PACRK_WP6_MASK (0x20U) +#define AIPS_PACRK_WP6_SHIFT (5U) +/*! WP6 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRK_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_WP6_SHIFT)) & AIPS_PACRK_WP6_MASK) +#define AIPS_PACRK_SP6_MASK (0x40U) +#define AIPS_PACRK_SP6_SHIFT (6U) +/*! SP6 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRK_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_SP6_SHIFT)) & AIPS_PACRK_SP6_MASK) +#define AIPS_PACRK_TP5_MASK (0x100U) +#define AIPS_PACRK_TP5_SHIFT (8U) +/*! TP5 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRK_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_TP5_SHIFT)) & AIPS_PACRK_TP5_MASK) +#define AIPS_PACRK_WP5_MASK (0x200U) +#define AIPS_PACRK_WP5_SHIFT (9U) +/*! WP5 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRK_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_WP5_SHIFT)) & AIPS_PACRK_WP5_MASK) +#define AIPS_PACRK_SP5_MASK (0x400U) +#define AIPS_PACRK_SP5_SHIFT (10U) +/*! SP5 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRK_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_SP5_SHIFT)) & AIPS_PACRK_SP5_MASK) +#define AIPS_PACRK_TP4_MASK (0x1000U) +#define AIPS_PACRK_TP4_SHIFT (12U) +/*! TP4 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRK_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_TP4_SHIFT)) & AIPS_PACRK_TP4_MASK) +#define AIPS_PACRK_WP4_MASK (0x2000U) +#define AIPS_PACRK_WP4_SHIFT (13U) +/*! WP4 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRK_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_WP4_SHIFT)) & AIPS_PACRK_WP4_MASK) +#define AIPS_PACRK_SP4_MASK (0x4000U) +#define AIPS_PACRK_SP4_SHIFT (14U) +/*! SP4 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRK_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_SP4_SHIFT)) & AIPS_PACRK_SP4_MASK) +#define AIPS_PACRK_TP3_MASK (0x10000U) +#define AIPS_PACRK_TP3_SHIFT (16U) +/*! TP3 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRK_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_TP3_SHIFT)) & AIPS_PACRK_TP3_MASK) +#define AIPS_PACRK_WP3_MASK (0x20000U) +#define AIPS_PACRK_WP3_SHIFT (17U) +/*! WP3 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRK_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_WP3_SHIFT)) & AIPS_PACRK_WP3_MASK) +#define AIPS_PACRK_SP3_MASK (0x40000U) +#define AIPS_PACRK_SP3_SHIFT (18U) +/*! SP3 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRK_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_SP3_SHIFT)) & AIPS_PACRK_SP3_MASK) +#define AIPS_PACRK_TP2_MASK (0x100000U) +#define AIPS_PACRK_TP2_SHIFT (20U) +/*! TP2 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRK_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_TP2_SHIFT)) & AIPS_PACRK_TP2_MASK) +#define AIPS_PACRK_WP2_MASK (0x200000U) +#define AIPS_PACRK_WP2_SHIFT (21U) +/*! WP2 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRK_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_WP2_SHIFT)) & AIPS_PACRK_WP2_MASK) +#define AIPS_PACRK_SP2_MASK (0x400000U) +#define AIPS_PACRK_SP2_SHIFT (22U) +/*! SP2 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRK_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_SP2_SHIFT)) & AIPS_PACRK_SP2_MASK) +#define AIPS_PACRK_TP1_MASK (0x1000000U) +#define AIPS_PACRK_TP1_SHIFT (24U) +/*! TP1 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRK_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_TP1_SHIFT)) & AIPS_PACRK_TP1_MASK) +#define AIPS_PACRK_WP1_MASK (0x2000000U) +#define AIPS_PACRK_WP1_SHIFT (25U) +/*! WP1 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRK_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_WP1_SHIFT)) & AIPS_PACRK_WP1_MASK) +#define AIPS_PACRK_SP1_MASK (0x4000000U) +#define AIPS_PACRK_SP1_SHIFT (26U) +/*! SP1 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRK_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_SP1_SHIFT)) & AIPS_PACRK_SP1_MASK) +#define AIPS_PACRK_TP0_MASK (0x10000000U) +#define AIPS_PACRK_TP0_SHIFT (28U) +/*! TP0 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRK_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_TP0_SHIFT)) & AIPS_PACRK_TP0_MASK) +#define AIPS_PACRK_WP0_MASK (0x20000000U) +#define AIPS_PACRK_WP0_SHIFT (29U) +/*! WP0 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRK_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_WP0_SHIFT)) & AIPS_PACRK_WP0_MASK) +#define AIPS_PACRK_SP0_MASK (0x40000000U) +#define AIPS_PACRK_SP0_SHIFT (30U) +/*! SP0 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRK_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRK_SP0_SHIFT)) & AIPS_PACRK_SP0_MASK) +/*! @} */ + +/*! @name PACRL - Peripheral Access Control Register */ +/*! @{ */ +#define AIPS_PACRL_TP7_MASK (0x1U) +#define AIPS_PACRL_TP7_SHIFT (0U) +/*! TP7 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRL_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_TP7_SHIFT)) & AIPS_PACRL_TP7_MASK) +#define AIPS_PACRL_WP7_MASK (0x2U) +#define AIPS_PACRL_WP7_SHIFT (1U) +/*! WP7 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRL_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_WP7_SHIFT)) & AIPS_PACRL_WP7_MASK) +#define AIPS_PACRL_SP7_MASK (0x4U) +#define AIPS_PACRL_SP7_SHIFT (2U) +/*! SP7 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRL_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_SP7_SHIFT)) & AIPS_PACRL_SP7_MASK) +#define AIPS_PACRL_TP6_MASK (0x10U) +#define AIPS_PACRL_TP6_SHIFT (4U) +/*! TP6 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRL_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_TP6_SHIFT)) & AIPS_PACRL_TP6_MASK) +#define AIPS_PACRL_WP6_MASK (0x20U) +#define AIPS_PACRL_WP6_SHIFT (5U) +/*! WP6 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRL_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_WP6_SHIFT)) & AIPS_PACRL_WP6_MASK) +#define AIPS_PACRL_SP6_MASK (0x40U) +#define AIPS_PACRL_SP6_SHIFT (6U) +/*! SP6 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRL_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_SP6_SHIFT)) & AIPS_PACRL_SP6_MASK) +#define AIPS_PACRL_TP5_MASK (0x100U) +#define AIPS_PACRL_TP5_SHIFT (8U) +/*! TP5 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRL_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_TP5_SHIFT)) & AIPS_PACRL_TP5_MASK) +#define AIPS_PACRL_WP5_MASK (0x200U) +#define AIPS_PACRL_WP5_SHIFT (9U) +/*! WP5 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRL_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_WP5_SHIFT)) & AIPS_PACRL_WP5_MASK) +#define AIPS_PACRL_SP5_MASK (0x400U) +#define AIPS_PACRL_SP5_SHIFT (10U) +/*! SP5 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRL_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_SP5_SHIFT)) & AIPS_PACRL_SP5_MASK) +#define AIPS_PACRL_TP4_MASK (0x1000U) +#define AIPS_PACRL_TP4_SHIFT (12U) +/*! TP4 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRL_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_TP4_SHIFT)) & AIPS_PACRL_TP4_MASK) +#define AIPS_PACRL_WP4_MASK (0x2000U) +#define AIPS_PACRL_WP4_SHIFT (13U) +/*! WP4 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRL_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_WP4_SHIFT)) & AIPS_PACRL_WP4_MASK) +#define AIPS_PACRL_SP4_MASK (0x4000U) +#define AIPS_PACRL_SP4_SHIFT (14U) +/*! SP4 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRL_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_SP4_SHIFT)) & AIPS_PACRL_SP4_MASK) +#define AIPS_PACRL_TP3_MASK (0x10000U) +#define AIPS_PACRL_TP3_SHIFT (16U) +/*! TP3 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRL_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_TP3_SHIFT)) & AIPS_PACRL_TP3_MASK) +#define AIPS_PACRL_WP3_MASK (0x20000U) +#define AIPS_PACRL_WP3_SHIFT (17U) +/*! WP3 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRL_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_WP3_SHIFT)) & AIPS_PACRL_WP3_MASK) +#define AIPS_PACRL_SP3_MASK (0x40000U) +#define AIPS_PACRL_SP3_SHIFT (18U) +/*! SP3 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRL_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_SP3_SHIFT)) & AIPS_PACRL_SP3_MASK) +#define AIPS_PACRL_TP2_MASK (0x100000U) +#define AIPS_PACRL_TP2_SHIFT (20U) +/*! TP2 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRL_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_TP2_SHIFT)) & AIPS_PACRL_TP2_MASK) +#define AIPS_PACRL_WP2_MASK (0x200000U) +#define AIPS_PACRL_WP2_SHIFT (21U) +/*! WP2 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRL_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_WP2_SHIFT)) & AIPS_PACRL_WP2_MASK) +#define AIPS_PACRL_SP2_MASK (0x400000U) +#define AIPS_PACRL_SP2_SHIFT (22U) +/*! SP2 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRL_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_SP2_SHIFT)) & AIPS_PACRL_SP2_MASK) +#define AIPS_PACRL_TP1_MASK (0x1000000U) +#define AIPS_PACRL_TP1_SHIFT (24U) +/*! TP1 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRL_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_TP1_SHIFT)) & AIPS_PACRL_TP1_MASK) +#define AIPS_PACRL_WP1_MASK (0x2000000U) +#define AIPS_PACRL_WP1_SHIFT (25U) +/*! WP1 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRL_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_WP1_SHIFT)) & AIPS_PACRL_WP1_MASK) +#define AIPS_PACRL_SP1_MASK (0x4000000U) +#define AIPS_PACRL_SP1_SHIFT (26U) +/*! SP1 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRL_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_SP1_SHIFT)) & AIPS_PACRL_SP1_MASK) +#define AIPS_PACRL_TP0_MASK (0x10000000U) +#define AIPS_PACRL_TP0_SHIFT (28U) +/*! TP0 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRL_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_TP0_SHIFT)) & AIPS_PACRL_TP0_MASK) +#define AIPS_PACRL_WP0_MASK (0x20000000U) +#define AIPS_PACRL_WP0_SHIFT (29U) +/*! WP0 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRL_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_WP0_SHIFT)) & AIPS_PACRL_WP0_MASK) +#define AIPS_PACRL_SP0_MASK (0x40000000U) +#define AIPS_PACRL_SP0_SHIFT (30U) +/*! SP0 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRL_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRL_SP0_SHIFT)) & AIPS_PACRL_SP0_MASK) +/*! @} */ + +/*! @name PACRM - Peripheral Access Control Register */ +/*! @{ */ +#define AIPS_PACRM_TP7_MASK (0x1U) +#define AIPS_PACRM_TP7_SHIFT (0U) +/*! TP7 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRM_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_TP7_SHIFT)) & AIPS_PACRM_TP7_MASK) +#define AIPS_PACRM_WP7_MASK (0x2U) +#define AIPS_PACRM_WP7_SHIFT (1U) +/*! WP7 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRM_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_WP7_SHIFT)) & AIPS_PACRM_WP7_MASK) +#define AIPS_PACRM_SP7_MASK (0x4U) +#define AIPS_PACRM_SP7_SHIFT (2U) +/*! SP7 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRM_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_SP7_SHIFT)) & AIPS_PACRM_SP7_MASK) +#define AIPS_PACRM_TP6_MASK (0x10U) +#define AIPS_PACRM_TP6_SHIFT (4U) +/*! TP6 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRM_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_TP6_SHIFT)) & AIPS_PACRM_TP6_MASK) +#define AIPS_PACRM_WP6_MASK (0x20U) +#define AIPS_PACRM_WP6_SHIFT (5U) +/*! WP6 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRM_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_WP6_SHIFT)) & AIPS_PACRM_WP6_MASK) +#define AIPS_PACRM_SP6_MASK (0x40U) +#define AIPS_PACRM_SP6_SHIFT (6U) +/*! SP6 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRM_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_SP6_SHIFT)) & AIPS_PACRM_SP6_MASK) +#define AIPS_PACRM_TP5_MASK (0x100U) +#define AIPS_PACRM_TP5_SHIFT (8U) +/*! TP5 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRM_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_TP5_SHIFT)) & AIPS_PACRM_TP5_MASK) +#define AIPS_PACRM_WP5_MASK (0x200U) +#define AIPS_PACRM_WP5_SHIFT (9U) +/*! WP5 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRM_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_WP5_SHIFT)) & AIPS_PACRM_WP5_MASK) +#define AIPS_PACRM_SP5_MASK (0x400U) +#define AIPS_PACRM_SP5_SHIFT (10U) +/*! SP5 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRM_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_SP5_SHIFT)) & AIPS_PACRM_SP5_MASK) +#define AIPS_PACRM_TP4_MASK (0x1000U) +#define AIPS_PACRM_TP4_SHIFT (12U) +/*! TP4 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRM_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_TP4_SHIFT)) & AIPS_PACRM_TP4_MASK) +#define AIPS_PACRM_WP4_MASK (0x2000U) +#define AIPS_PACRM_WP4_SHIFT (13U) +/*! WP4 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRM_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_WP4_SHIFT)) & AIPS_PACRM_WP4_MASK) +#define AIPS_PACRM_SP4_MASK (0x4000U) +#define AIPS_PACRM_SP4_SHIFT (14U) +/*! SP4 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRM_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_SP4_SHIFT)) & AIPS_PACRM_SP4_MASK) +#define AIPS_PACRM_TP3_MASK (0x10000U) +#define AIPS_PACRM_TP3_SHIFT (16U) +/*! TP3 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRM_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_TP3_SHIFT)) & AIPS_PACRM_TP3_MASK) +#define AIPS_PACRM_WP3_MASK (0x20000U) +#define AIPS_PACRM_WP3_SHIFT (17U) +/*! WP3 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRM_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_WP3_SHIFT)) & AIPS_PACRM_WP3_MASK) +#define AIPS_PACRM_SP3_MASK (0x40000U) +#define AIPS_PACRM_SP3_SHIFT (18U) +/*! SP3 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRM_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_SP3_SHIFT)) & AIPS_PACRM_SP3_MASK) +#define AIPS_PACRM_TP2_MASK (0x100000U) +#define AIPS_PACRM_TP2_SHIFT (20U) +/*! TP2 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRM_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_TP2_SHIFT)) & AIPS_PACRM_TP2_MASK) +#define AIPS_PACRM_WP2_MASK (0x200000U) +#define AIPS_PACRM_WP2_SHIFT (21U) +/*! WP2 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRM_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_WP2_SHIFT)) & AIPS_PACRM_WP2_MASK) +#define AIPS_PACRM_SP2_MASK (0x400000U) +#define AIPS_PACRM_SP2_SHIFT (22U) +/*! SP2 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRM_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_SP2_SHIFT)) & AIPS_PACRM_SP2_MASK) +#define AIPS_PACRM_TP1_MASK (0x1000000U) +#define AIPS_PACRM_TP1_SHIFT (24U) +/*! TP1 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRM_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_TP1_SHIFT)) & AIPS_PACRM_TP1_MASK) +#define AIPS_PACRM_WP1_MASK (0x2000000U) +#define AIPS_PACRM_WP1_SHIFT (25U) +/*! WP1 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRM_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_WP1_SHIFT)) & AIPS_PACRM_WP1_MASK) +#define AIPS_PACRM_SP1_MASK (0x4000000U) +#define AIPS_PACRM_SP1_SHIFT (26U) +/*! SP1 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRM_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_SP1_SHIFT)) & AIPS_PACRM_SP1_MASK) +#define AIPS_PACRM_TP0_MASK (0x10000000U) +#define AIPS_PACRM_TP0_SHIFT (28U) +/*! TP0 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRM_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_TP0_SHIFT)) & AIPS_PACRM_TP0_MASK) +#define AIPS_PACRM_WP0_MASK (0x20000000U) +#define AIPS_PACRM_WP0_SHIFT (29U) +/*! WP0 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRM_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_WP0_SHIFT)) & AIPS_PACRM_WP0_MASK) +#define AIPS_PACRM_SP0_MASK (0x40000000U) +#define AIPS_PACRM_SP0_SHIFT (30U) +/*! SP0 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRM_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRM_SP0_SHIFT)) & AIPS_PACRM_SP0_MASK) +/*! @} */ + +/*! @name PACRN - Peripheral Access Control Register */ +/*! @{ */ +#define AIPS_PACRN_TP7_MASK (0x1U) +#define AIPS_PACRN_TP7_SHIFT (0U) +/*! TP7 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRN_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_TP7_SHIFT)) & AIPS_PACRN_TP7_MASK) +#define AIPS_PACRN_WP7_MASK (0x2U) +#define AIPS_PACRN_WP7_SHIFT (1U) +/*! WP7 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRN_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_WP7_SHIFT)) & AIPS_PACRN_WP7_MASK) +#define AIPS_PACRN_SP7_MASK (0x4U) +#define AIPS_PACRN_SP7_SHIFT (2U) +/*! SP7 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRN_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_SP7_SHIFT)) & AIPS_PACRN_SP7_MASK) +#define AIPS_PACRN_TP6_MASK (0x10U) +#define AIPS_PACRN_TP6_SHIFT (4U) +/*! TP6 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRN_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_TP6_SHIFT)) & AIPS_PACRN_TP6_MASK) +#define AIPS_PACRN_WP6_MASK (0x20U) +#define AIPS_PACRN_WP6_SHIFT (5U) +/*! WP6 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRN_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_WP6_SHIFT)) & AIPS_PACRN_WP6_MASK) +#define AIPS_PACRN_SP6_MASK (0x40U) +#define AIPS_PACRN_SP6_SHIFT (6U) +/*! SP6 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRN_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_SP6_SHIFT)) & AIPS_PACRN_SP6_MASK) +#define AIPS_PACRN_TP5_MASK (0x100U) +#define AIPS_PACRN_TP5_SHIFT (8U) +/*! TP5 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRN_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_TP5_SHIFT)) & AIPS_PACRN_TP5_MASK) +#define AIPS_PACRN_WP5_MASK (0x200U) +#define AIPS_PACRN_WP5_SHIFT (9U) +/*! WP5 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRN_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_WP5_SHIFT)) & AIPS_PACRN_WP5_MASK) +#define AIPS_PACRN_SP5_MASK (0x400U) +#define AIPS_PACRN_SP5_SHIFT (10U) +/*! SP5 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRN_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_SP5_SHIFT)) & AIPS_PACRN_SP5_MASK) +#define AIPS_PACRN_TP4_MASK (0x1000U) +#define AIPS_PACRN_TP4_SHIFT (12U) +/*! TP4 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRN_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_TP4_SHIFT)) & AIPS_PACRN_TP4_MASK) +#define AIPS_PACRN_WP4_MASK (0x2000U) +#define AIPS_PACRN_WP4_SHIFT (13U) +/*! WP4 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRN_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_WP4_SHIFT)) & AIPS_PACRN_WP4_MASK) +#define AIPS_PACRN_SP4_MASK (0x4000U) +#define AIPS_PACRN_SP4_SHIFT (14U) +/*! SP4 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRN_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_SP4_SHIFT)) & AIPS_PACRN_SP4_MASK) +#define AIPS_PACRN_TP3_MASK (0x10000U) +#define AIPS_PACRN_TP3_SHIFT (16U) +/*! TP3 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRN_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_TP3_SHIFT)) & AIPS_PACRN_TP3_MASK) +#define AIPS_PACRN_WP3_MASK (0x20000U) +#define AIPS_PACRN_WP3_SHIFT (17U) +/*! WP3 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRN_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_WP3_SHIFT)) & AIPS_PACRN_WP3_MASK) +#define AIPS_PACRN_SP3_MASK (0x40000U) +#define AIPS_PACRN_SP3_SHIFT (18U) +/*! SP3 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRN_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_SP3_SHIFT)) & AIPS_PACRN_SP3_MASK) +#define AIPS_PACRN_TP2_MASK (0x100000U) +#define AIPS_PACRN_TP2_SHIFT (20U) +/*! TP2 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRN_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_TP2_SHIFT)) & AIPS_PACRN_TP2_MASK) +#define AIPS_PACRN_WP2_MASK (0x200000U) +#define AIPS_PACRN_WP2_SHIFT (21U) +/*! WP2 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRN_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_WP2_SHIFT)) & AIPS_PACRN_WP2_MASK) +#define AIPS_PACRN_SP2_MASK (0x400000U) +#define AIPS_PACRN_SP2_SHIFT (22U) +/*! SP2 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRN_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_SP2_SHIFT)) & AIPS_PACRN_SP2_MASK) +#define AIPS_PACRN_TP1_MASK (0x1000000U) +#define AIPS_PACRN_TP1_SHIFT (24U) +/*! TP1 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRN_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_TP1_SHIFT)) & AIPS_PACRN_TP1_MASK) +#define AIPS_PACRN_WP1_MASK (0x2000000U) +#define AIPS_PACRN_WP1_SHIFT (25U) +/*! WP1 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRN_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_WP1_SHIFT)) & AIPS_PACRN_WP1_MASK) +#define AIPS_PACRN_SP1_MASK (0x4000000U) +#define AIPS_PACRN_SP1_SHIFT (26U) +/*! SP1 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRN_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_SP1_SHIFT)) & AIPS_PACRN_SP1_MASK) +#define AIPS_PACRN_TP0_MASK (0x10000000U) +#define AIPS_PACRN_TP0_SHIFT (28U) +/*! TP0 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRN_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_TP0_SHIFT)) & AIPS_PACRN_TP0_MASK) +#define AIPS_PACRN_WP0_MASK (0x20000000U) +#define AIPS_PACRN_WP0_SHIFT (29U) +/*! WP0 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRN_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_WP0_SHIFT)) & AIPS_PACRN_WP0_MASK) +#define AIPS_PACRN_SP0_MASK (0x40000000U) +#define AIPS_PACRN_SP0_SHIFT (30U) +/*! SP0 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRN_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRN_SP0_SHIFT)) & AIPS_PACRN_SP0_MASK) +/*! @} */ + +/*! @name PACRO - Peripheral Access Control Register */ +/*! @{ */ +#define AIPS_PACRO_TP7_MASK (0x1U) +#define AIPS_PACRO_TP7_SHIFT (0U) +/*! TP7 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRO_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_TP7_SHIFT)) & AIPS_PACRO_TP7_MASK) +#define AIPS_PACRO_WP7_MASK (0x2U) +#define AIPS_PACRO_WP7_SHIFT (1U) +/*! WP7 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRO_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_WP7_SHIFT)) & AIPS_PACRO_WP7_MASK) +#define AIPS_PACRO_SP7_MASK (0x4U) +#define AIPS_PACRO_SP7_SHIFT (2U) +/*! SP7 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRO_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_SP7_SHIFT)) & AIPS_PACRO_SP7_MASK) +#define AIPS_PACRO_TP6_MASK (0x10U) +#define AIPS_PACRO_TP6_SHIFT (4U) +/*! TP6 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRO_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_TP6_SHIFT)) & AIPS_PACRO_TP6_MASK) +#define AIPS_PACRO_WP6_MASK (0x20U) +#define AIPS_PACRO_WP6_SHIFT (5U) +/*! WP6 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRO_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_WP6_SHIFT)) & AIPS_PACRO_WP6_MASK) +#define AIPS_PACRO_SP6_MASK (0x40U) +#define AIPS_PACRO_SP6_SHIFT (6U) +/*! SP6 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRO_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_SP6_SHIFT)) & AIPS_PACRO_SP6_MASK) +#define AIPS_PACRO_TP5_MASK (0x100U) +#define AIPS_PACRO_TP5_SHIFT (8U) +/*! TP5 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRO_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_TP5_SHIFT)) & AIPS_PACRO_TP5_MASK) +#define AIPS_PACRO_WP5_MASK (0x200U) +#define AIPS_PACRO_WP5_SHIFT (9U) +/*! WP5 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRO_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_WP5_SHIFT)) & AIPS_PACRO_WP5_MASK) +#define AIPS_PACRO_SP5_MASK (0x400U) +#define AIPS_PACRO_SP5_SHIFT (10U) +/*! SP5 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRO_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_SP5_SHIFT)) & AIPS_PACRO_SP5_MASK) +#define AIPS_PACRO_TP4_MASK (0x1000U) +#define AIPS_PACRO_TP4_SHIFT (12U) +/*! TP4 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRO_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_TP4_SHIFT)) & AIPS_PACRO_TP4_MASK) +#define AIPS_PACRO_WP4_MASK (0x2000U) +#define AIPS_PACRO_WP4_SHIFT (13U) +/*! WP4 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRO_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_WP4_SHIFT)) & AIPS_PACRO_WP4_MASK) +#define AIPS_PACRO_SP4_MASK (0x4000U) +#define AIPS_PACRO_SP4_SHIFT (14U) +/*! SP4 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRO_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_SP4_SHIFT)) & AIPS_PACRO_SP4_MASK) +#define AIPS_PACRO_TP3_MASK (0x10000U) +#define AIPS_PACRO_TP3_SHIFT (16U) +/*! TP3 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRO_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_TP3_SHIFT)) & AIPS_PACRO_TP3_MASK) +#define AIPS_PACRO_WP3_MASK (0x20000U) +#define AIPS_PACRO_WP3_SHIFT (17U) +/*! WP3 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRO_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_WP3_SHIFT)) & AIPS_PACRO_WP3_MASK) +#define AIPS_PACRO_SP3_MASK (0x40000U) +#define AIPS_PACRO_SP3_SHIFT (18U) +/*! SP3 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRO_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_SP3_SHIFT)) & AIPS_PACRO_SP3_MASK) +#define AIPS_PACRO_TP2_MASK (0x100000U) +#define AIPS_PACRO_TP2_SHIFT (20U) +/*! TP2 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRO_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_TP2_SHIFT)) & AIPS_PACRO_TP2_MASK) +#define AIPS_PACRO_WP2_MASK (0x200000U) +#define AIPS_PACRO_WP2_SHIFT (21U) +/*! WP2 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRO_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_WP2_SHIFT)) & AIPS_PACRO_WP2_MASK) +#define AIPS_PACRO_SP2_MASK (0x400000U) +#define AIPS_PACRO_SP2_SHIFT (22U) +/*! SP2 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRO_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_SP2_SHIFT)) & AIPS_PACRO_SP2_MASK) +#define AIPS_PACRO_TP1_MASK (0x1000000U) +#define AIPS_PACRO_TP1_SHIFT (24U) +/*! TP1 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRO_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_TP1_SHIFT)) & AIPS_PACRO_TP1_MASK) +#define AIPS_PACRO_WP1_MASK (0x2000000U) +#define AIPS_PACRO_WP1_SHIFT (25U) +/*! WP1 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRO_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_WP1_SHIFT)) & AIPS_PACRO_WP1_MASK) +#define AIPS_PACRO_SP1_MASK (0x4000000U) +#define AIPS_PACRO_SP1_SHIFT (26U) +/*! SP1 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRO_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_SP1_SHIFT)) & AIPS_PACRO_SP1_MASK) +#define AIPS_PACRO_TP0_MASK (0x10000000U) +#define AIPS_PACRO_TP0_SHIFT (28U) +/*! TP0 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRO_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_TP0_SHIFT)) & AIPS_PACRO_TP0_MASK) +#define AIPS_PACRO_WP0_MASK (0x20000000U) +#define AIPS_PACRO_WP0_SHIFT (29U) +/*! WP0 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRO_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_WP0_SHIFT)) & AIPS_PACRO_WP0_MASK) +#define AIPS_PACRO_SP0_MASK (0x40000000U) +#define AIPS_PACRO_SP0_SHIFT (30U) +/*! SP0 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRO_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRO_SP0_SHIFT)) & AIPS_PACRO_SP0_MASK) +/*! @} */ + +/*! @name PACRP - Peripheral Access Control Register */ +/*! @{ */ +#define AIPS_PACRP_TP7_MASK (0x1U) +#define AIPS_PACRP_TP7_SHIFT (0U) +/*! TP7 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRP_TP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_TP7_SHIFT)) & AIPS_PACRP_TP7_MASK) +#define AIPS_PACRP_WP7_MASK (0x2U) +#define AIPS_PACRP_WP7_SHIFT (1U) +/*! WP7 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRP_WP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_WP7_SHIFT)) & AIPS_PACRP_WP7_MASK) +#define AIPS_PACRP_SP7_MASK (0x4U) +#define AIPS_PACRP_SP7_SHIFT (2U) +/*! SP7 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRP_SP7(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_SP7_SHIFT)) & AIPS_PACRP_SP7_MASK) +#define AIPS_PACRP_TP6_MASK (0x10U) +#define AIPS_PACRP_TP6_SHIFT (4U) +/*! TP6 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRP_TP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_TP6_SHIFT)) & AIPS_PACRP_TP6_MASK) +#define AIPS_PACRP_WP6_MASK (0x20U) +#define AIPS_PACRP_WP6_SHIFT (5U) +/*! WP6 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRP_WP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_WP6_SHIFT)) & AIPS_PACRP_WP6_MASK) +#define AIPS_PACRP_SP6_MASK (0x40U) +#define AIPS_PACRP_SP6_SHIFT (6U) +/*! SP6 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRP_SP6(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_SP6_SHIFT)) & AIPS_PACRP_SP6_MASK) +#define AIPS_PACRP_TP5_MASK (0x100U) +#define AIPS_PACRP_TP5_SHIFT (8U) +/*! TP5 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRP_TP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_TP5_SHIFT)) & AIPS_PACRP_TP5_MASK) +#define AIPS_PACRP_WP5_MASK (0x200U) +#define AIPS_PACRP_WP5_SHIFT (9U) +/*! WP5 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRP_WP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_WP5_SHIFT)) & AIPS_PACRP_WP5_MASK) +#define AIPS_PACRP_SP5_MASK (0x400U) +#define AIPS_PACRP_SP5_SHIFT (10U) +/*! SP5 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRP_SP5(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_SP5_SHIFT)) & AIPS_PACRP_SP5_MASK) +#define AIPS_PACRP_TP4_MASK (0x1000U) +#define AIPS_PACRP_TP4_SHIFT (12U) +/*! TP4 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRP_TP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_TP4_SHIFT)) & AIPS_PACRP_TP4_MASK) +#define AIPS_PACRP_WP4_MASK (0x2000U) +#define AIPS_PACRP_WP4_SHIFT (13U) +/*! WP4 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRP_WP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_WP4_SHIFT)) & AIPS_PACRP_WP4_MASK) +#define AIPS_PACRP_SP4_MASK (0x4000U) +#define AIPS_PACRP_SP4_SHIFT (14U) +/*! SP4 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRP_SP4(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_SP4_SHIFT)) & AIPS_PACRP_SP4_MASK) +#define AIPS_PACRP_TP3_MASK (0x10000U) +#define AIPS_PACRP_TP3_SHIFT (16U) +/*! TP3 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRP_TP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_TP3_SHIFT)) & AIPS_PACRP_TP3_MASK) +#define AIPS_PACRP_WP3_MASK (0x20000U) +#define AIPS_PACRP_WP3_SHIFT (17U) +/*! WP3 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRP_WP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_WP3_SHIFT)) & AIPS_PACRP_WP3_MASK) +#define AIPS_PACRP_SP3_MASK (0x40000U) +#define AIPS_PACRP_SP3_SHIFT (18U) +/*! SP3 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRP_SP3(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_SP3_SHIFT)) & AIPS_PACRP_SP3_MASK) +#define AIPS_PACRP_TP2_MASK (0x100000U) +#define AIPS_PACRP_TP2_SHIFT (20U) +/*! TP2 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRP_TP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_TP2_SHIFT)) & AIPS_PACRP_TP2_MASK) +#define AIPS_PACRP_WP2_MASK (0x200000U) +#define AIPS_PACRP_WP2_SHIFT (21U) +/*! WP2 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRP_WP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_WP2_SHIFT)) & AIPS_PACRP_WP2_MASK) +#define AIPS_PACRP_SP2_MASK (0x400000U) +#define AIPS_PACRP_SP2_SHIFT (22U) +/*! SP2 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRP_SP2(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_SP2_SHIFT)) & AIPS_PACRP_SP2_MASK) +#define AIPS_PACRP_TP1_MASK (0x1000000U) +#define AIPS_PACRP_TP1_SHIFT (24U) +/*! TP1 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRP_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_TP1_SHIFT)) & AIPS_PACRP_TP1_MASK) +#define AIPS_PACRP_WP1_MASK (0x2000000U) +#define AIPS_PACRP_WP1_SHIFT (25U) +/*! WP1 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRP_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_WP1_SHIFT)) & AIPS_PACRP_WP1_MASK) +#define AIPS_PACRP_SP1_MASK (0x4000000U) +#define AIPS_PACRP_SP1_SHIFT (26U) +/*! SP1 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRP_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_SP1_SHIFT)) & AIPS_PACRP_SP1_MASK) +#define AIPS_PACRP_TP0_MASK (0x10000000U) +#define AIPS_PACRP_TP0_SHIFT (28U) +/*! TP0 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRP_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_TP0_SHIFT)) & AIPS_PACRP_TP0_MASK) +#define AIPS_PACRP_WP0_MASK (0x20000000U) +#define AIPS_PACRP_WP0_SHIFT (29U) +/*! WP0 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRP_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_WP0_SHIFT)) & AIPS_PACRP_WP0_MASK) +#define AIPS_PACRP_SP0_MASK (0x40000000U) +#define AIPS_PACRP_SP0_SHIFT (30U) +/*! SP0 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRP_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRP_SP0_SHIFT)) & AIPS_PACRP_SP0_MASK) +/*! @} */ + +/*! @name PACRU - Peripheral Access Control Register */ +/*! @{ */ +#define AIPS_PACRU_TP1_MASK (0x1000000U) +#define AIPS_PACRU_TP1_SHIFT (24U) +/*! TP1 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRU_TP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRU_TP1_SHIFT)) & AIPS_PACRU_TP1_MASK) +#define AIPS_PACRU_WP1_MASK (0x2000000U) +#define AIPS_PACRU_WP1_SHIFT (25U) +/*! WP1 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRU_WP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRU_WP1_SHIFT)) & AIPS_PACRU_WP1_MASK) +#define AIPS_PACRU_SP1_MASK (0x4000000U) +#define AIPS_PACRU_SP1_SHIFT (26U) +/*! SP1 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRU_SP1(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRU_SP1_SHIFT)) & AIPS_PACRU_SP1_MASK) +#define AIPS_PACRU_TP0_MASK (0x10000000U) +#define AIPS_PACRU_TP0_SHIFT (28U) +/*! TP0 - Trusted Protect + * 0b0..Accesses from an untrusted master are allowed. + * 0b1..Accesses from an untrusted master are not allowed. + */ +#define AIPS_PACRU_TP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRU_TP0_SHIFT)) & AIPS_PACRU_TP0_MASK) +#define AIPS_PACRU_WP0_MASK (0x20000000U) +#define AIPS_PACRU_WP0_SHIFT (29U) +/*! WP0 - Write Protect + * 0b0..This peripheral allows write accesses. + * 0b1..This peripheral is write protected. + */ +#define AIPS_PACRU_WP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRU_WP0_SHIFT)) & AIPS_PACRU_WP0_MASK) +#define AIPS_PACRU_SP0_MASK (0x40000000U) +#define AIPS_PACRU_SP0_SHIFT (30U) +/*! SP0 - Supervisor Protect + * 0b0..This peripheral does not require supervisor privilege level for accesses. + * 0b1..This peripheral requires supervisor privilege level for accesses. + */ +#define AIPS_PACRU_SP0(x) (((uint32_t)(((uint32_t)(x)) << AIPS_PACRU_SP0_SHIFT)) & AIPS_PACRU_SP0_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group AIPS_Register_Masks */ + + +/* AIPS - Peripheral instance base addresses */ +/** Peripheral AIPS0 base address */ +#define AIPS0_BASE (0x40000000u) +/** Peripheral AIPS0 base pointer */ +#define AIPS0 ((AIPS_Type *)AIPS0_BASE) +/** Peripheral AIPS1 base address */ +#define AIPS1_BASE (0x40080000u) +/** Peripheral AIPS1 base pointer */ +#define AIPS1 ((AIPS_Type *)AIPS1_BASE) +/** Array initializer of AIPS peripheral base addresses */ +#define AIPS_BASE_ADDRS { AIPS0_BASE, AIPS1_BASE } +/** Array initializer of AIPS peripheral base pointers */ +#define AIPS_BASE_PTRS { AIPS0, AIPS1 } + +/*! + * @} + */ /* end of group AIPS_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- AXBS Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup AXBS_Peripheral_Access_Layer AXBS Peripheral Access Layer + * @{ + */ + +/** AXBS - Register Layout Typedef */ +typedef struct { + struct { /* offset: 0x0, array step: 0x100 */ + __IO uint32_t PRS; /**< Priority Registers Slave, array offset: 0x0, array step: 0x100 */ + uint8_t RESERVED_0[12]; + __IO uint32_t CRS; /**< Control Register, array offset: 0x10, array step: 0x100 */ + uint8_t RESERVED_1[236]; + } SLAVE[5]; + uint8_t RESERVED_0[768]; + __IO uint32_t MGPCR0; /**< Master General Purpose Control Register, offset: 0x800 */ + uint8_t RESERVED_1[252]; + __IO uint32_t MGPCR1; /**< Master General Purpose Control Register, offset: 0x900 */ + uint8_t RESERVED_2[252]; + __IO uint32_t MGPCR2; /**< Master General Purpose Control Register, offset: 0xA00 */ + uint8_t RESERVED_3[252]; + __IO uint32_t MGPCR3; /**< Master General Purpose Control Register, offset: 0xB00 */ + uint8_t RESERVED_4[252]; + __IO uint32_t MGPCR4; /**< Master General Purpose Control Register, offset: 0xC00 */ + uint8_t RESERVED_5[252]; + __IO uint32_t MGPCR5; /**< Master General Purpose Control Register, offset: 0xD00 */ +} AXBS_Type; + +/* ---------------------------------------------------------------------------- + -- AXBS Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup AXBS_Register_Masks AXBS Register Masks + * @{ + */ + +/*! @name PRS - Priority Registers Slave */ +/*! @{ */ +#define AXBS_PRS_M0_MASK (0x7U) +#define AXBS_PRS_M0_SHIFT (0U) +/*! M0 - Master 0 Priority. Sets the arbitration priority for this port on the associated slave port. + * 0b000..This master has level 1, or highest, priority when accessing the slave port. + * 0b001..This master has level 2 priority when accessing the slave port. + * 0b010..This master has level 3 priority when accessing the slave port. + * 0b011..This master has level 4 priority when accessing the slave port. + * 0b100..This master has level 5 priority when accessing the slave port. + * 0b101..This master has level 6 priority when accessing the slave port. + * 0b110..This master has level 7 priority when accessing the slave port. + * 0b111..This master has level 8, or lowest, priority when accessing the slave port. + */ +#define AXBS_PRS_M0(x) (((uint32_t)(((uint32_t)(x)) << AXBS_PRS_M0_SHIFT)) & AXBS_PRS_M0_MASK) +#define AXBS_PRS_M1_MASK (0x70U) +#define AXBS_PRS_M1_SHIFT (4U) +/*! M1 - Master 1 Priority. Sets the arbitration priority for this port on the associated slave port. + * 0b000..This master has level 1, or highest, priority when accessing the slave port. + * 0b001..This master has level 2 priority when accessing the slave port. + * 0b010..This master has level 3 priority when accessing the slave port. + * 0b011..This master has level 4 priority when accessing the slave port. + * 0b100..This master has level 5 priority when accessing the slave port. + * 0b101..This master has level 6 priority when accessing the slave port. + * 0b110..This master has level 7 priority when accessing the slave port. + * 0b111..This master has level 8, or lowest, priority when accessing the slave port. + */ +#define AXBS_PRS_M1(x) (((uint32_t)(((uint32_t)(x)) << AXBS_PRS_M1_SHIFT)) & AXBS_PRS_M1_MASK) +#define AXBS_PRS_M2_MASK (0x700U) +#define AXBS_PRS_M2_SHIFT (8U) +/*! M2 - Master 2 Priority. Sets the arbitration priority for this port on the associated slave port. + * 0b000..This master has level 1, or highest, priority when accessing the slave port. + * 0b001..This master has level 2 priority when accessing the slave port. + * 0b010..This master has level 3 priority when accessing the slave port. + * 0b011..This master has level 4 priority when accessing the slave port. + * 0b100..This master has level 5 priority when accessing the slave port. + * 0b101..This master has level 6 priority when accessing the slave port. + * 0b110..This master has level 7 priority when accessing the slave port. + * 0b111..This master has level 8, or lowest, priority when accessing the slave port. + */ +#define AXBS_PRS_M2(x) (((uint32_t)(((uint32_t)(x)) << AXBS_PRS_M2_SHIFT)) & AXBS_PRS_M2_MASK) +#define AXBS_PRS_M3_MASK (0x7000U) +#define AXBS_PRS_M3_SHIFT (12U) +/*! M3 - Master 3 Priority. Sets the arbitration priority for this port on the associated slave port. + * 0b000..This master has level 1, or highest, priority when accessing the slave port. + * 0b001..This master has level 2 priority when accessing the slave port. + * 0b010..This master has level 3 priority when accessing the slave port. + * 0b011..This master has level 4 priority when accessing the slave port. + * 0b100..This master has level 5 priority when accessing the slave port. + * 0b101..This master has level 6 priority when accessing the slave port. + * 0b110..This master has level 7 priority when accessing the slave port. + * 0b111..This master has level 8, or lowest, priority when accessing the slave port. + */ +#define AXBS_PRS_M3(x) (((uint32_t)(((uint32_t)(x)) << AXBS_PRS_M3_SHIFT)) & AXBS_PRS_M3_MASK) +#define AXBS_PRS_M4_MASK (0x70000U) +#define AXBS_PRS_M4_SHIFT (16U) +/*! M4 - Master 4 Priority. Sets the arbitration priority for this port on the associated slave port. + * 0b000..This master has level 1, or highest, priority when accessing the slave port. + * 0b001..This master has level 2 priority when accessing the slave port. + * 0b010..This master has level 3 priority when accessing the slave port. + * 0b011..This master has level 4 priority when accessing the slave port. + * 0b100..This master has level 5 priority when accessing the slave port. + * 0b101..This master has level 6 priority when accessing the slave port. + * 0b110..This master has level 7 priority when accessing the slave port. + * 0b111..This master has level 8, or lowest, priority when accessing the slave port. + */ +#define AXBS_PRS_M4(x) (((uint32_t)(((uint32_t)(x)) << AXBS_PRS_M4_SHIFT)) & AXBS_PRS_M4_MASK) +#define AXBS_PRS_M5_MASK (0x700000U) +#define AXBS_PRS_M5_SHIFT (20U) +/*! M5 - Master 5 Priority. Sets the arbitration priority for this port on the associated slave port. + * 0b000..This master has level 1, or highest, priority when accessing the slave port. + * 0b001..This master has level 2 priority when accessing the slave port. + * 0b010..This master has level 3 priority when accessing the slave port. + * 0b011..This master has level 4 priority when accessing the slave port. + * 0b100..This master has level 5 priority when accessing the slave port. + * 0b101..This master has level 6 priority when accessing the slave port. + * 0b110..This master has level 7 priority when accessing the slave port. + * 0b111..This master has level 8, or lowest, priority when accessing the slave port. + */ +#define AXBS_PRS_M5(x) (((uint32_t)(((uint32_t)(x)) << AXBS_PRS_M5_SHIFT)) & AXBS_PRS_M5_MASK) +/*! @} */ + +/* The count of AXBS_PRS */ +#define AXBS_PRS_COUNT (5U) + +/*! @name CRS - Control Register */ +/*! @{ */ +#define AXBS_CRS_PARK_MASK (0x7U) +#define AXBS_CRS_PARK_SHIFT (0U) +/*! PARK - Park + * 0b000..Park on master port M0 + * 0b001..Park on master port M1 + * 0b010..Park on master port M2 + * 0b011..Park on master port M3 + * 0b100..Park on master port M4 + * 0b101..Park on master port M5 + * 0b110..Park on master port M6 + * 0b111..Park on master port M7 + */ +#define AXBS_CRS_PARK(x) (((uint32_t)(((uint32_t)(x)) << AXBS_CRS_PARK_SHIFT)) & AXBS_CRS_PARK_MASK) +#define AXBS_CRS_PCTL_MASK (0x30U) +#define AXBS_CRS_PCTL_SHIFT (4U) +/*! PCTL - Parking Control + * 0b00..When no master makes a request, the arbiter parks the slave port on the master port defined by the PARK field + * 0b01..When no master makes a request, the arbiter parks the slave port on the last master to be in control of the slave port + * 0b10..When no master makes a request, the slave port is not parked on a master and the arbiter drives all outputs to a constant safe state + * 0b11..Reserved + */ +#define AXBS_CRS_PCTL(x) (((uint32_t)(((uint32_t)(x)) << AXBS_CRS_PCTL_SHIFT)) & AXBS_CRS_PCTL_MASK) +#define AXBS_CRS_ARB_MASK (0x300U) +#define AXBS_CRS_ARB_SHIFT (8U) +/*! ARB - Arbitration Mode + * 0b00..Fixed priority + * 0b01..Round-robin, or rotating, priority + * 0b10..Reserved + * 0b11..Reserved + */ +#define AXBS_CRS_ARB(x) (((uint32_t)(((uint32_t)(x)) << AXBS_CRS_ARB_SHIFT)) & AXBS_CRS_ARB_MASK) +#define AXBS_CRS_HLP_MASK (0x40000000U) +#define AXBS_CRS_HLP_SHIFT (30U) +/*! HLP - Halt Low Priority + * 0b0..The low power mode request has the highest priority for arbitration on this slave port + * 0b1..The low power mode request has the lowest initial priority for arbitration on this slave port + */ +#define AXBS_CRS_HLP(x) (((uint32_t)(((uint32_t)(x)) << AXBS_CRS_HLP_SHIFT)) & AXBS_CRS_HLP_MASK) +#define AXBS_CRS_RO_MASK (0x80000000U) +#define AXBS_CRS_RO_SHIFT (31U) +/*! RO - Read Only + * 0b0..The slave port's registers are writeable + * 0b1..The slave port's registers are read-only and cannot be written. Attempted writes have no effect on the registers and result in a bus error response. + */ +#define AXBS_CRS_RO(x) (((uint32_t)(((uint32_t)(x)) << AXBS_CRS_RO_SHIFT)) & AXBS_CRS_RO_MASK) +/*! @} */ + +/* The count of AXBS_CRS */ +#define AXBS_CRS_COUNT (5U) + +/*! @name MGPCR0 - Master General Purpose Control Register */ +/*! @{ */ +#define AXBS_MGPCR0_AULB_MASK (0x7U) +#define AXBS_MGPCR0_AULB_SHIFT (0U) +/*! AULB - Arbitrates On Undefined Length Bursts + * 0b000..No arbitration is allowed during an undefined length burst + * 0b001..Arbitration is allowed at any time during an undefined length burst + * 0b010..Arbitration is allowed after four beats of an undefined length burst + * 0b011..Arbitration is allowed after eight beats of an undefined length burst + * 0b100..Arbitration is allowed after 16 beats of an undefined length burst + * 0b101..Reserved + * 0b110..Reserved + * 0b111..Reserved + */ +#define AXBS_MGPCR0_AULB(x) (((uint32_t)(((uint32_t)(x)) << AXBS_MGPCR0_AULB_SHIFT)) & AXBS_MGPCR0_AULB_MASK) +/*! @} */ + +/*! @name MGPCR1 - Master General Purpose Control Register */ +/*! @{ */ +#define AXBS_MGPCR1_AULB_MASK (0x7U) +#define AXBS_MGPCR1_AULB_SHIFT (0U) +/*! AULB - Arbitrates On Undefined Length Bursts + * 0b000..No arbitration is allowed during an undefined length burst + * 0b001..Arbitration is allowed at any time during an undefined length burst + * 0b010..Arbitration is allowed after four beats of an undefined length burst + * 0b011..Arbitration is allowed after eight beats of an undefined length burst + * 0b100..Arbitration is allowed after 16 beats of an undefined length burst + * 0b101..Reserved + * 0b110..Reserved + * 0b111..Reserved + */ +#define AXBS_MGPCR1_AULB(x) (((uint32_t)(((uint32_t)(x)) << AXBS_MGPCR1_AULB_SHIFT)) & AXBS_MGPCR1_AULB_MASK) +/*! @} */ + +/*! @name MGPCR2 - Master General Purpose Control Register */ +/*! @{ */ +#define AXBS_MGPCR2_AULB_MASK (0x7U) +#define AXBS_MGPCR2_AULB_SHIFT (0U) +/*! AULB - Arbitrates On Undefined Length Bursts + * 0b000..No arbitration is allowed during an undefined length burst + * 0b001..Arbitration is allowed at any time during an undefined length burst + * 0b010..Arbitration is allowed after four beats of an undefined length burst + * 0b011..Arbitration is allowed after eight beats of an undefined length burst + * 0b100..Arbitration is allowed after 16 beats of an undefined length burst + * 0b101..Reserved + * 0b110..Reserved + * 0b111..Reserved + */ +#define AXBS_MGPCR2_AULB(x) (((uint32_t)(((uint32_t)(x)) << AXBS_MGPCR2_AULB_SHIFT)) & AXBS_MGPCR2_AULB_MASK) +/*! @} */ + +/*! @name MGPCR3 - Master General Purpose Control Register */ +/*! @{ */ +#define AXBS_MGPCR3_AULB_MASK (0x7U) +#define AXBS_MGPCR3_AULB_SHIFT (0U) +/*! AULB - Arbitrates On Undefined Length Bursts + * 0b000..No arbitration is allowed during an undefined length burst + * 0b001..Arbitration is allowed at any time during an undefined length burst + * 0b010..Arbitration is allowed after four beats of an undefined length burst + * 0b011..Arbitration is allowed after eight beats of an undefined length burst + * 0b100..Arbitration is allowed after 16 beats of an undefined length burst + * 0b101..Reserved + * 0b110..Reserved + * 0b111..Reserved + */ +#define AXBS_MGPCR3_AULB(x) (((uint32_t)(((uint32_t)(x)) << AXBS_MGPCR3_AULB_SHIFT)) & AXBS_MGPCR3_AULB_MASK) +/*! @} */ + +/*! @name MGPCR4 - Master General Purpose Control Register */ +/*! @{ */ +#define AXBS_MGPCR4_AULB_MASK (0x7U) +#define AXBS_MGPCR4_AULB_SHIFT (0U) +/*! AULB - Arbitrates On Undefined Length Bursts + * 0b000..No arbitration is allowed during an undefined length burst + * 0b001..Arbitration is allowed at any time during an undefined length burst + * 0b010..Arbitration is allowed after four beats of an undefined length burst + * 0b011..Arbitration is allowed after eight beats of an undefined length burst + * 0b100..Arbitration is allowed after 16 beats of an undefined length burst + * 0b101..Reserved + * 0b110..Reserved + * 0b111..Reserved + */ +#define AXBS_MGPCR4_AULB(x) (((uint32_t)(((uint32_t)(x)) << AXBS_MGPCR4_AULB_SHIFT)) & AXBS_MGPCR4_AULB_MASK) +/*! @} */ + +/*! @name MGPCR5 - Master General Purpose Control Register */ +/*! @{ */ +#define AXBS_MGPCR5_AULB_MASK (0x7U) +#define AXBS_MGPCR5_AULB_SHIFT (0U) +/*! AULB - Arbitrates On Undefined Length Bursts + * 0b000..No arbitration is allowed during an undefined length burst + * 0b001..Arbitration is allowed at any time during an undefined length burst + * 0b010..Arbitration is allowed after four beats of an undefined length burst + * 0b011..Arbitration is allowed after eight beats of an undefined length burst + * 0b100..Arbitration is allowed after 16 beats of an undefined length burst + * 0b101..Reserved + * 0b110..Reserved + * 0b111..Reserved + */ +#define AXBS_MGPCR5_AULB(x) (((uint32_t)(((uint32_t)(x)) << AXBS_MGPCR5_AULB_SHIFT)) & AXBS_MGPCR5_AULB_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group AXBS_Register_Masks */ + + +/* AXBS - Peripheral instance base addresses */ +/** Peripheral AXBS base address */ +#define AXBS_BASE (0x40004000u) +/** Peripheral AXBS base pointer */ +#define AXBS ((AXBS_Type *)AXBS_BASE) +/** Array initializer of AXBS peripheral base addresses */ +#define AXBS_BASE_ADDRS { AXBS_BASE } +/** Array initializer of AXBS peripheral base pointers */ +#define AXBS_BASE_PTRS { AXBS } + +/*! + * @} + */ /* end of group AXBS_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- CAN Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CAN_Peripheral_Access_Layer CAN Peripheral Access Layer + * @{ + */ + +/** CAN - Register Layout Typedef */ +typedef struct { + __IO uint32_t MCR; /**< Module Configuration Register, offset: 0x0 */ + __IO uint32_t CTRL1; /**< Control 1 register, offset: 0x4 */ + __IO uint32_t TIMER; /**< Free Running Timer, offset: 0x8 */ + uint8_t RESERVED_0[4]; + __IO uint32_t RXMGMASK; /**< Rx Mailboxes Global Mask Register, offset: 0x10 */ + __IO uint32_t RX14MASK; /**< Rx 14 Mask register, offset: 0x14 */ + __IO uint32_t RX15MASK; /**< Rx 15 Mask register, offset: 0x18 */ + __IO uint32_t ECR; /**< Error Counter, offset: 0x1C */ + __IO uint32_t ESR1; /**< Error and Status 1 register, offset: 0x20 */ + uint8_t RESERVED_1[4]; + __IO uint32_t IMASK1; /**< Interrupt Masks 1 register, offset: 0x28 */ + uint8_t RESERVED_2[4]; + __IO uint32_t IFLAG1; /**< Interrupt Flags 1 register, offset: 0x30 */ + __IO uint32_t CTRL2; /**< Control 2 register, offset: 0x34 */ + __I uint32_t ESR2; /**< Error and Status 2 register, offset: 0x38 */ + uint8_t RESERVED_3[8]; + __I uint32_t CRCR; /**< CRC Register, offset: 0x44 */ + __IO uint32_t RXFGMASK; /**< Rx FIFO Global Mask register, offset: 0x48 */ + __I uint32_t RXFIR; /**< Rx FIFO Information Register, offset: 0x4C */ + uint8_t RESERVED_4[48]; + struct { /* offset: 0x80, array step: 0x10 */ + __IO uint32_t CS; /**< Message Buffer 0 CS Register..Message Buffer 15 CS Register, array offset: 0x80, array step: 0x10 */ + __IO uint32_t ID; /**< Message Buffer 0 ID Register..Message Buffer 15 ID Register, array offset: 0x84, array step: 0x10 */ + __IO uint32_t WORD0; /**< Message Buffer 0 WORD0 Register..Message Buffer 15 WORD0 Register, array offset: 0x88, array step: 0x10 */ + __IO uint32_t WORD1; /**< Message Buffer 0 WORD1 Register..Message Buffer 15 WORD1 Register, array offset: 0x8C, array step: 0x10 */ + } MB[16]; + uint8_t RESERVED_5[1792]; + __IO uint32_t RXIMR[16]; /**< Rx Individual Mask Registers, array offset: 0x880, array step: 0x4 */ +} CAN_Type; + +/* ---------------------------------------------------------------------------- + -- CAN Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CAN_Register_Masks CAN Register Masks + * @{ + */ + +/*! @name MCR - Module Configuration Register */ +/*! @{ */ +#define CAN_MCR_MAXMB_MASK (0x7FU) +#define CAN_MCR_MAXMB_SHIFT (0U) +#define CAN_MCR_MAXMB(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_MAXMB_SHIFT)) & CAN_MCR_MAXMB_MASK) +#define CAN_MCR_IDAM_MASK (0x300U) +#define CAN_MCR_IDAM_SHIFT (8U) +/*! IDAM - ID Acceptance Mode + * 0b00..Format A: One full ID (standard and extended) per ID Filter Table element. + * 0b01..Format B: Two full standard IDs or two partial 14-bit (standard and extended) IDs per ID Filter Table element. + * 0b10..Format C: Four partial 8-bit Standard IDs per ID Filter Table element. + * 0b11..Format D: All frames rejected. + */ +#define CAN_MCR_IDAM(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_IDAM_SHIFT)) & CAN_MCR_IDAM_MASK) +#define CAN_MCR_AEN_MASK (0x1000U) +#define CAN_MCR_AEN_SHIFT (12U) +/*! AEN - Abort Enable + * 0b0..Abort disabled. + * 0b1..Abort enabled. + */ +#define CAN_MCR_AEN(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_AEN_SHIFT)) & CAN_MCR_AEN_MASK) +#define CAN_MCR_LPRIOEN_MASK (0x2000U) +#define CAN_MCR_LPRIOEN_SHIFT (13U) +/*! LPRIOEN - Local Priority Enable + * 0b0..Local Priority disabled. + * 0b1..Local Priority enabled. + */ +#define CAN_MCR_LPRIOEN(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_LPRIOEN_SHIFT)) & CAN_MCR_LPRIOEN_MASK) +#define CAN_MCR_IRMQ_MASK (0x10000U) +#define CAN_MCR_IRMQ_SHIFT (16U) +/*! IRMQ - Individual Rx Masking And Queue Enable + * 0b0..Individual Rx masking and queue feature are disabled. For backward compatibility with legacy applications, the reading of C/S word locks the MB even if it is EMPTY. + * 0b1..Individual Rx masking and queue feature are enabled. + */ +#define CAN_MCR_IRMQ(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_IRMQ_SHIFT)) & CAN_MCR_IRMQ_MASK) +#define CAN_MCR_SRXDIS_MASK (0x20000U) +#define CAN_MCR_SRXDIS_SHIFT (17U) +/*! SRXDIS - Self Reception Disable + * 0b0..Self reception enabled. + * 0b1..Self reception disabled. + */ +#define CAN_MCR_SRXDIS(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_SRXDIS_SHIFT)) & CAN_MCR_SRXDIS_MASK) +#define CAN_MCR_WAKSRC_MASK (0x80000U) +#define CAN_MCR_WAKSRC_SHIFT (19U) +/*! WAKSRC - Wake Up Source + * 0b0..FlexCAN uses the unfiltered Rx input to detect recessive to dominant edges on the CAN bus. + * 0b1..FlexCAN uses the filtered Rx input to detect recessive to dominant edges on the CAN bus. + */ +#define CAN_MCR_WAKSRC(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_WAKSRC_SHIFT)) & CAN_MCR_WAKSRC_MASK) +#define CAN_MCR_LPMACK_MASK (0x100000U) +#define CAN_MCR_LPMACK_SHIFT (20U) +/*! LPMACK - Low-Power Mode Acknowledge + * 0b0..FlexCAN is not in a low-power mode. + * 0b1..FlexCAN is in a low-power mode. + */ +#define CAN_MCR_LPMACK(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_LPMACK_SHIFT)) & CAN_MCR_LPMACK_MASK) +#define CAN_MCR_WRNEN_MASK (0x200000U) +#define CAN_MCR_WRNEN_SHIFT (21U) +/*! WRNEN - Warning Interrupt Enable + * 0b0..TWRNINT and RWRNINT bits are zero, independent of the values in the error counters. + * 0b1..TWRNINT and RWRNINT bits are set when the respective error counter transitions from less than 96 to greater than or equal to 96. + */ +#define CAN_MCR_WRNEN(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_WRNEN_SHIFT)) & CAN_MCR_WRNEN_MASK) +#define CAN_MCR_SLFWAK_MASK (0x400000U) +#define CAN_MCR_SLFWAK_SHIFT (22U) +/*! SLFWAK - Self Wake Up + * 0b0..FlexCAN Self Wake Up feature is disabled. + * 0b1..FlexCAN Self Wake Up feature is enabled. + */ +#define CAN_MCR_SLFWAK(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_SLFWAK_SHIFT)) & CAN_MCR_SLFWAK_MASK) +#define CAN_MCR_SUPV_MASK (0x800000U) +#define CAN_MCR_SUPV_SHIFT (23U) +/*! SUPV - Supervisor Mode + * 0b0..FlexCAN is in User mode. Affected registers allow both Supervisor and Unrestricted accesses . + * 0b1..FlexCAN is in Supervisor mode. Affected registers allow only Supervisor access. Unrestricted access behaves as though the access was done to an unimplemented register location . + */ +#define CAN_MCR_SUPV(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_SUPV_SHIFT)) & CAN_MCR_SUPV_MASK) +#define CAN_MCR_FRZACK_MASK (0x1000000U) +#define CAN_MCR_FRZACK_SHIFT (24U) +/*! FRZACK - Freeze Mode Acknowledge + * 0b0..FlexCAN not in Freeze mode, prescaler running. + * 0b1..FlexCAN in Freeze mode, prescaler stopped. + */ +#define CAN_MCR_FRZACK(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_FRZACK_SHIFT)) & CAN_MCR_FRZACK_MASK) +#define CAN_MCR_SOFTRST_MASK (0x2000000U) +#define CAN_MCR_SOFTRST_SHIFT (25U) +/*! SOFTRST - Soft Reset + * 0b0..No reset request. + * 0b1..Resets the registers affected by soft reset. + */ +#define CAN_MCR_SOFTRST(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_SOFTRST_SHIFT)) & CAN_MCR_SOFTRST_MASK) +#define CAN_MCR_WAKMSK_MASK (0x4000000U) +#define CAN_MCR_WAKMSK_SHIFT (26U) +/*! WAKMSK - Wake Up Interrupt Mask + * 0b0..Wake Up Interrupt is disabled. + * 0b1..Wake Up Interrupt is enabled. + */ +#define CAN_MCR_WAKMSK(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_WAKMSK_SHIFT)) & CAN_MCR_WAKMSK_MASK) +#define CAN_MCR_NOTRDY_MASK (0x8000000U) +#define CAN_MCR_NOTRDY_SHIFT (27U) +/*! NOTRDY - FlexCAN Not Ready + * 0b0..FlexCAN module is either in Normal mode, Listen-Only mode or Loop-Back mode. + * 0b1..FlexCAN module is either in Disable mode , Stop mode or Freeze mode. + */ +#define CAN_MCR_NOTRDY(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_NOTRDY_SHIFT)) & CAN_MCR_NOTRDY_MASK) +#define CAN_MCR_HALT_MASK (0x10000000U) +#define CAN_MCR_HALT_SHIFT (28U) +/*! HALT - Halt FlexCAN + * 0b0..No Freeze mode request. + * 0b1..Enters Freeze mode if the FRZ bit is asserted. + */ +#define CAN_MCR_HALT(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_HALT_SHIFT)) & CAN_MCR_HALT_MASK) +#define CAN_MCR_RFEN_MASK (0x20000000U) +#define CAN_MCR_RFEN_SHIFT (29U) +/*! RFEN - Rx FIFO Enable + * 0b0..Rx FIFO not enabled. + * 0b1..Rx FIFO enabled. + */ +#define CAN_MCR_RFEN(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_RFEN_SHIFT)) & CAN_MCR_RFEN_MASK) +#define CAN_MCR_FRZ_MASK (0x40000000U) +#define CAN_MCR_FRZ_SHIFT (30U) +/*! FRZ - Freeze Enable + * 0b0..Not enabled to enter Freeze mode. + * 0b1..Enabled to enter Freeze mode. + */ +#define CAN_MCR_FRZ(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_FRZ_SHIFT)) & CAN_MCR_FRZ_MASK) +#define CAN_MCR_MDIS_MASK (0x80000000U) +#define CAN_MCR_MDIS_SHIFT (31U) +/*! MDIS - Module Disable + * 0b0..Enable the FlexCAN module. + * 0b1..Disable the FlexCAN module. + */ +#define CAN_MCR_MDIS(x) (((uint32_t)(((uint32_t)(x)) << CAN_MCR_MDIS_SHIFT)) & CAN_MCR_MDIS_MASK) +/*! @} */ + +/*! @name CTRL1 - Control 1 register */ +/*! @{ */ +#define CAN_CTRL1_PROPSEG_MASK (0x7U) +#define CAN_CTRL1_PROPSEG_SHIFT (0U) +#define CAN_CTRL1_PROPSEG(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL1_PROPSEG_SHIFT)) & CAN_CTRL1_PROPSEG_MASK) +#define CAN_CTRL1_LOM_MASK (0x8U) +#define CAN_CTRL1_LOM_SHIFT (3U) +/*! LOM - Listen-Only Mode + * 0b0..Listen-Only mode is deactivated. + * 0b1..FlexCAN module operates in Listen-Only mode. + */ +#define CAN_CTRL1_LOM(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL1_LOM_SHIFT)) & CAN_CTRL1_LOM_MASK) +#define CAN_CTRL1_LBUF_MASK (0x10U) +#define CAN_CTRL1_LBUF_SHIFT (4U) +/*! LBUF - Lowest Buffer Transmitted First + * 0b0..Buffer with highest priority is transmitted first. + * 0b1..Lowest number buffer is transmitted first. + */ +#define CAN_CTRL1_LBUF(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL1_LBUF_SHIFT)) & CAN_CTRL1_LBUF_MASK) +#define CAN_CTRL1_TSYN_MASK (0x20U) +#define CAN_CTRL1_TSYN_SHIFT (5U) +/*! TSYN - Timer Sync + * 0b0..Timer Sync feature disabled + * 0b1..Timer Sync feature enabled + */ +#define CAN_CTRL1_TSYN(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL1_TSYN_SHIFT)) & CAN_CTRL1_TSYN_MASK) +#define CAN_CTRL1_BOFFREC_MASK (0x40U) +#define CAN_CTRL1_BOFFREC_SHIFT (6U) +/*! BOFFREC - Bus Off Recovery + * 0b0..Automatic recovering from Bus Off state enabled, according to CAN Spec 2.0 part B. + * 0b1..Automatic recovering from Bus Off state disabled. + */ +#define CAN_CTRL1_BOFFREC(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL1_BOFFREC_SHIFT)) & CAN_CTRL1_BOFFREC_MASK) +#define CAN_CTRL1_SMP_MASK (0x80U) +#define CAN_CTRL1_SMP_SHIFT (7U) +/*! SMP - CAN Bit Sampling + * 0b0..Just one sample is used to determine the bit value. + * 0b1..Three samples are used to determine the value of the received bit: the regular one (sample point) and 2 preceding samples; a majority rule is used. + */ +#define CAN_CTRL1_SMP(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL1_SMP_SHIFT)) & CAN_CTRL1_SMP_MASK) +#define CAN_CTRL1_RWRNMSK_MASK (0x400U) +#define CAN_CTRL1_RWRNMSK_SHIFT (10U) +/*! RWRNMSK - Rx Warning Interrupt Mask + * 0b0..Rx Warning Interrupt disabled. + * 0b1..Rx Warning Interrupt enabled. + */ +#define CAN_CTRL1_RWRNMSK(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL1_RWRNMSK_SHIFT)) & CAN_CTRL1_RWRNMSK_MASK) +#define CAN_CTRL1_TWRNMSK_MASK (0x800U) +#define CAN_CTRL1_TWRNMSK_SHIFT (11U) +/*! TWRNMSK - Tx Warning Interrupt Mask + * 0b0..Tx Warning Interrupt disabled. + * 0b1..Tx Warning Interrupt enabled. + */ +#define CAN_CTRL1_TWRNMSK(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL1_TWRNMSK_SHIFT)) & CAN_CTRL1_TWRNMSK_MASK) +#define CAN_CTRL1_LPB_MASK (0x1000U) +#define CAN_CTRL1_LPB_SHIFT (12U) +/*! LPB - Loop Back Mode + * 0b0..Loop Back disabled. + * 0b1..Loop Back enabled. + */ +#define CAN_CTRL1_LPB(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL1_LPB_SHIFT)) & CAN_CTRL1_LPB_MASK) +#define CAN_CTRL1_CLKSRC_MASK (0x2000U) +#define CAN_CTRL1_CLKSRC_SHIFT (13U) +/*! CLKSRC - CAN Engine Clock Source + * 0b0..The CAN engine clock source is the oscillator clock. Under this condition, the oscillator clock frequency must be lower than the bus clock. + * 0b1..The CAN engine clock source is the peripheral clock. + */ +#define CAN_CTRL1_CLKSRC(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL1_CLKSRC_SHIFT)) & CAN_CTRL1_CLKSRC_MASK) +#define CAN_CTRL1_ERRMSK_MASK (0x4000U) +#define CAN_CTRL1_ERRMSK_SHIFT (14U) +/*! ERRMSK - Error Mask + * 0b0..Error interrupt disabled. + * 0b1..Error interrupt enabled. + */ +#define CAN_CTRL1_ERRMSK(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL1_ERRMSK_SHIFT)) & CAN_CTRL1_ERRMSK_MASK) +#define CAN_CTRL1_BOFFMSK_MASK (0x8000U) +#define CAN_CTRL1_BOFFMSK_SHIFT (15U) +/*! BOFFMSK - Bus Off Mask + * 0b0..Bus Off interrupt disabled. + * 0b1..Bus Off interrupt enabled. + */ +#define CAN_CTRL1_BOFFMSK(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL1_BOFFMSK_SHIFT)) & CAN_CTRL1_BOFFMSK_MASK) +#define CAN_CTRL1_PSEG2_MASK (0x70000U) +#define CAN_CTRL1_PSEG2_SHIFT (16U) +#define CAN_CTRL1_PSEG2(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL1_PSEG2_SHIFT)) & CAN_CTRL1_PSEG2_MASK) +#define CAN_CTRL1_PSEG1_MASK (0x380000U) +#define CAN_CTRL1_PSEG1_SHIFT (19U) +#define CAN_CTRL1_PSEG1(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL1_PSEG1_SHIFT)) & CAN_CTRL1_PSEG1_MASK) +#define CAN_CTRL1_RJW_MASK (0xC00000U) +#define CAN_CTRL1_RJW_SHIFT (22U) +#define CAN_CTRL1_RJW(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL1_RJW_SHIFT)) & CAN_CTRL1_RJW_MASK) +#define CAN_CTRL1_PRESDIV_MASK (0xFF000000U) +#define CAN_CTRL1_PRESDIV_SHIFT (24U) +#define CAN_CTRL1_PRESDIV(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL1_PRESDIV_SHIFT)) & CAN_CTRL1_PRESDIV_MASK) +/*! @} */ + +/*! @name TIMER - Free Running Timer */ +/*! @{ */ +#define CAN_TIMER_TIMER_MASK (0xFFFFU) +#define CAN_TIMER_TIMER_SHIFT (0U) +#define CAN_TIMER_TIMER(x) (((uint32_t)(((uint32_t)(x)) << CAN_TIMER_TIMER_SHIFT)) & CAN_TIMER_TIMER_MASK) +/*! @} */ + +/*! @name RXMGMASK - Rx Mailboxes Global Mask Register */ +/*! @{ */ +#define CAN_RXMGMASK_MG_MASK (0xFFFFFFFFU) +#define CAN_RXMGMASK_MG_SHIFT (0U) +/*! MG - Rx Mailboxes Global Mask Bits + * 0b00000000000000000000000000000000..The corresponding bit in the filter is "don't care." + * 0b00000000000000000000000000000001..The corresponding bit in the filter is checked. + */ +#define CAN_RXMGMASK_MG(x) (((uint32_t)(((uint32_t)(x)) << CAN_RXMGMASK_MG_SHIFT)) & CAN_RXMGMASK_MG_MASK) +/*! @} */ + +/*! @name RX14MASK - Rx 14 Mask register */ +/*! @{ */ +#define CAN_RX14MASK_RX14M_MASK (0xFFFFFFFFU) +#define CAN_RX14MASK_RX14M_SHIFT (0U) +/*! RX14M - Rx Buffer 14 Mask Bits + * 0b00000000000000000000000000000000..The corresponding bit in the filter is "don't care." + * 0b00000000000000000000000000000001..The corresponding bit in the filter is checked. + */ +#define CAN_RX14MASK_RX14M(x) (((uint32_t)(((uint32_t)(x)) << CAN_RX14MASK_RX14M_SHIFT)) & CAN_RX14MASK_RX14M_MASK) +/*! @} */ + +/*! @name RX15MASK - Rx 15 Mask register */ +/*! @{ */ +#define CAN_RX15MASK_RX15M_MASK (0xFFFFFFFFU) +#define CAN_RX15MASK_RX15M_SHIFT (0U) +/*! RX15M - Rx Buffer 15 Mask Bits + * 0b00000000000000000000000000000000..The corresponding bit in the filter is "don't care." + * 0b00000000000000000000000000000001..The corresponding bit in the filter is checked. + */ +#define CAN_RX15MASK_RX15M(x) (((uint32_t)(((uint32_t)(x)) << CAN_RX15MASK_RX15M_SHIFT)) & CAN_RX15MASK_RX15M_MASK) +/*! @} */ + +/*! @name ECR - Error Counter */ +/*! @{ */ +#define CAN_ECR_TXERRCNT_MASK (0xFFU) +#define CAN_ECR_TXERRCNT_SHIFT (0U) +#define CAN_ECR_TXERRCNT(x) (((uint32_t)(((uint32_t)(x)) << CAN_ECR_TXERRCNT_SHIFT)) & CAN_ECR_TXERRCNT_MASK) +#define CAN_ECR_RXERRCNT_MASK (0xFF00U) +#define CAN_ECR_RXERRCNT_SHIFT (8U) +#define CAN_ECR_RXERRCNT(x) (((uint32_t)(((uint32_t)(x)) << CAN_ECR_RXERRCNT_SHIFT)) & CAN_ECR_RXERRCNT_MASK) +/*! @} */ + +/*! @name ESR1 - Error and Status 1 register */ +/*! @{ */ +#define CAN_ESR1_WAKINT_MASK (0x1U) +#define CAN_ESR1_WAKINT_SHIFT (0U) +/*! WAKINT - Wake-Up Interrupt + * 0b0..No such occurrence. + * 0b1..Indicates a recessive to dominant transition was received on the CAN bus. + */ +#define CAN_ESR1_WAKINT(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_WAKINT_SHIFT)) & CAN_ESR1_WAKINT_MASK) +#define CAN_ESR1_ERRINT_MASK (0x2U) +#define CAN_ESR1_ERRINT_SHIFT (1U) +/*! ERRINT - Error Interrupt + * 0b0..No such occurrence. + * 0b1..Indicates setting of any Error Bit in the Error and Status Register. + */ +#define CAN_ESR1_ERRINT(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_ERRINT_SHIFT)) & CAN_ESR1_ERRINT_MASK) +#define CAN_ESR1_BOFFINT_MASK (0x4U) +#define CAN_ESR1_BOFFINT_SHIFT (2U) +/*! BOFFINT - Bus Off Interrupt + * 0b0..No such occurrence. + * 0b1..FlexCAN module entered Bus Off state. + */ +#define CAN_ESR1_BOFFINT(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_BOFFINT_SHIFT)) & CAN_ESR1_BOFFINT_MASK) +#define CAN_ESR1_RX_MASK (0x8U) +#define CAN_ESR1_RX_SHIFT (3U) +/*! RX - FlexCAN In Reception + * 0b0..FlexCAN is not receiving a message. + * 0b1..FlexCAN is receiving a message. + */ +#define CAN_ESR1_RX(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_RX_SHIFT)) & CAN_ESR1_RX_MASK) +#define CAN_ESR1_FLTCONF_MASK (0x30U) +#define CAN_ESR1_FLTCONF_SHIFT (4U) +/*! FLTCONF - Fault Confinement State + * 0b00..Error Active + * 0b01..Error Passive + * 0b1x..Bus Off + */ +#define CAN_ESR1_FLTCONF(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_FLTCONF_SHIFT)) & CAN_ESR1_FLTCONF_MASK) +#define CAN_ESR1_TX_MASK (0x40U) +#define CAN_ESR1_TX_SHIFT (6U) +/*! TX - FlexCAN In Transmission + * 0b0..FlexCAN is not transmitting a message. + * 0b1..FlexCAN is transmitting a message. + */ +#define CAN_ESR1_TX(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_TX_SHIFT)) & CAN_ESR1_TX_MASK) +#define CAN_ESR1_IDLE_MASK (0x80U) +#define CAN_ESR1_IDLE_SHIFT (7U) +/*! IDLE + * 0b0..No such occurrence. + * 0b1..CAN bus is now IDLE. + */ +#define CAN_ESR1_IDLE(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_IDLE_SHIFT)) & CAN_ESR1_IDLE_MASK) +#define CAN_ESR1_RXWRN_MASK (0x100U) +#define CAN_ESR1_RXWRN_SHIFT (8U) +/*! RXWRN - Rx Error Warning + * 0b0..No such occurrence. + * 0b1..RXERRCNT is greater than or equal to 96. + */ +#define CAN_ESR1_RXWRN(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_RXWRN_SHIFT)) & CAN_ESR1_RXWRN_MASK) +#define CAN_ESR1_TXWRN_MASK (0x200U) +#define CAN_ESR1_TXWRN_SHIFT (9U) +/*! TXWRN - TX Error Warning + * 0b0..No such occurrence. + * 0b1..TXERRCNT is greater than or equal to 96. + */ +#define CAN_ESR1_TXWRN(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_TXWRN_SHIFT)) & CAN_ESR1_TXWRN_MASK) +#define CAN_ESR1_STFERR_MASK (0x400U) +#define CAN_ESR1_STFERR_SHIFT (10U) +/*! STFERR - Stuffing Error + * 0b0..No such occurrence. + * 0b1..A Stuffing Error occurred since last read of this register. + */ +#define CAN_ESR1_STFERR(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_STFERR_SHIFT)) & CAN_ESR1_STFERR_MASK) +#define CAN_ESR1_FRMERR_MASK (0x800U) +#define CAN_ESR1_FRMERR_SHIFT (11U) +/*! FRMERR - Form Error + * 0b0..No such occurrence. + * 0b1..A Form Error occurred since last read of this register. + */ +#define CAN_ESR1_FRMERR(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_FRMERR_SHIFT)) & CAN_ESR1_FRMERR_MASK) +#define CAN_ESR1_CRCERR_MASK (0x1000U) +#define CAN_ESR1_CRCERR_SHIFT (12U) +/*! CRCERR - Cyclic Redundancy Check Error + * 0b0..No such occurrence. + * 0b1..A CRC error occurred since last read of this register. + */ +#define CAN_ESR1_CRCERR(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_CRCERR_SHIFT)) & CAN_ESR1_CRCERR_MASK) +#define CAN_ESR1_ACKERR_MASK (0x2000U) +#define CAN_ESR1_ACKERR_SHIFT (13U) +/*! ACKERR - Acknowledge Error + * 0b0..No such occurrence. + * 0b1..An ACK error occurred since last read of this register. + */ +#define CAN_ESR1_ACKERR(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_ACKERR_SHIFT)) & CAN_ESR1_ACKERR_MASK) +#define CAN_ESR1_BIT0ERR_MASK (0x4000U) +#define CAN_ESR1_BIT0ERR_SHIFT (14U) +/*! BIT0ERR - Bit0 Error + * 0b0..No such occurrence. + * 0b1..At least one bit sent as dominant is received as recessive. + */ +#define CAN_ESR1_BIT0ERR(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_BIT0ERR_SHIFT)) & CAN_ESR1_BIT0ERR_MASK) +#define CAN_ESR1_BIT1ERR_MASK (0x8000U) +#define CAN_ESR1_BIT1ERR_SHIFT (15U) +/*! BIT1ERR - Bit1 Error + * 0b0..No such occurrence. + * 0b1..At least one bit sent as recessive is received as dominant. + */ +#define CAN_ESR1_BIT1ERR(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_BIT1ERR_SHIFT)) & CAN_ESR1_BIT1ERR_MASK) +#define CAN_ESR1_RWRNINT_MASK (0x10000U) +#define CAN_ESR1_RWRNINT_SHIFT (16U) +/*! RWRNINT - Rx Warning Interrupt Flag + * 0b0..No such occurrence. + * 0b1..The Rx error counter transitioned from less than 96 to greater than or equal to 96. + */ +#define CAN_ESR1_RWRNINT(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_RWRNINT_SHIFT)) & CAN_ESR1_RWRNINT_MASK) +#define CAN_ESR1_TWRNINT_MASK (0x20000U) +#define CAN_ESR1_TWRNINT_SHIFT (17U) +/*! TWRNINT - Tx Warning Interrupt Flag + * 0b0..No such occurrence. + * 0b1..The Tx error counter transitioned from less than 96 to greater than or equal to 96. + */ +#define CAN_ESR1_TWRNINT(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_TWRNINT_SHIFT)) & CAN_ESR1_TWRNINT_MASK) +#define CAN_ESR1_SYNCH_MASK (0x40000U) +#define CAN_ESR1_SYNCH_SHIFT (18U) +/*! SYNCH - CAN Synchronization Status + * 0b0..FlexCAN is not synchronized to the CAN bus. + * 0b1..FlexCAN is synchronized to the CAN bus. + */ +#define CAN_ESR1_SYNCH(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR1_SYNCH_SHIFT)) & CAN_ESR1_SYNCH_MASK) +/*! @} */ + +/*! @name IMASK1 - Interrupt Masks 1 register */ +/*! @{ */ +#define CAN_IMASK1_BUFLM_MASK (0xFFFFFFFFU) +#define CAN_IMASK1_BUFLM_SHIFT (0U) +/*! BUFLM - Buffer MB i Mask + * 0b00000000000000000000000000000000..The corresponding buffer Interrupt is disabled. + * 0b00000000000000000000000000000001..The corresponding buffer Interrupt is enabled. + */ +#define CAN_IMASK1_BUFLM(x) (((uint32_t)(((uint32_t)(x)) << CAN_IMASK1_BUFLM_SHIFT)) & CAN_IMASK1_BUFLM_MASK) +/*! @} */ + +/*! @name IFLAG1 - Interrupt Flags 1 register */ +/*! @{ */ +#define CAN_IFLAG1_BUF0I_MASK (0x1U) +#define CAN_IFLAG1_BUF0I_SHIFT (0U) +/*! BUF0I - Buffer MB0 Interrupt Or "reserved" + * 0b0..The corresponding buffer has no occurrence of successfully completed transmission or reception when MCR[RFEN]=0. + * 0b1..The corresponding buffer has successfully completed transmission or reception when MCR[RFEN]=0. + */ +#define CAN_IFLAG1_BUF0I(x) (((uint32_t)(((uint32_t)(x)) << CAN_IFLAG1_BUF0I_SHIFT)) & CAN_IFLAG1_BUF0I_MASK) +#define CAN_IFLAG1_BUF4TO1I_MASK (0x1EU) +#define CAN_IFLAG1_BUF4TO1I_SHIFT (1U) +/*! BUF4TO1I - Buffer MB i Interrupt Or "reserved" + * 0b0000..The corresponding buffer has no occurrence of successfully completed transmission or reception when MCR[RFEN]=0. + * 0b0001..The corresponding buffer has successfully completed transmission or reception when MCR[RFEN]=0. + */ +#define CAN_IFLAG1_BUF4TO1I(x) (((uint32_t)(((uint32_t)(x)) << CAN_IFLAG1_BUF4TO1I_SHIFT)) & CAN_IFLAG1_BUF4TO1I_MASK) +#define CAN_IFLAG1_BUF5I_MASK (0x20U) +#define CAN_IFLAG1_BUF5I_SHIFT (5U) +/*! BUF5I - Buffer MB5 Interrupt Or "Frames available in Rx FIFO" + * 0b0..No occurrence of MB5 completing transmission/reception when MCR[RFEN]=0, or of frame(s) available in the FIFO, when MCR[RFEN]=1 + * 0b1..MB5 completed transmission/reception when MCR[RFEN]=0, or frame(s) available in the Rx FIFO when MCR[RFEN]=1 + */ +#define CAN_IFLAG1_BUF5I(x) (((uint32_t)(((uint32_t)(x)) << CAN_IFLAG1_BUF5I_SHIFT)) & CAN_IFLAG1_BUF5I_MASK) +#define CAN_IFLAG1_BUF6I_MASK (0x40U) +#define CAN_IFLAG1_BUF6I_SHIFT (6U) +/*! BUF6I - Buffer MB6 Interrupt Or "Rx FIFO Warning" + * 0b0..No occurrence of MB6 completing transmission/reception when MCR[RFEN]=0, or of Rx FIFO almost full when MCR[RFEN]=1 + * 0b1..MB6 completed transmission/reception when MCR[RFEN]=0, or Rx FIFO almost full when MCR[RFEN]=1 + */ +#define CAN_IFLAG1_BUF6I(x) (((uint32_t)(((uint32_t)(x)) << CAN_IFLAG1_BUF6I_SHIFT)) & CAN_IFLAG1_BUF6I_MASK) +#define CAN_IFLAG1_BUF7I_MASK (0x80U) +#define CAN_IFLAG1_BUF7I_SHIFT (7U) +/*! BUF7I - Buffer MB7 Interrupt Or "Rx FIFO Overflow" + * 0b0..No occurrence of MB7 completing transmission/reception when MCR[RFEN]=0, or of Rx FIFO overflow when MCR[RFEN]=1 + * 0b1..MB7 completed transmission/reception when MCR[RFEN]=0, or Rx FIFO overflow when MCR[RFEN]=1 + */ +#define CAN_IFLAG1_BUF7I(x) (((uint32_t)(((uint32_t)(x)) << CAN_IFLAG1_BUF7I_SHIFT)) & CAN_IFLAG1_BUF7I_MASK) +#define CAN_IFLAG1_BUF31TO8I_MASK (0xFFFFFF00U) +#define CAN_IFLAG1_BUF31TO8I_SHIFT (8U) +/*! BUF31TO8I - Buffer MBi Interrupt + * 0b000000000000000000000000..The corresponding buffer has no occurrence of successfully completed transmission or reception. + * 0b000000000000000000000001..The corresponding buffer has successfully completed transmission or reception. + */ +#define CAN_IFLAG1_BUF31TO8I(x) (((uint32_t)(((uint32_t)(x)) << CAN_IFLAG1_BUF31TO8I_SHIFT)) & CAN_IFLAG1_BUF31TO8I_MASK) +/*! @} */ + +/*! @name CTRL2 - Control 2 register */ +/*! @{ */ +#define CAN_CTRL2_EACEN_MASK (0x10000U) +#define CAN_CTRL2_EACEN_SHIFT (16U) +/*! EACEN - Entire Frame Arbitration Field Comparison Enable For Rx Mailboxes + * 0b0..Rx Mailbox filter's IDE bit is always compared and RTR is never compared despite mask bits. + * 0b1..Enables the comparison of both Rx Mailbox filter's IDE and RTR bit with their corresponding bits within the incoming frame. Mask bits do apply. + */ +#define CAN_CTRL2_EACEN(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL2_EACEN_SHIFT)) & CAN_CTRL2_EACEN_MASK) +#define CAN_CTRL2_RRS_MASK (0x20000U) +#define CAN_CTRL2_RRS_SHIFT (17U) +/*! RRS - Remote Request Storing + * 0b0..Remote Response Frame is generated. + * 0b1..Remote Request Frame is stored. + */ +#define CAN_CTRL2_RRS(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL2_RRS_SHIFT)) & CAN_CTRL2_RRS_MASK) +#define CAN_CTRL2_MRP_MASK (0x40000U) +#define CAN_CTRL2_MRP_SHIFT (18U) +/*! MRP - Mailboxes Reception Priority + * 0b0..Matching starts from Rx FIFO and continues on Mailboxes. + * 0b1..Matching starts from Mailboxes and continues on Rx FIFO. + */ +#define CAN_CTRL2_MRP(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL2_MRP_SHIFT)) & CAN_CTRL2_MRP_MASK) +#define CAN_CTRL2_TASD_MASK (0xF80000U) +#define CAN_CTRL2_TASD_SHIFT (19U) +#define CAN_CTRL2_TASD(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL2_TASD_SHIFT)) & CAN_CTRL2_TASD_MASK) +#define CAN_CTRL2_RFFN_MASK (0xF000000U) +#define CAN_CTRL2_RFFN_SHIFT (24U) +#define CAN_CTRL2_RFFN(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL2_RFFN_SHIFT)) & CAN_CTRL2_RFFN_MASK) +#define CAN_CTRL2_WRMFRZ_MASK (0x10000000U) +#define CAN_CTRL2_WRMFRZ_SHIFT (28U) +/*! WRMFRZ - Write-Access To Memory In Freeze Mode + * 0b0..Maintain the write access restrictions. + * 0b1..Enable unrestricted write access to FlexCAN memory. + */ +#define CAN_CTRL2_WRMFRZ(x) (((uint32_t)(((uint32_t)(x)) << CAN_CTRL2_WRMFRZ_SHIFT)) & CAN_CTRL2_WRMFRZ_MASK) +/*! @} */ + +/*! @name ESR2 - Error and Status 2 register */ +/*! @{ */ +#define CAN_ESR2_IMB_MASK (0x2000U) +#define CAN_ESR2_IMB_SHIFT (13U) +/*! IMB - Inactive Mailbox + * 0b0..If ESR2[VPS] is asserted, the ESR2[LPTM] is not an inactive Mailbox. + * 0b1..If ESR2[VPS] is asserted, there is at least one inactive Mailbox. LPTM content is the number of the first one. + */ +#define CAN_ESR2_IMB(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR2_IMB_SHIFT)) & CAN_ESR2_IMB_MASK) +#define CAN_ESR2_VPS_MASK (0x4000U) +#define CAN_ESR2_VPS_SHIFT (14U) +/*! VPS - Valid Priority Status + * 0b0..Contents of IMB and LPTM are invalid. + * 0b1..Contents of IMB and LPTM are valid. + */ +#define CAN_ESR2_VPS(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR2_VPS_SHIFT)) & CAN_ESR2_VPS_MASK) +#define CAN_ESR2_LPTM_MASK (0x7F0000U) +#define CAN_ESR2_LPTM_SHIFT (16U) +#define CAN_ESR2_LPTM(x) (((uint32_t)(((uint32_t)(x)) << CAN_ESR2_LPTM_SHIFT)) & CAN_ESR2_LPTM_MASK) +/*! @} */ + +/*! @name CRCR - CRC Register */ +/*! @{ */ +#define CAN_CRCR_TXCRC_MASK (0x7FFFU) +#define CAN_CRCR_TXCRC_SHIFT (0U) +#define CAN_CRCR_TXCRC(x) (((uint32_t)(((uint32_t)(x)) << CAN_CRCR_TXCRC_SHIFT)) & CAN_CRCR_TXCRC_MASK) +#define CAN_CRCR_MBCRC_MASK (0x7F0000U) +#define CAN_CRCR_MBCRC_SHIFT (16U) +#define CAN_CRCR_MBCRC(x) (((uint32_t)(((uint32_t)(x)) << CAN_CRCR_MBCRC_SHIFT)) & CAN_CRCR_MBCRC_MASK) +/*! @} */ + +/*! @name RXFGMASK - Rx FIFO Global Mask register */ +/*! @{ */ +#define CAN_RXFGMASK_FGM_MASK (0xFFFFFFFFU) +#define CAN_RXFGMASK_FGM_SHIFT (0U) +/*! FGM - Rx FIFO Global Mask Bits + * 0b00000000000000000000000000000000..The corresponding bit in the filter is "don't care." + * 0b00000000000000000000000000000001..The corresponding bit in the filter is checked. + */ +#define CAN_RXFGMASK_FGM(x) (((uint32_t)(((uint32_t)(x)) << CAN_RXFGMASK_FGM_SHIFT)) & CAN_RXFGMASK_FGM_MASK) +/*! @} */ + +/*! @name RXFIR - Rx FIFO Information Register */ +/*! @{ */ +#define CAN_RXFIR_IDHIT_MASK (0x1FFU) +#define CAN_RXFIR_IDHIT_SHIFT (0U) +#define CAN_RXFIR_IDHIT(x) (((uint32_t)(((uint32_t)(x)) << CAN_RXFIR_IDHIT_SHIFT)) & CAN_RXFIR_IDHIT_MASK) +/*! @} */ + +/*! @name CS - Message Buffer 0 CS Register..Message Buffer 15 CS Register */ +/*! @{ */ +#define CAN_CS_TIME_STAMP_MASK (0xFFFFU) +#define CAN_CS_TIME_STAMP_SHIFT (0U) +#define CAN_CS_TIME_STAMP(x) (((uint32_t)(((uint32_t)(x)) << CAN_CS_TIME_STAMP_SHIFT)) & CAN_CS_TIME_STAMP_MASK) +#define CAN_CS_DLC_MASK (0xF0000U) +#define CAN_CS_DLC_SHIFT (16U) +#define CAN_CS_DLC(x) (((uint32_t)(((uint32_t)(x)) << CAN_CS_DLC_SHIFT)) & CAN_CS_DLC_MASK) +#define CAN_CS_RTR_MASK (0x100000U) +#define CAN_CS_RTR_SHIFT (20U) +#define CAN_CS_RTR(x) (((uint32_t)(((uint32_t)(x)) << CAN_CS_RTR_SHIFT)) & CAN_CS_RTR_MASK) +#define CAN_CS_IDE_MASK (0x200000U) +#define CAN_CS_IDE_SHIFT (21U) +#define CAN_CS_IDE(x) (((uint32_t)(((uint32_t)(x)) << CAN_CS_IDE_SHIFT)) & CAN_CS_IDE_MASK) +#define CAN_CS_SRR_MASK (0x400000U) +#define CAN_CS_SRR_SHIFT (22U) +#define CAN_CS_SRR(x) (((uint32_t)(((uint32_t)(x)) << CAN_CS_SRR_SHIFT)) & CAN_CS_SRR_MASK) +#define CAN_CS_CODE_MASK (0xF000000U) +#define CAN_CS_CODE_SHIFT (24U) +#define CAN_CS_CODE(x) (((uint32_t)(((uint32_t)(x)) << CAN_CS_CODE_SHIFT)) & CAN_CS_CODE_MASK) +/*! @} */ + +/* The count of CAN_CS */ +#define CAN_CS_COUNT (16U) + +/*! @name ID - Message Buffer 0 ID Register..Message Buffer 15 ID Register */ +/*! @{ */ +#define CAN_ID_EXT_MASK (0x3FFFFU) +#define CAN_ID_EXT_SHIFT (0U) +#define CAN_ID_EXT(x) (((uint32_t)(((uint32_t)(x)) << CAN_ID_EXT_SHIFT)) & CAN_ID_EXT_MASK) +#define CAN_ID_STD_MASK (0x1FFC0000U) +#define CAN_ID_STD_SHIFT (18U) +#define CAN_ID_STD(x) (((uint32_t)(((uint32_t)(x)) << CAN_ID_STD_SHIFT)) & CAN_ID_STD_MASK) +#define CAN_ID_PRIO_MASK (0xE0000000U) +#define CAN_ID_PRIO_SHIFT (29U) +#define CAN_ID_PRIO(x) (((uint32_t)(((uint32_t)(x)) << CAN_ID_PRIO_SHIFT)) & CAN_ID_PRIO_MASK) +/*! @} */ + +/* The count of CAN_ID */ +#define CAN_ID_COUNT (16U) + +/*! @name WORD0 - Message Buffer 0 WORD0 Register..Message Buffer 15 WORD0 Register */ +/*! @{ */ +#define CAN_WORD0_DATA_BYTE_3_MASK (0xFFU) +#define CAN_WORD0_DATA_BYTE_3_SHIFT (0U) +#define CAN_WORD0_DATA_BYTE_3(x) (((uint32_t)(((uint32_t)(x)) << CAN_WORD0_DATA_BYTE_3_SHIFT)) & CAN_WORD0_DATA_BYTE_3_MASK) +#define CAN_WORD0_DATA_BYTE_2_MASK (0xFF00U) +#define CAN_WORD0_DATA_BYTE_2_SHIFT (8U) +#define CAN_WORD0_DATA_BYTE_2(x) (((uint32_t)(((uint32_t)(x)) << CAN_WORD0_DATA_BYTE_2_SHIFT)) & CAN_WORD0_DATA_BYTE_2_MASK) +#define CAN_WORD0_DATA_BYTE_1_MASK (0xFF0000U) +#define CAN_WORD0_DATA_BYTE_1_SHIFT (16U) +#define CAN_WORD0_DATA_BYTE_1(x) (((uint32_t)(((uint32_t)(x)) << CAN_WORD0_DATA_BYTE_1_SHIFT)) & CAN_WORD0_DATA_BYTE_1_MASK) +#define CAN_WORD0_DATA_BYTE_0_MASK (0xFF000000U) +#define CAN_WORD0_DATA_BYTE_0_SHIFT (24U) +#define CAN_WORD0_DATA_BYTE_0(x) (((uint32_t)(((uint32_t)(x)) << CAN_WORD0_DATA_BYTE_0_SHIFT)) & CAN_WORD0_DATA_BYTE_0_MASK) +/*! @} */ + +/* The count of CAN_WORD0 */ +#define CAN_WORD0_COUNT (16U) + +/*! @name WORD1 - Message Buffer 0 WORD1 Register..Message Buffer 15 WORD1 Register */ +/*! @{ */ +#define CAN_WORD1_DATA_BYTE_7_MASK (0xFFU) +#define CAN_WORD1_DATA_BYTE_7_SHIFT (0U) +#define CAN_WORD1_DATA_BYTE_7(x) (((uint32_t)(((uint32_t)(x)) << CAN_WORD1_DATA_BYTE_7_SHIFT)) & CAN_WORD1_DATA_BYTE_7_MASK) +#define CAN_WORD1_DATA_BYTE_6_MASK (0xFF00U) +#define CAN_WORD1_DATA_BYTE_6_SHIFT (8U) +#define CAN_WORD1_DATA_BYTE_6(x) (((uint32_t)(((uint32_t)(x)) << CAN_WORD1_DATA_BYTE_6_SHIFT)) & CAN_WORD1_DATA_BYTE_6_MASK) +#define CAN_WORD1_DATA_BYTE_5_MASK (0xFF0000U) +#define CAN_WORD1_DATA_BYTE_5_SHIFT (16U) +#define CAN_WORD1_DATA_BYTE_5(x) (((uint32_t)(((uint32_t)(x)) << CAN_WORD1_DATA_BYTE_5_SHIFT)) & CAN_WORD1_DATA_BYTE_5_MASK) +#define CAN_WORD1_DATA_BYTE_4_MASK (0xFF000000U) +#define CAN_WORD1_DATA_BYTE_4_SHIFT (24U) +#define CAN_WORD1_DATA_BYTE_4(x) (((uint32_t)(((uint32_t)(x)) << CAN_WORD1_DATA_BYTE_4_SHIFT)) & CAN_WORD1_DATA_BYTE_4_MASK) +/*! @} */ + +/* The count of CAN_WORD1 */ +#define CAN_WORD1_COUNT (16U) + +/*! @name RXIMR - Rx Individual Mask Registers */ +/*! @{ */ +#define CAN_RXIMR_MI_MASK (0xFFFFFFFFU) +#define CAN_RXIMR_MI_SHIFT (0U) +/*! MI - Individual Mask Bits + * 0b00000000000000000000000000000000..The corresponding bit in the filter is "don't care." + * 0b00000000000000000000000000000001..The corresponding bit in the filter is checked. + */ +#define CAN_RXIMR_MI(x) (((uint32_t)(((uint32_t)(x)) << CAN_RXIMR_MI_SHIFT)) & CAN_RXIMR_MI_MASK) +/*! @} */ + +/* The count of CAN_RXIMR */ +#define CAN_RXIMR_COUNT (16U) + + +/*! + * @} + */ /* end of group CAN_Register_Masks */ + + +/* CAN - Peripheral instance base addresses */ +/** Peripheral CAN0 base address */ +#define CAN0_BASE (0x40024000u) +/** Peripheral CAN0 base pointer */ +#define CAN0 ((CAN_Type *)CAN0_BASE) +/** Array initializer of CAN peripheral base addresses */ +#define CAN_BASE_ADDRS { CAN0_BASE } +/** Array initializer of CAN peripheral base pointers */ +#define CAN_BASE_PTRS { CAN0 } +/** Interrupt vectors for the CAN peripheral type */ +#define CAN_Rx_Warning_IRQS { CAN0_Rx_Warning_IRQn } +#define CAN_Tx_Warning_IRQS { CAN0_Tx_Warning_IRQn } +#define CAN_Wake_Up_IRQS { CAN0_Wake_Up_IRQn } +#define CAN_Error_IRQS { CAN0_Error_IRQn } +#define CAN_Bus_Off_IRQS { CAN0_Bus_Off_IRQn } +#define CAN_ORed_Message_buffer_IRQS { CAN0_ORed_Message_buffer_IRQn } + +/*! + * @} + */ /* end of group CAN_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- CAU Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CAU_Peripheral_Access_Layer CAU Peripheral Access Layer + * @{ + */ + +/** CAU - Register Layout Typedef */ +typedef struct { + __O uint32_t DIRECT[16]; /**< Direct access register 0..Direct access register 15, array offset: 0x0, array step: 0x4 */ + uint8_t RESERVED_0[2048]; + __O uint32_t LDR_CASR; /**< Status register - Load Register command, offset: 0x840 */ + __O uint32_t LDR_CAA; /**< Accumulator register - Load Register command, offset: 0x844 */ + __O uint32_t LDR_CA[9]; /**< General Purpose Register 0 - Load Register command..General Purpose Register 8 - Load Register command, array offset: 0x848, array step: 0x4 */ + uint8_t RESERVED_1[20]; + __I uint32_t STR_CASR; /**< Status register - Store Register command, offset: 0x880 */ + __I uint32_t STR_CAA; /**< Accumulator register - Store Register command, offset: 0x884 */ + __I uint32_t STR_CA[9]; /**< General Purpose Register 0 - Store Register command..General Purpose Register 8 - Store Register command, array offset: 0x888, array step: 0x4 */ + uint8_t RESERVED_2[20]; + __O uint32_t ADR_CASR; /**< Status register - Add Register command, offset: 0x8C0 */ + __O uint32_t ADR_CAA; /**< Accumulator register - Add to register command, offset: 0x8C4 */ + __O uint32_t ADR_CA[9]; /**< General Purpose Register 0 - Add to register command..General Purpose Register 8 - Add to register command, array offset: 0x8C8, array step: 0x4 */ + uint8_t RESERVED_3[20]; + __O uint32_t RADR_CASR; /**< Status register - Reverse and Add to Register command, offset: 0x900 */ + __O uint32_t RADR_CAA; /**< Accumulator register - Reverse and Add to Register command, offset: 0x904 */ + __O uint32_t RADR_CA[9]; /**< General Purpose Register 0 - Reverse and Add to Register command..General Purpose Register 8 - Reverse and Add to Register command, array offset: 0x908, array step: 0x4 */ + uint8_t RESERVED_4[84]; + __O uint32_t XOR_CASR; /**< Status register - Exclusive Or command, offset: 0x980 */ + __O uint32_t XOR_CAA; /**< Accumulator register - Exclusive Or command, offset: 0x984 */ + __O uint32_t XOR_CA[9]; /**< General Purpose Register 0 - Exclusive Or command..General Purpose Register 8 - Exclusive Or command, array offset: 0x988, array step: 0x4 */ + uint8_t RESERVED_5[20]; + __O uint32_t ROTL_CASR; /**< Status register - Rotate Left command, offset: 0x9C0 */ + __O uint32_t ROTL_CAA; /**< Accumulator register - Rotate Left command, offset: 0x9C4 */ + __O uint32_t ROTL_CA[9]; /**< General Purpose Register 0 - Rotate Left command..General Purpose Register 8 - Rotate Left command, array offset: 0x9C8, array step: 0x4 */ + uint8_t RESERVED_6[276]; + __O uint32_t AESC_CASR; /**< Status register - AES Column Operation command, offset: 0xB00 */ + __O uint32_t AESC_CAA; /**< Accumulator register - AES Column Operation command, offset: 0xB04 */ + __O uint32_t AESC_CA[9]; /**< General Purpose Register 0 - AES Column Operation command..General Purpose Register 8 - AES Column Operation command, array offset: 0xB08, array step: 0x4 */ + uint8_t RESERVED_7[20]; + __O uint32_t AESIC_CASR; /**< Status register - AES Inverse Column Operation command, offset: 0xB40 */ + __O uint32_t AESIC_CAA; /**< Accumulator register - AES Inverse Column Operation command, offset: 0xB44 */ + __O uint32_t AESIC_CA[9]; /**< General Purpose Register 0 - AES Inverse Column Operation command..General Purpose Register 8 - AES Inverse Column Operation command, array offset: 0xB48, array step: 0x4 */ +} CAU_Type; + +/* ---------------------------------------------------------------------------- + -- CAU Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CAU_Register_Masks CAU Register Masks + * @{ + */ + +/*! @name DIRECT - Direct access register 0..Direct access register 15 */ +/*! @{ */ +#define CAU_DIRECT_CAU_DIRECT0_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT0_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT0(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT0_SHIFT)) & CAU_DIRECT_CAU_DIRECT0_MASK) +#define CAU_DIRECT_CAU_DIRECT1_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT1_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT1(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT1_SHIFT)) & CAU_DIRECT_CAU_DIRECT1_MASK) +#define CAU_DIRECT_CAU_DIRECT2_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT2_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT2(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT2_SHIFT)) & CAU_DIRECT_CAU_DIRECT2_MASK) +#define CAU_DIRECT_CAU_DIRECT3_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT3_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT3(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT3_SHIFT)) & CAU_DIRECT_CAU_DIRECT3_MASK) +#define CAU_DIRECT_CAU_DIRECT4_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT4_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT4(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT4_SHIFT)) & CAU_DIRECT_CAU_DIRECT4_MASK) +#define CAU_DIRECT_CAU_DIRECT5_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT5_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT5(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT5_SHIFT)) & CAU_DIRECT_CAU_DIRECT5_MASK) +#define CAU_DIRECT_CAU_DIRECT6_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT6_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT6(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT6_SHIFT)) & CAU_DIRECT_CAU_DIRECT6_MASK) +#define CAU_DIRECT_CAU_DIRECT7_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT7_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT7(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT7_SHIFT)) & CAU_DIRECT_CAU_DIRECT7_MASK) +#define CAU_DIRECT_CAU_DIRECT8_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT8_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT8(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT8_SHIFT)) & CAU_DIRECT_CAU_DIRECT8_MASK) +#define CAU_DIRECT_CAU_DIRECT9_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT9_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT9(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT9_SHIFT)) & CAU_DIRECT_CAU_DIRECT9_MASK) +#define CAU_DIRECT_CAU_DIRECT10_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT10_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT10(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT10_SHIFT)) & CAU_DIRECT_CAU_DIRECT10_MASK) +#define CAU_DIRECT_CAU_DIRECT11_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT11_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT11(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT11_SHIFT)) & CAU_DIRECT_CAU_DIRECT11_MASK) +#define CAU_DIRECT_CAU_DIRECT12_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT12_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT12(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT12_SHIFT)) & CAU_DIRECT_CAU_DIRECT12_MASK) +#define CAU_DIRECT_CAU_DIRECT13_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT13_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT13(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT13_SHIFT)) & CAU_DIRECT_CAU_DIRECT13_MASK) +#define CAU_DIRECT_CAU_DIRECT14_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT14_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT14(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT14_SHIFT)) & CAU_DIRECT_CAU_DIRECT14_MASK) +#define CAU_DIRECT_CAU_DIRECT15_MASK (0xFFFFFFFFU) +#define CAU_DIRECT_CAU_DIRECT15_SHIFT (0U) +#define CAU_DIRECT_CAU_DIRECT15(x) (((uint32_t)(((uint32_t)(x)) << CAU_DIRECT_CAU_DIRECT15_SHIFT)) & CAU_DIRECT_CAU_DIRECT15_MASK) +/*! @} */ + +/* The count of CAU_DIRECT */ +#define CAU_DIRECT_COUNT (16U) + +/*! @name LDR_CASR - Status register - Load Register command */ +/*! @{ */ +#define CAU_LDR_CASR_IC_MASK (0x1U) +#define CAU_LDR_CASR_IC_SHIFT (0U) +/*! IC + * 0b0..No illegal commands issued + * 0b1..Illegal command issued + */ +#define CAU_LDR_CASR_IC(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CASR_IC_SHIFT)) & CAU_LDR_CASR_IC_MASK) +#define CAU_LDR_CASR_DPE_MASK (0x2U) +#define CAU_LDR_CASR_DPE_SHIFT (1U) +/*! DPE + * 0b0..No error detected + * 0b1..DES key parity error detected + */ +#define CAU_LDR_CASR_DPE(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CASR_DPE_SHIFT)) & CAU_LDR_CASR_DPE_MASK) +#define CAU_LDR_CASR_VER_MASK (0xF0000000U) +#define CAU_LDR_CASR_VER_SHIFT (28U) +/*! VER - CAU version + * 0b0001..Initial CAU version + * 0b0010..Second version, added support for SHA-256 algorithm.(This is the value on this device) + */ +#define CAU_LDR_CASR_VER(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CASR_VER_SHIFT)) & CAU_LDR_CASR_VER_MASK) +/*! @} */ + +/*! @name LDR_CAA - Accumulator register - Load Register command */ +/*! @{ */ +#define CAU_LDR_CAA_ACC_MASK (0xFFFFFFFFU) +#define CAU_LDR_CAA_ACC_SHIFT (0U) +#define CAU_LDR_CAA_ACC(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CAA_ACC_SHIFT)) & CAU_LDR_CAA_ACC_MASK) +/*! @} */ + +/*! @name LDR_CA - General Purpose Register 0 - Load Register command..General Purpose Register 8 - Load Register command */ +/*! @{ */ +#define CAU_LDR_CA_CA0_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA0_SHIFT (0U) +#define CAU_LDR_CA_CA0(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA0_SHIFT)) & CAU_LDR_CA_CA0_MASK) +#define CAU_LDR_CA_CA1_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA1_SHIFT (0U) +#define CAU_LDR_CA_CA1(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA1_SHIFT)) & CAU_LDR_CA_CA1_MASK) +#define CAU_LDR_CA_CA2_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA2_SHIFT (0U) +#define CAU_LDR_CA_CA2(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA2_SHIFT)) & CAU_LDR_CA_CA2_MASK) +#define CAU_LDR_CA_CA3_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA3_SHIFT (0U) +#define CAU_LDR_CA_CA3(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA3_SHIFT)) & CAU_LDR_CA_CA3_MASK) +#define CAU_LDR_CA_CA4_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA4_SHIFT (0U) +#define CAU_LDR_CA_CA4(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA4_SHIFT)) & CAU_LDR_CA_CA4_MASK) +#define CAU_LDR_CA_CA5_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA5_SHIFT (0U) +#define CAU_LDR_CA_CA5(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA5_SHIFT)) & CAU_LDR_CA_CA5_MASK) +#define CAU_LDR_CA_CA6_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA6_SHIFT (0U) +#define CAU_LDR_CA_CA6(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA6_SHIFT)) & CAU_LDR_CA_CA6_MASK) +#define CAU_LDR_CA_CA7_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA7_SHIFT (0U) +#define CAU_LDR_CA_CA7(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA7_SHIFT)) & CAU_LDR_CA_CA7_MASK) +#define CAU_LDR_CA_CA8_MASK (0xFFFFFFFFU) +#define CAU_LDR_CA_CA8_SHIFT (0U) +#define CAU_LDR_CA_CA8(x) (((uint32_t)(((uint32_t)(x)) << CAU_LDR_CA_CA8_SHIFT)) & CAU_LDR_CA_CA8_MASK) +/*! @} */ + +/* The count of CAU_LDR_CA */ +#define CAU_LDR_CA_COUNT (9U) + +/*! @name STR_CASR - Status register - Store Register command */ +/*! @{ */ +#define CAU_STR_CASR_IC_MASK (0x1U) +#define CAU_STR_CASR_IC_SHIFT (0U) +/*! IC + * 0b0..No illegal commands issued + * 0b1..Illegal command issued + */ +#define CAU_STR_CASR_IC(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CASR_IC_SHIFT)) & CAU_STR_CASR_IC_MASK) +#define CAU_STR_CASR_DPE_MASK (0x2U) +#define CAU_STR_CASR_DPE_SHIFT (1U) +/*! DPE + * 0b0..No error detected + * 0b1..DES key parity error detected + */ +#define CAU_STR_CASR_DPE(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CASR_DPE_SHIFT)) & CAU_STR_CASR_DPE_MASK) +#define CAU_STR_CASR_VER_MASK (0xF0000000U) +#define CAU_STR_CASR_VER_SHIFT (28U) +/*! VER - CAU version + * 0b0001..Initial CAU version + * 0b0010..Second version, added support for SHA-256 algorithm.(This is the value on this device) + */ +#define CAU_STR_CASR_VER(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CASR_VER_SHIFT)) & CAU_STR_CASR_VER_MASK) +/*! @} */ + +/*! @name STR_CAA - Accumulator register - Store Register command */ +/*! @{ */ +#define CAU_STR_CAA_ACC_MASK (0xFFFFFFFFU) +#define CAU_STR_CAA_ACC_SHIFT (0U) +#define CAU_STR_CAA_ACC(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CAA_ACC_SHIFT)) & CAU_STR_CAA_ACC_MASK) +/*! @} */ + +/*! @name STR_CA - General Purpose Register 0 - Store Register command..General Purpose Register 8 - Store Register command */ +/*! @{ */ +#define CAU_STR_CA_CA0_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA0_SHIFT (0U) +#define CAU_STR_CA_CA0(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA0_SHIFT)) & CAU_STR_CA_CA0_MASK) +#define CAU_STR_CA_CA1_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA1_SHIFT (0U) +#define CAU_STR_CA_CA1(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA1_SHIFT)) & CAU_STR_CA_CA1_MASK) +#define CAU_STR_CA_CA2_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA2_SHIFT (0U) +#define CAU_STR_CA_CA2(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA2_SHIFT)) & CAU_STR_CA_CA2_MASK) +#define CAU_STR_CA_CA3_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA3_SHIFT (0U) +#define CAU_STR_CA_CA3(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA3_SHIFT)) & CAU_STR_CA_CA3_MASK) +#define CAU_STR_CA_CA4_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA4_SHIFT (0U) +#define CAU_STR_CA_CA4(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA4_SHIFT)) & CAU_STR_CA_CA4_MASK) +#define CAU_STR_CA_CA5_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA5_SHIFT (0U) +#define CAU_STR_CA_CA5(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA5_SHIFT)) & CAU_STR_CA_CA5_MASK) +#define CAU_STR_CA_CA6_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA6_SHIFT (0U) +#define CAU_STR_CA_CA6(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA6_SHIFT)) & CAU_STR_CA_CA6_MASK) +#define CAU_STR_CA_CA7_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA7_SHIFT (0U) +#define CAU_STR_CA_CA7(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA7_SHIFT)) & CAU_STR_CA_CA7_MASK) +#define CAU_STR_CA_CA8_MASK (0xFFFFFFFFU) +#define CAU_STR_CA_CA8_SHIFT (0U) +#define CAU_STR_CA_CA8(x) (((uint32_t)(((uint32_t)(x)) << CAU_STR_CA_CA8_SHIFT)) & CAU_STR_CA_CA8_MASK) +/*! @} */ + +/* The count of CAU_STR_CA */ +#define CAU_STR_CA_COUNT (9U) + +/*! @name ADR_CASR - Status register - Add Register command */ +/*! @{ */ +#define CAU_ADR_CASR_IC_MASK (0x1U) +#define CAU_ADR_CASR_IC_SHIFT (0U) +/*! IC + * 0b0..No illegal commands issued + * 0b1..Illegal command issued + */ +#define CAU_ADR_CASR_IC(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CASR_IC_SHIFT)) & CAU_ADR_CASR_IC_MASK) +#define CAU_ADR_CASR_DPE_MASK (0x2U) +#define CAU_ADR_CASR_DPE_SHIFT (1U) +/*! DPE + * 0b0..No error detected + * 0b1..DES key parity error detected + */ +#define CAU_ADR_CASR_DPE(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CASR_DPE_SHIFT)) & CAU_ADR_CASR_DPE_MASK) +#define CAU_ADR_CASR_VER_MASK (0xF0000000U) +#define CAU_ADR_CASR_VER_SHIFT (28U) +/*! VER - CAU version + * 0b0001..Initial CAU version + * 0b0010..Second version, added support for SHA-256 algorithm.(This is the value on this device) + */ +#define CAU_ADR_CASR_VER(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CASR_VER_SHIFT)) & CAU_ADR_CASR_VER_MASK) +/*! @} */ + +/*! @name ADR_CAA - Accumulator register - Add to register command */ +/*! @{ */ +#define CAU_ADR_CAA_ACC_MASK (0xFFFFFFFFU) +#define CAU_ADR_CAA_ACC_SHIFT (0U) +#define CAU_ADR_CAA_ACC(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CAA_ACC_SHIFT)) & CAU_ADR_CAA_ACC_MASK) +/*! @} */ + +/*! @name ADR_CA - General Purpose Register 0 - Add to register command..General Purpose Register 8 - Add to register command */ +/*! @{ */ +#define CAU_ADR_CA_CA0_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA0_SHIFT (0U) +#define CAU_ADR_CA_CA0(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA0_SHIFT)) & CAU_ADR_CA_CA0_MASK) +#define CAU_ADR_CA_CA1_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA1_SHIFT (0U) +#define CAU_ADR_CA_CA1(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA1_SHIFT)) & CAU_ADR_CA_CA1_MASK) +#define CAU_ADR_CA_CA2_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA2_SHIFT (0U) +#define CAU_ADR_CA_CA2(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA2_SHIFT)) & CAU_ADR_CA_CA2_MASK) +#define CAU_ADR_CA_CA3_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA3_SHIFT (0U) +#define CAU_ADR_CA_CA3(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA3_SHIFT)) & CAU_ADR_CA_CA3_MASK) +#define CAU_ADR_CA_CA4_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA4_SHIFT (0U) +#define CAU_ADR_CA_CA4(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA4_SHIFT)) & CAU_ADR_CA_CA4_MASK) +#define CAU_ADR_CA_CA5_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA5_SHIFT (0U) +#define CAU_ADR_CA_CA5(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA5_SHIFT)) & CAU_ADR_CA_CA5_MASK) +#define CAU_ADR_CA_CA6_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA6_SHIFT (0U) +#define CAU_ADR_CA_CA6(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA6_SHIFT)) & CAU_ADR_CA_CA6_MASK) +#define CAU_ADR_CA_CA7_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA7_SHIFT (0U) +#define CAU_ADR_CA_CA7(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA7_SHIFT)) & CAU_ADR_CA_CA7_MASK) +#define CAU_ADR_CA_CA8_MASK (0xFFFFFFFFU) +#define CAU_ADR_CA_CA8_SHIFT (0U) +#define CAU_ADR_CA_CA8(x) (((uint32_t)(((uint32_t)(x)) << CAU_ADR_CA_CA8_SHIFT)) & CAU_ADR_CA_CA8_MASK) +/*! @} */ + +/* The count of CAU_ADR_CA */ +#define CAU_ADR_CA_COUNT (9U) + +/*! @name RADR_CASR - Status register - Reverse and Add to Register command */ +/*! @{ */ +#define CAU_RADR_CASR_IC_MASK (0x1U) +#define CAU_RADR_CASR_IC_SHIFT (0U) +/*! IC + * 0b0..No illegal commands issued + * 0b1..Illegal command issued + */ +#define CAU_RADR_CASR_IC(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CASR_IC_SHIFT)) & CAU_RADR_CASR_IC_MASK) +#define CAU_RADR_CASR_DPE_MASK (0x2U) +#define CAU_RADR_CASR_DPE_SHIFT (1U) +/*! DPE + * 0b0..No error detected + * 0b1..DES key parity error detected + */ +#define CAU_RADR_CASR_DPE(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CASR_DPE_SHIFT)) & CAU_RADR_CASR_DPE_MASK) +#define CAU_RADR_CASR_VER_MASK (0xF0000000U) +#define CAU_RADR_CASR_VER_SHIFT (28U) +/*! VER - CAU version + * 0b0001..Initial CAU version + * 0b0010..Second version, added support for SHA-256 algorithm.(This is the value on this device) + */ +#define CAU_RADR_CASR_VER(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CASR_VER_SHIFT)) & CAU_RADR_CASR_VER_MASK) +/*! @} */ + +/*! @name RADR_CAA - Accumulator register - Reverse and Add to Register command */ +/*! @{ */ +#define CAU_RADR_CAA_ACC_MASK (0xFFFFFFFFU) +#define CAU_RADR_CAA_ACC_SHIFT (0U) +#define CAU_RADR_CAA_ACC(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CAA_ACC_SHIFT)) & CAU_RADR_CAA_ACC_MASK) +/*! @} */ + +/*! @name RADR_CA - General Purpose Register 0 - Reverse and Add to Register command..General Purpose Register 8 - Reverse and Add to Register command */ +/*! @{ */ +#define CAU_RADR_CA_CA0_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA0_SHIFT (0U) +#define CAU_RADR_CA_CA0(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA0_SHIFT)) & CAU_RADR_CA_CA0_MASK) +#define CAU_RADR_CA_CA1_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA1_SHIFT (0U) +#define CAU_RADR_CA_CA1(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA1_SHIFT)) & CAU_RADR_CA_CA1_MASK) +#define CAU_RADR_CA_CA2_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA2_SHIFT (0U) +#define CAU_RADR_CA_CA2(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA2_SHIFT)) & CAU_RADR_CA_CA2_MASK) +#define CAU_RADR_CA_CA3_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA3_SHIFT (0U) +#define CAU_RADR_CA_CA3(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA3_SHIFT)) & CAU_RADR_CA_CA3_MASK) +#define CAU_RADR_CA_CA4_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA4_SHIFT (0U) +#define CAU_RADR_CA_CA4(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA4_SHIFT)) & CAU_RADR_CA_CA4_MASK) +#define CAU_RADR_CA_CA5_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA5_SHIFT (0U) +#define CAU_RADR_CA_CA5(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA5_SHIFT)) & CAU_RADR_CA_CA5_MASK) +#define CAU_RADR_CA_CA6_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA6_SHIFT (0U) +#define CAU_RADR_CA_CA6(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA6_SHIFT)) & CAU_RADR_CA_CA6_MASK) +#define CAU_RADR_CA_CA7_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA7_SHIFT (0U) +#define CAU_RADR_CA_CA7(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA7_SHIFT)) & CAU_RADR_CA_CA7_MASK) +#define CAU_RADR_CA_CA8_MASK (0xFFFFFFFFU) +#define CAU_RADR_CA_CA8_SHIFT (0U) +#define CAU_RADR_CA_CA8(x) (((uint32_t)(((uint32_t)(x)) << CAU_RADR_CA_CA8_SHIFT)) & CAU_RADR_CA_CA8_MASK) +/*! @} */ + +/* The count of CAU_RADR_CA */ +#define CAU_RADR_CA_COUNT (9U) + +/*! @name XOR_CASR - Status register - Exclusive Or command */ +/*! @{ */ +#define CAU_XOR_CASR_IC_MASK (0x1U) +#define CAU_XOR_CASR_IC_SHIFT (0U) +/*! IC + * 0b0..No illegal commands issued + * 0b1..Illegal command issued + */ +#define CAU_XOR_CASR_IC(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CASR_IC_SHIFT)) & CAU_XOR_CASR_IC_MASK) +#define CAU_XOR_CASR_DPE_MASK (0x2U) +#define CAU_XOR_CASR_DPE_SHIFT (1U) +/*! DPE + * 0b0..No error detected + * 0b1..DES key parity error detected + */ +#define CAU_XOR_CASR_DPE(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CASR_DPE_SHIFT)) & CAU_XOR_CASR_DPE_MASK) +#define CAU_XOR_CASR_VER_MASK (0xF0000000U) +#define CAU_XOR_CASR_VER_SHIFT (28U) +/*! VER - CAU version + * 0b0001..Initial CAU version + * 0b0010..Second version, added support for SHA-256 algorithm.(This is the value on this device) + */ +#define CAU_XOR_CASR_VER(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CASR_VER_SHIFT)) & CAU_XOR_CASR_VER_MASK) +/*! @} */ + +/*! @name XOR_CAA - Accumulator register - Exclusive Or command */ +/*! @{ */ +#define CAU_XOR_CAA_ACC_MASK (0xFFFFFFFFU) +#define CAU_XOR_CAA_ACC_SHIFT (0U) +#define CAU_XOR_CAA_ACC(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CAA_ACC_SHIFT)) & CAU_XOR_CAA_ACC_MASK) +/*! @} */ + +/*! @name XOR_CA - General Purpose Register 0 - Exclusive Or command..General Purpose Register 8 - Exclusive Or command */ +/*! @{ */ +#define CAU_XOR_CA_CA0_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA0_SHIFT (0U) +#define CAU_XOR_CA_CA0(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA0_SHIFT)) & CAU_XOR_CA_CA0_MASK) +#define CAU_XOR_CA_CA1_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA1_SHIFT (0U) +#define CAU_XOR_CA_CA1(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA1_SHIFT)) & CAU_XOR_CA_CA1_MASK) +#define CAU_XOR_CA_CA2_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA2_SHIFT (0U) +#define CAU_XOR_CA_CA2(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA2_SHIFT)) & CAU_XOR_CA_CA2_MASK) +#define CAU_XOR_CA_CA3_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA3_SHIFT (0U) +#define CAU_XOR_CA_CA3(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA3_SHIFT)) & CAU_XOR_CA_CA3_MASK) +#define CAU_XOR_CA_CA4_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA4_SHIFT (0U) +#define CAU_XOR_CA_CA4(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA4_SHIFT)) & CAU_XOR_CA_CA4_MASK) +#define CAU_XOR_CA_CA5_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA5_SHIFT (0U) +#define CAU_XOR_CA_CA5(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA5_SHIFT)) & CAU_XOR_CA_CA5_MASK) +#define CAU_XOR_CA_CA6_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA6_SHIFT (0U) +#define CAU_XOR_CA_CA6(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA6_SHIFT)) & CAU_XOR_CA_CA6_MASK) +#define CAU_XOR_CA_CA7_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA7_SHIFT (0U) +#define CAU_XOR_CA_CA7(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA7_SHIFT)) & CAU_XOR_CA_CA7_MASK) +#define CAU_XOR_CA_CA8_MASK (0xFFFFFFFFU) +#define CAU_XOR_CA_CA8_SHIFT (0U) +#define CAU_XOR_CA_CA8(x) (((uint32_t)(((uint32_t)(x)) << CAU_XOR_CA_CA8_SHIFT)) & CAU_XOR_CA_CA8_MASK) +/*! @} */ + +/* The count of CAU_XOR_CA */ +#define CAU_XOR_CA_COUNT (9U) + +/*! @name ROTL_CASR - Status register - Rotate Left command */ +/*! @{ */ +#define CAU_ROTL_CASR_IC_MASK (0x1U) +#define CAU_ROTL_CASR_IC_SHIFT (0U) +/*! IC + * 0b0..No illegal commands issued + * 0b1..Illegal command issued + */ +#define CAU_ROTL_CASR_IC(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CASR_IC_SHIFT)) & CAU_ROTL_CASR_IC_MASK) +#define CAU_ROTL_CASR_DPE_MASK (0x2U) +#define CAU_ROTL_CASR_DPE_SHIFT (1U) +/*! DPE + * 0b0..No error detected + * 0b1..DES key parity error detected + */ +#define CAU_ROTL_CASR_DPE(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CASR_DPE_SHIFT)) & CAU_ROTL_CASR_DPE_MASK) +#define CAU_ROTL_CASR_VER_MASK (0xF0000000U) +#define CAU_ROTL_CASR_VER_SHIFT (28U) +/*! VER - CAU version + * 0b0001..Initial CAU version + * 0b0010..Second version, added support for SHA-256 algorithm.(This is the value on this device) + */ +#define CAU_ROTL_CASR_VER(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CASR_VER_SHIFT)) & CAU_ROTL_CASR_VER_MASK) +/*! @} */ + +/*! @name ROTL_CAA - Accumulator register - Rotate Left command */ +/*! @{ */ +#define CAU_ROTL_CAA_ACC_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CAA_ACC_SHIFT (0U) +#define CAU_ROTL_CAA_ACC(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CAA_ACC_SHIFT)) & CAU_ROTL_CAA_ACC_MASK) +/*! @} */ + +/*! @name ROTL_CA - General Purpose Register 0 - Rotate Left command..General Purpose Register 8 - Rotate Left command */ +/*! @{ */ +#define CAU_ROTL_CA_CA0_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA0_SHIFT (0U) +#define CAU_ROTL_CA_CA0(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA0_SHIFT)) & CAU_ROTL_CA_CA0_MASK) +#define CAU_ROTL_CA_CA1_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA1_SHIFT (0U) +#define CAU_ROTL_CA_CA1(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA1_SHIFT)) & CAU_ROTL_CA_CA1_MASK) +#define CAU_ROTL_CA_CA2_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA2_SHIFT (0U) +#define CAU_ROTL_CA_CA2(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA2_SHIFT)) & CAU_ROTL_CA_CA2_MASK) +#define CAU_ROTL_CA_CA3_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA3_SHIFT (0U) +#define CAU_ROTL_CA_CA3(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA3_SHIFT)) & CAU_ROTL_CA_CA3_MASK) +#define CAU_ROTL_CA_CA4_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA4_SHIFT (0U) +#define CAU_ROTL_CA_CA4(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA4_SHIFT)) & CAU_ROTL_CA_CA4_MASK) +#define CAU_ROTL_CA_CA5_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA5_SHIFT (0U) +#define CAU_ROTL_CA_CA5(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA5_SHIFT)) & CAU_ROTL_CA_CA5_MASK) +#define CAU_ROTL_CA_CA6_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA6_SHIFT (0U) +#define CAU_ROTL_CA_CA6(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA6_SHIFT)) & CAU_ROTL_CA_CA6_MASK) +#define CAU_ROTL_CA_CA7_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA7_SHIFT (0U) +#define CAU_ROTL_CA_CA7(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA7_SHIFT)) & CAU_ROTL_CA_CA7_MASK) +#define CAU_ROTL_CA_CA8_MASK (0xFFFFFFFFU) +#define CAU_ROTL_CA_CA8_SHIFT (0U) +#define CAU_ROTL_CA_CA8(x) (((uint32_t)(((uint32_t)(x)) << CAU_ROTL_CA_CA8_SHIFT)) & CAU_ROTL_CA_CA8_MASK) +/*! @} */ + +/* The count of CAU_ROTL_CA */ +#define CAU_ROTL_CA_COUNT (9U) + +/*! @name AESC_CASR - Status register - AES Column Operation command */ +/*! @{ */ +#define CAU_AESC_CASR_IC_MASK (0x1U) +#define CAU_AESC_CASR_IC_SHIFT (0U) +/*! IC + * 0b0..No illegal commands issued + * 0b1..Illegal command issued + */ +#define CAU_AESC_CASR_IC(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CASR_IC_SHIFT)) & CAU_AESC_CASR_IC_MASK) +#define CAU_AESC_CASR_DPE_MASK (0x2U) +#define CAU_AESC_CASR_DPE_SHIFT (1U) +/*! DPE + * 0b0..No error detected + * 0b1..DES key parity error detected + */ +#define CAU_AESC_CASR_DPE(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CASR_DPE_SHIFT)) & CAU_AESC_CASR_DPE_MASK) +#define CAU_AESC_CASR_VER_MASK (0xF0000000U) +#define CAU_AESC_CASR_VER_SHIFT (28U) +/*! VER - CAU version + * 0b0001..Initial CAU version + * 0b0010..Second version, added support for SHA-256 algorithm.(This is the value on this device) + */ +#define CAU_AESC_CASR_VER(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CASR_VER_SHIFT)) & CAU_AESC_CASR_VER_MASK) +/*! @} */ + +/*! @name AESC_CAA - Accumulator register - AES Column Operation command */ +/*! @{ */ +#define CAU_AESC_CAA_ACC_MASK (0xFFFFFFFFU) +#define CAU_AESC_CAA_ACC_SHIFT (0U) +#define CAU_AESC_CAA_ACC(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CAA_ACC_SHIFT)) & CAU_AESC_CAA_ACC_MASK) +/*! @} */ + +/*! @name AESC_CA - General Purpose Register 0 - AES Column Operation command..General Purpose Register 8 - AES Column Operation command */ +/*! @{ */ +#define CAU_AESC_CA_CA0_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA0_SHIFT (0U) +#define CAU_AESC_CA_CA0(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA0_SHIFT)) & CAU_AESC_CA_CA0_MASK) +#define CAU_AESC_CA_CA1_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA1_SHIFT (0U) +#define CAU_AESC_CA_CA1(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA1_SHIFT)) & CAU_AESC_CA_CA1_MASK) +#define CAU_AESC_CA_CA2_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA2_SHIFT (0U) +#define CAU_AESC_CA_CA2(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA2_SHIFT)) & CAU_AESC_CA_CA2_MASK) +#define CAU_AESC_CA_CA3_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA3_SHIFT (0U) +#define CAU_AESC_CA_CA3(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA3_SHIFT)) & CAU_AESC_CA_CA3_MASK) +#define CAU_AESC_CA_CA4_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA4_SHIFT (0U) +#define CAU_AESC_CA_CA4(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA4_SHIFT)) & CAU_AESC_CA_CA4_MASK) +#define CAU_AESC_CA_CA5_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA5_SHIFT (0U) +#define CAU_AESC_CA_CA5(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA5_SHIFT)) & CAU_AESC_CA_CA5_MASK) +#define CAU_AESC_CA_CA6_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA6_SHIFT (0U) +#define CAU_AESC_CA_CA6(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA6_SHIFT)) & CAU_AESC_CA_CA6_MASK) +#define CAU_AESC_CA_CA7_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA7_SHIFT (0U) +#define CAU_AESC_CA_CA7(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA7_SHIFT)) & CAU_AESC_CA_CA7_MASK) +#define CAU_AESC_CA_CA8_MASK (0xFFFFFFFFU) +#define CAU_AESC_CA_CA8_SHIFT (0U) +#define CAU_AESC_CA_CA8(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESC_CA_CA8_SHIFT)) & CAU_AESC_CA_CA8_MASK) +/*! @} */ + +/* The count of CAU_AESC_CA */ +#define CAU_AESC_CA_COUNT (9U) + +/*! @name AESIC_CASR - Status register - AES Inverse Column Operation command */ +/*! @{ */ +#define CAU_AESIC_CASR_IC_MASK (0x1U) +#define CAU_AESIC_CASR_IC_SHIFT (0U) +/*! IC + * 0b0..No illegal commands issued + * 0b1..Illegal command issued + */ +#define CAU_AESIC_CASR_IC(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CASR_IC_SHIFT)) & CAU_AESIC_CASR_IC_MASK) +#define CAU_AESIC_CASR_DPE_MASK (0x2U) +#define CAU_AESIC_CASR_DPE_SHIFT (1U) +/*! DPE + * 0b0..No error detected + * 0b1..DES key parity error detected + */ +#define CAU_AESIC_CASR_DPE(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CASR_DPE_SHIFT)) & CAU_AESIC_CASR_DPE_MASK) +#define CAU_AESIC_CASR_VER_MASK (0xF0000000U) +#define CAU_AESIC_CASR_VER_SHIFT (28U) +/*! VER - CAU version + * 0b0001..Initial CAU version + * 0b0010..Second version, added support for SHA-256 algorithm.(This is the value on this device) + */ +#define CAU_AESIC_CASR_VER(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CASR_VER_SHIFT)) & CAU_AESIC_CASR_VER_MASK) +/*! @} */ + +/*! @name AESIC_CAA - Accumulator register - AES Inverse Column Operation command */ +/*! @{ */ +#define CAU_AESIC_CAA_ACC_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CAA_ACC_SHIFT (0U) +#define CAU_AESIC_CAA_ACC(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CAA_ACC_SHIFT)) & CAU_AESIC_CAA_ACC_MASK) +/*! @} */ + +/*! @name AESIC_CA - General Purpose Register 0 - AES Inverse Column Operation command..General Purpose Register 8 - AES Inverse Column Operation command */ +/*! @{ */ +#define CAU_AESIC_CA_CA0_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA0_SHIFT (0U) +#define CAU_AESIC_CA_CA0(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA0_SHIFT)) & CAU_AESIC_CA_CA0_MASK) +#define CAU_AESIC_CA_CA1_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA1_SHIFT (0U) +#define CAU_AESIC_CA_CA1(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA1_SHIFT)) & CAU_AESIC_CA_CA1_MASK) +#define CAU_AESIC_CA_CA2_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA2_SHIFT (0U) +#define CAU_AESIC_CA_CA2(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA2_SHIFT)) & CAU_AESIC_CA_CA2_MASK) +#define CAU_AESIC_CA_CA3_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA3_SHIFT (0U) +#define CAU_AESIC_CA_CA3(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA3_SHIFT)) & CAU_AESIC_CA_CA3_MASK) +#define CAU_AESIC_CA_CA4_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA4_SHIFT (0U) +#define CAU_AESIC_CA_CA4(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA4_SHIFT)) & CAU_AESIC_CA_CA4_MASK) +#define CAU_AESIC_CA_CA5_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA5_SHIFT (0U) +#define CAU_AESIC_CA_CA5(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA5_SHIFT)) & CAU_AESIC_CA_CA5_MASK) +#define CAU_AESIC_CA_CA6_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA6_SHIFT (0U) +#define CAU_AESIC_CA_CA6(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA6_SHIFT)) & CAU_AESIC_CA_CA6_MASK) +#define CAU_AESIC_CA_CA7_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA7_SHIFT (0U) +#define CAU_AESIC_CA_CA7(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA7_SHIFT)) & CAU_AESIC_CA_CA7_MASK) +#define CAU_AESIC_CA_CA8_MASK (0xFFFFFFFFU) +#define CAU_AESIC_CA_CA8_SHIFT (0U) +#define CAU_AESIC_CA_CA8(x) (((uint32_t)(((uint32_t)(x)) << CAU_AESIC_CA_CA8_SHIFT)) & CAU_AESIC_CA_CA8_MASK) +/*! @} */ + +/* The count of CAU_AESIC_CA */ +#define CAU_AESIC_CA_COUNT (9U) + + +/*! + * @} + */ /* end of group CAU_Register_Masks */ + + +/* CAU - Peripheral instance base addresses */ +/** Peripheral CAU base address */ +#define CAU_BASE (0xE0081000u) +/** Peripheral CAU base pointer */ +#define CAU ((CAU_Type *)CAU_BASE) +/** Array initializer of CAU peripheral base addresses */ +#define CAU_BASE_ADDRS { CAU_BASE } +/** Array initializer of CAU peripheral base pointers */ +#define CAU_BASE_PTRS { CAU } + +/*! + * @} + */ /* end of group CAU_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- CMP Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CMP_Peripheral_Access_Layer CMP Peripheral Access Layer + * @{ + */ + +/** CMP - Register Layout Typedef */ +typedef struct { + __IO uint8_t CR0; /**< CMP Control Register 0, offset: 0x0 */ + __IO uint8_t CR1; /**< CMP Control Register 1, offset: 0x1 */ + __IO uint8_t FPR; /**< CMP Filter Period Register, offset: 0x2 */ + __IO uint8_t SCR; /**< CMP Status and Control Register, offset: 0x3 */ + __IO uint8_t DACCR; /**< DAC Control Register, offset: 0x4 */ + __IO uint8_t MUXCR; /**< MUX Control Register, offset: 0x5 */ +} CMP_Type; + +/* ---------------------------------------------------------------------------- + -- CMP Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CMP_Register_Masks CMP Register Masks + * @{ + */ + +/*! @name CR0 - CMP Control Register 0 */ +/*! @{ */ +#define CMP_CR0_HYSTCTR_MASK (0x3U) +#define CMP_CR0_HYSTCTR_SHIFT (0U) +/*! HYSTCTR - Comparator hard block hysteresis control + * 0b00..Level 0 + * 0b01..Level 1 + * 0b10..Level 2 + * 0b11..Level 3 + */ +#define CMP_CR0_HYSTCTR(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR0_HYSTCTR_SHIFT)) & CMP_CR0_HYSTCTR_MASK) +#define CMP_CR0_FILTER_CNT_MASK (0x70U) +#define CMP_CR0_FILTER_CNT_SHIFT (4U) +/*! FILTER_CNT - Filter Sample Count + * 0b000..Filter is disabled. If SE = 1, then COUT is a logic 0. This is not a legal state, and is not recommended. If SE = 0, COUT = COUTA. + * 0b001..One sample must agree. The comparator output is simply sampled. + * 0b010..2 consecutive samples must agree. + * 0b011..3 consecutive samples must agree. + * 0b100..4 consecutive samples must agree. + * 0b101..5 consecutive samples must agree. + * 0b110..6 consecutive samples must agree. + * 0b111..7 consecutive samples must agree. + */ +#define CMP_CR0_FILTER_CNT(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR0_FILTER_CNT_SHIFT)) & CMP_CR0_FILTER_CNT_MASK) +/*! @} */ + +/*! @name CR1 - CMP Control Register 1 */ +/*! @{ */ +#define CMP_CR1_EN_MASK (0x1U) +#define CMP_CR1_EN_SHIFT (0U) +/*! EN - Comparator Module Enable + * 0b0..Analog Comparator is disabled. + * 0b1..Analog Comparator is enabled. + */ +#define CMP_CR1_EN(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_EN_SHIFT)) & CMP_CR1_EN_MASK) +#define CMP_CR1_OPE_MASK (0x2U) +#define CMP_CR1_OPE_SHIFT (1U) +/*! OPE - Comparator Output Pin Enable + * 0b0..CMPO is not available on the associated CMPO output pin. If the comparator does not own the pin, this field has no effect. + * 0b1..CMPO is available on the associated CMPO output pin. The comparator output (CMPO) is driven out on the associated CMPO output pin if the comparator owns the pin. If the comparator does not own the field, this bit has no effect. + */ +#define CMP_CR1_OPE(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_OPE_SHIFT)) & CMP_CR1_OPE_MASK) +#define CMP_CR1_COS_MASK (0x4U) +#define CMP_CR1_COS_SHIFT (2U) +/*! COS - Comparator Output Select + * 0b0..Set the filtered comparator output (CMPO) to equal COUT. + * 0b1..Set the unfiltered comparator output (CMPO) to equal COUTA. + */ +#define CMP_CR1_COS(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_COS_SHIFT)) & CMP_CR1_COS_MASK) +#define CMP_CR1_INV_MASK (0x8U) +#define CMP_CR1_INV_SHIFT (3U) +/*! INV - Comparator INVERT + * 0b0..Does not invert the comparator output. + * 0b1..Inverts the comparator output. + */ +#define CMP_CR1_INV(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_INV_SHIFT)) & CMP_CR1_INV_MASK) +#define CMP_CR1_PMODE_MASK (0x10U) +#define CMP_CR1_PMODE_SHIFT (4U) +/*! PMODE - Power Mode Select + * 0b0..Low-Speed (LS) Comparison mode selected. In this mode, CMP has slower output propagation delay and lower current consumption. + * 0b1..High-Speed (HS) Comparison mode selected. In this mode, CMP has faster output propagation delay and higher current consumption. + */ +#define CMP_CR1_PMODE(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_PMODE_SHIFT)) & CMP_CR1_PMODE_MASK) +#define CMP_CR1_WE_MASK (0x40U) +#define CMP_CR1_WE_SHIFT (6U) +/*! WE - Windowing Enable + * 0b0..Windowing mode is not selected. + * 0b1..Windowing mode is selected. + */ +#define CMP_CR1_WE(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_WE_SHIFT)) & CMP_CR1_WE_MASK) +#define CMP_CR1_SE_MASK (0x80U) +#define CMP_CR1_SE_SHIFT (7U) +/*! SE - Sample Enable + * 0b0..Sampling mode is not selected. + * 0b1..Sampling mode is selected. + */ +#define CMP_CR1_SE(x) (((uint8_t)(((uint8_t)(x)) << CMP_CR1_SE_SHIFT)) & CMP_CR1_SE_MASK) +/*! @} */ + +/*! @name FPR - CMP Filter Period Register */ +/*! @{ */ +#define CMP_FPR_FILT_PER_MASK (0xFFU) +#define CMP_FPR_FILT_PER_SHIFT (0U) +#define CMP_FPR_FILT_PER(x) (((uint8_t)(((uint8_t)(x)) << CMP_FPR_FILT_PER_SHIFT)) & CMP_FPR_FILT_PER_MASK) +/*! @} */ + +/*! @name SCR - CMP Status and Control Register */ +/*! @{ */ +#define CMP_SCR_COUT_MASK (0x1U) +#define CMP_SCR_COUT_SHIFT (0U) +#define CMP_SCR_COUT(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_COUT_SHIFT)) & CMP_SCR_COUT_MASK) +#define CMP_SCR_CFF_MASK (0x2U) +#define CMP_SCR_CFF_SHIFT (1U) +/*! CFF - Analog Comparator Flag Falling + * 0b0..Falling-edge on COUT has not been detected. + * 0b1..Falling-edge on COUT has occurred. + */ +#define CMP_SCR_CFF(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_CFF_SHIFT)) & CMP_SCR_CFF_MASK) +#define CMP_SCR_CFR_MASK (0x4U) +#define CMP_SCR_CFR_SHIFT (2U) +/*! CFR - Analog Comparator Flag Rising + * 0b0..Rising-edge on COUT has not been detected. + * 0b1..Rising-edge on COUT has occurred. + */ +#define CMP_SCR_CFR(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_CFR_SHIFT)) & CMP_SCR_CFR_MASK) +#define CMP_SCR_IEF_MASK (0x8U) +#define CMP_SCR_IEF_SHIFT (3U) +/*! IEF - Comparator Interrupt Enable Falling + * 0b0..Interrupt is disabled. + * 0b1..Interrupt is enabled. + */ +#define CMP_SCR_IEF(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_IEF_SHIFT)) & CMP_SCR_IEF_MASK) +#define CMP_SCR_IER_MASK (0x10U) +#define CMP_SCR_IER_SHIFT (4U) +/*! IER - Comparator Interrupt Enable Rising + * 0b0..Interrupt is disabled. + * 0b1..Interrupt is enabled. + */ +#define CMP_SCR_IER(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_IER_SHIFT)) & CMP_SCR_IER_MASK) +#define CMP_SCR_DMAEN_MASK (0x40U) +#define CMP_SCR_DMAEN_SHIFT (6U) +/*! DMAEN - DMA Enable Control + * 0b0..DMA is disabled. + * 0b1..DMA is enabled. + */ +#define CMP_SCR_DMAEN(x) (((uint8_t)(((uint8_t)(x)) << CMP_SCR_DMAEN_SHIFT)) & CMP_SCR_DMAEN_MASK) +/*! @} */ + +/*! @name DACCR - DAC Control Register */ +/*! @{ */ +#define CMP_DACCR_VOSEL_MASK (0x3FU) +#define CMP_DACCR_VOSEL_SHIFT (0U) +#define CMP_DACCR_VOSEL(x) (((uint8_t)(((uint8_t)(x)) << CMP_DACCR_VOSEL_SHIFT)) & CMP_DACCR_VOSEL_MASK) +#define CMP_DACCR_VRSEL_MASK (0x40U) +#define CMP_DACCR_VRSEL_SHIFT (6U) +/*! VRSEL - Supply Voltage Reference Source Select + * 0b0..V is selected as resistor ladder network supply reference V. in1 in + * 0b1..V is selected as resistor ladder network supply reference V. in2 in + */ +#define CMP_DACCR_VRSEL(x) (((uint8_t)(((uint8_t)(x)) << CMP_DACCR_VRSEL_SHIFT)) & CMP_DACCR_VRSEL_MASK) +#define CMP_DACCR_DACEN_MASK (0x80U) +#define CMP_DACCR_DACEN_SHIFT (7U) +/*! DACEN - DAC Enable + * 0b0..DAC is disabled. + * 0b1..DAC is enabled. + */ +#define CMP_DACCR_DACEN(x) (((uint8_t)(((uint8_t)(x)) << CMP_DACCR_DACEN_SHIFT)) & CMP_DACCR_DACEN_MASK) +/*! @} */ + +/*! @name MUXCR - MUX Control Register */ +/*! @{ */ +#define CMP_MUXCR_MSEL_MASK (0x7U) +#define CMP_MUXCR_MSEL_SHIFT (0U) +/*! MSEL - Minus Input Mux Control + * 0b000..IN0 + * 0b001..IN1 + * 0b010..IN2 + * 0b011..IN3 + * 0b100..IN4 + * 0b101..IN5 + * 0b110..IN6 + * 0b111..IN7 + */ +#define CMP_MUXCR_MSEL(x) (((uint8_t)(((uint8_t)(x)) << CMP_MUXCR_MSEL_SHIFT)) & CMP_MUXCR_MSEL_MASK) +#define CMP_MUXCR_PSEL_MASK (0x38U) +#define CMP_MUXCR_PSEL_SHIFT (3U) +/*! PSEL - Plus Input Mux Control + * 0b000..IN0 + * 0b001..IN1 + * 0b010..IN2 + * 0b011..IN3 + * 0b100..IN4 + * 0b101..IN5 + * 0b110..IN6 + * 0b111..IN7 + */ +#define CMP_MUXCR_PSEL(x) (((uint8_t)(((uint8_t)(x)) << CMP_MUXCR_PSEL_SHIFT)) & CMP_MUXCR_PSEL_MASK) +#define CMP_MUXCR_PSTM_MASK (0x80U) +#define CMP_MUXCR_PSTM_SHIFT (7U) +/*! PSTM - Pass Through Mode Enable + * 0b0..Pass Through Mode is disabled. + * 0b1..Pass Through Mode is enabled. + */ +#define CMP_MUXCR_PSTM(x) (((uint8_t)(((uint8_t)(x)) << CMP_MUXCR_PSTM_SHIFT)) & CMP_MUXCR_PSTM_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group CMP_Register_Masks */ + + +/* CMP - Peripheral instance base addresses */ +/** Peripheral CMP0 base address */ +#define CMP0_BASE (0x40073000u) +/** Peripheral CMP0 base pointer */ +#define CMP0 ((CMP_Type *)CMP0_BASE) +/** Peripheral CMP1 base address */ +#define CMP1_BASE (0x40073008u) +/** Peripheral CMP1 base pointer */ +#define CMP1 ((CMP_Type *)CMP1_BASE) +/** Peripheral CMP2 base address */ +#define CMP2_BASE (0x40073010u) +/** Peripheral CMP2 base pointer */ +#define CMP2 ((CMP_Type *)CMP2_BASE) +/** Array initializer of CMP peripheral base addresses */ +#define CMP_BASE_ADDRS { CMP0_BASE, CMP1_BASE, CMP2_BASE } +/** Array initializer of CMP peripheral base pointers */ +#define CMP_BASE_PTRS { CMP0, CMP1, CMP2 } +/** Interrupt vectors for the CMP peripheral type */ +#define CMP_IRQS { CMP0_IRQn, CMP1_IRQn, CMP2_IRQn } + +/*! + * @} + */ /* end of group CMP_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- CMT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CMT_Peripheral_Access_Layer CMT Peripheral Access Layer + * @{ + */ + +/** CMT - Register Layout Typedef */ +typedef struct { + __IO uint8_t CGH1; /**< CMT Carrier Generator High Data Register 1, offset: 0x0 */ + __IO uint8_t CGL1; /**< CMT Carrier Generator Low Data Register 1, offset: 0x1 */ + __IO uint8_t CGH2; /**< CMT Carrier Generator High Data Register 2, offset: 0x2 */ + __IO uint8_t CGL2; /**< CMT Carrier Generator Low Data Register 2, offset: 0x3 */ + __IO uint8_t OC; /**< CMT Output Control Register, offset: 0x4 */ + __IO uint8_t MSC; /**< CMT Modulator Status and Control Register, offset: 0x5 */ + __IO uint8_t CMD1; /**< CMT Modulator Data Register Mark High, offset: 0x6 */ + __IO uint8_t CMD2; /**< CMT Modulator Data Register Mark Low, offset: 0x7 */ + __IO uint8_t CMD3; /**< CMT Modulator Data Register Space High, offset: 0x8 */ + __IO uint8_t CMD4; /**< CMT Modulator Data Register Space Low, offset: 0x9 */ + __IO uint8_t PPS; /**< CMT Primary Prescaler Register, offset: 0xA */ + __IO uint8_t DMA; /**< CMT Direct Memory Access Register, offset: 0xB */ +} CMT_Type; + +/* ---------------------------------------------------------------------------- + -- CMT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CMT_Register_Masks CMT Register Masks + * @{ + */ + +/*! @name CGH1 - CMT Carrier Generator High Data Register 1 */ +/*! @{ */ +#define CMT_CGH1_PH_MASK (0xFFU) +#define CMT_CGH1_PH_SHIFT (0U) +#define CMT_CGH1_PH(x) (((uint8_t)(((uint8_t)(x)) << CMT_CGH1_PH_SHIFT)) & CMT_CGH1_PH_MASK) +/*! @} */ + +/*! @name CGL1 - CMT Carrier Generator Low Data Register 1 */ +/*! @{ */ +#define CMT_CGL1_PL_MASK (0xFFU) +#define CMT_CGL1_PL_SHIFT (0U) +#define CMT_CGL1_PL(x) (((uint8_t)(((uint8_t)(x)) << CMT_CGL1_PL_SHIFT)) & CMT_CGL1_PL_MASK) +/*! @} */ + +/*! @name CGH2 - CMT Carrier Generator High Data Register 2 */ +/*! @{ */ +#define CMT_CGH2_SH_MASK (0xFFU) +#define CMT_CGH2_SH_SHIFT (0U) +#define CMT_CGH2_SH(x) (((uint8_t)(((uint8_t)(x)) << CMT_CGH2_SH_SHIFT)) & CMT_CGH2_SH_MASK) +/*! @} */ + +/*! @name CGL2 - CMT Carrier Generator Low Data Register 2 */ +/*! @{ */ +#define CMT_CGL2_SL_MASK (0xFFU) +#define CMT_CGL2_SL_SHIFT (0U) +#define CMT_CGL2_SL(x) (((uint8_t)(((uint8_t)(x)) << CMT_CGL2_SL_SHIFT)) & CMT_CGL2_SL_MASK) +/*! @} */ + +/*! @name OC - CMT Output Control Register */ +/*! @{ */ +#define CMT_OC_IROPEN_MASK (0x20U) +#define CMT_OC_IROPEN_SHIFT (5U) +/*! IROPEN - IRO Pin Enable + * 0b0..The IRO signal is disabled. + * 0b1..The IRO signal is enabled as output. + */ +#define CMT_OC_IROPEN(x) (((uint8_t)(((uint8_t)(x)) << CMT_OC_IROPEN_SHIFT)) & CMT_OC_IROPEN_MASK) +#define CMT_OC_CMTPOL_MASK (0x40U) +#define CMT_OC_CMTPOL_SHIFT (6U) +/*! CMTPOL - CMT Output Polarity + * 0b0..The IRO signal is active-low. + * 0b1..The IRO signal is active-high. + */ +#define CMT_OC_CMTPOL(x) (((uint8_t)(((uint8_t)(x)) << CMT_OC_CMTPOL_SHIFT)) & CMT_OC_CMTPOL_MASK) +#define CMT_OC_IROL_MASK (0x80U) +#define CMT_OC_IROL_SHIFT (7U) +#define CMT_OC_IROL(x) (((uint8_t)(((uint8_t)(x)) << CMT_OC_IROL_SHIFT)) & CMT_OC_IROL_MASK) +/*! @} */ + +/*! @name MSC - CMT Modulator Status and Control Register */ +/*! @{ */ +#define CMT_MSC_MCGEN_MASK (0x1U) +#define CMT_MSC_MCGEN_SHIFT (0U) +/*! MCGEN - Modulator and Carrier Generator Enable + * 0b0..Modulator and carrier generator disabled + * 0b1..Modulator and carrier generator enabled + */ +#define CMT_MSC_MCGEN(x) (((uint8_t)(((uint8_t)(x)) << CMT_MSC_MCGEN_SHIFT)) & CMT_MSC_MCGEN_MASK) +#define CMT_MSC_EOCIE_MASK (0x2U) +#define CMT_MSC_EOCIE_SHIFT (1U) +/*! EOCIE - End of Cycle Interrupt Enable + * 0b0..CPU interrupt is disabled. + * 0b1..CPU interrupt is enabled. + */ +#define CMT_MSC_EOCIE(x) (((uint8_t)(((uint8_t)(x)) << CMT_MSC_EOCIE_SHIFT)) & CMT_MSC_EOCIE_MASK) +#define CMT_MSC_FSK_MASK (0x4U) +#define CMT_MSC_FSK_SHIFT (2U) +/*! FSK - FSK Mode Select + * 0b0..The CMT operates in Time or Baseband mode. + * 0b1..The CMT operates in FSK mode. + */ +#define CMT_MSC_FSK(x) (((uint8_t)(((uint8_t)(x)) << CMT_MSC_FSK_SHIFT)) & CMT_MSC_FSK_MASK) +#define CMT_MSC_BASE_MASK (0x8U) +#define CMT_MSC_BASE_SHIFT (3U) +/*! BASE - Baseband Enable + * 0b0..Baseband mode is disabled. + * 0b1..Baseband mode is enabled. + */ +#define CMT_MSC_BASE(x) (((uint8_t)(((uint8_t)(x)) << CMT_MSC_BASE_SHIFT)) & CMT_MSC_BASE_MASK) +#define CMT_MSC_EXSPC_MASK (0x10U) +#define CMT_MSC_EXSPC_SHIFT (4U) +/*! EXSPC - Extended Space Enable + * 0b0..Extended space is disabled. + * 0b1..Extended space is enabled. + */ +#define CMT_MSC_EXSPC(x) (((uint8_t)(((uint8_t)(x)) << CMT_MSC_EXSPC_SHIFT)) & CMT_MSC_EXSPC_MASK) +#define CMT_MSC_CMTDIV_MASK (0x60U) +#define CMT_MSC_CMTDIV_SHIFT (5U) +/*! CMTDIV - CMT Clock Divide Prescaler + * 0b00..IF * 1 + * 0b01..IF * 2 + * 0b10..IF * 4 + * 0b11..IF * 8 + */ +#define CMT_MSC_CMTDIV(x) (((uint8_t)(((uint8_t)(x)) << CMT_MSC_CMTDIV_SHIFT)) & CMT_MSC_CMTDIV_MASK) +#define CMT_MSC_EOCF_MASK (0x80U) +#define CMT_MSC_EOCF_SHIFT (7U) +/*! EOCF - End Of Cycle Status Flag + * 0b0..End of modulation cycle has not occured since the flag last cleared. + * 0b1..End of modulator cycle has occurred. + */ +#define CMT_MSC_EOCF(x) (((uint8_t)(((uint8_t)(x)) << CMT_MSC_EOCF_SHIFT)) & CMT_MSC_EOCF_MASK) +/*! @} */ + +/*! @name CMD1 - CMT Modulator Data Register Mark High */ +/*! @{ */ +#define CMT_CMD1_MB_MASK (0xFFU) +#define CMT_CMD1_MB_SHIFT (0U) +#define CMT_CMD1_MB(x) (((uint8_t)(((uint8_t)(x)) << CMT_CMD1_MB_SHIFT)) & CMT_CMD1_MB_MASK) +/*! @} */ + +/*! @name CMD2 - CMT Modulator Data Register Mark Low */ +/*! @{ */ +#define CMT_CMD2_MB_MASK (0xFFU) +#define CMT_CMD2_MB_SHIFT (0U) +#define CMT_CMD2_MB(x) (((uint8_t)(((uint8_t)(x)) << CMT_CMD2_MB_SHIFT)) & CMT_CMD2_MB_MASK) +/*! @} */ + +/*! @name CMD3 - CMT Modulator Data Register Space High */ +/*! @{ */ +#define CMT_CMD3_SB_MASK (0xFFU) +#define CMT_CMD3_SB_SHIFT (0U) +#define CMT_CMD3_SB(x) (((uint8_t)(((uint8_t)(x)) << CMT_CMD3_SB_SHIFT)) & CMT_CMD3_SB_MASK) +/*! @} */ + +/*! @name CMD4 - CMT Modulator Data Register Space Low */ +/*! @{ */ +#define CMT_CMD4_SB_MASK (0xFFU) +#define CMT_CMD4_SB_SHIFT (0U) +#define CMT_CMD4_SB(x) (((uint8_t)(((uint8_t)(x)) << CMT_CMD4_SB_SHIFT)) & CMT_CMD4_SB_MASK) +/*! @} */ + +/*! @name PPS - CMT Primary Prescaler Register */ +/*! @{ */ +#define CMT_PPS_PPSDIV_MASK (0xFU) +#define CMT_PPS_PPSDIV_SHIFT (0U) +/*! PPSDIV - Primary Prescaler Divider + * 0b0000..Bus clock * 1 + * 0b0001..Bus clock * 2 + * 0b0010..Bus clock * 3 + * 0b0011..Bus clock * 4 + * 0b0100..Bus clock * 5 + * 0b0101..Bus clock * 6 + * 0b0110..Bus clock * 7 + * 0b0111..Bus clock * 8 + * 0b1000..Bus clock * 9 + * 0b1001..Bus clock * 10 + * 0b1010..Bus clock * 11 + * 0b1011..Bus clock * 12 + * 0b1100..Bus clock * 13 + * 0b1101..Bus clock * 14 + * 0b1110..Bus clock * 15 + * 0b1111..Bus clock * 16 + */ +#define CMT_PPS_PPSDIV(x) (((uint8_t)(((uint8_t)(x)) << CMT_PPS_PPSDIV_SHIFT)) & CMT_PPS_PPSDIV_MASK) +/*! @} */ + +/*! @name DMA - CMT Direct Memory Access Register */ +/*! @{ */ +#define CMT_DMA_DMA_MASK (0x1U) +#define CMT_DMA_DMA_SHIFT (0U) +/*! DMA - DMA Enable + * 0b0..DMA transfer request and done are disabled. + * 0b1..DMA transfer request and done are enabled. + */ +#define CMT_DMA_DMA(x) (((uint8_t)(((uint8_t)(x)) << CMT_DMA_DMA_SHIFT)) & CMT_DMA_DMA_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group CMT_Register_Masks */ + + +/* CMT - Peripheral instance base addresses */ +/** Peripheral CMT base address */ +#define CMT_BASE (0x40062000u) +/** Peripheral CMT base pointer */ +#define CMT ((CMT_Type *)CMT_BASE) +/** Array initializer of CMT peripheral base addresses */ +#define CMT_BASE_ADDRS { CMT_BASE } +/** Array initializer of CMT peripheral base pointers */ +#define CMT_BASE_PTRS { CMT } +/** Interrupt vectors for the CMT peripheral type */ +#define CMT_IRQS { CMT_IRQn } + +/*! + * @} + */ /* end of group CMT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- CRC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CRC_Peripheral_Access_Layer CRC Peripheral Access Layer + * @{ + */ + +/** CRC - Register Layout Typedef */ +typedef struct { + union { /* offset: 0x0 */ + struct { /* offset: 0x0 */ + __IO uint16_t DATAL; /**< CRC_DATAL register., offset: 0x0 */ + __IO uint16_t DATAH; /**< CRC_DATAH register., offset: 0x2 */ + } ACCESS16BIT; + __IO uint32_t DATA; /**< CRC Data register, offset: 0x0 */ + struct { /* offset: 0x0 */ + __IO uint8_t DATALL; /**< CRC_DATALL register., offset: 0x0 */ + __IO uint8_t DATALU; /**< CRC_DATALU register., offset: 0x1 */ + __IO uint8_t DATAHL; /**< CRC_DATAHL register., offset: 0x2 */ + __IO uint8_t DATAHU; /**< CRC_DATAHU register., offset: 0x3 */ + } ACCESS8BIT; + }; + union { /* offset: 0x4 */ + struct { /* offset: 0x4 */ + __IO uint16_t GPOLYL; /**< CRC_GPOLYL register., offset: 0x4 */ + __IO uint16_t GPOLYH; /**< CRC_GPOLYH register., offset: 0x6 */ + } GPOLY_ACCESS16BIT; + __IO uint32_t GPOLY; /**< CRC Polynomial register, offset: 0x4 */ + struct { /* offset: 0x4 */ + __IO uint8_t GPOLYLL; /**< CRC_GPOLYLL register., offset: 0x4 */ + __IO uint8_t GPOLYLU; /**< CRC_GPOLYLU register., offset: 0x5 */ + __IO uint8_t GPOLYHL; /**< CRC_GPOLYHL register., offset: 0x6 */ + __IO uint8_t GPOLYHU; /**< CRC_GPOLYHU register., offset: 0x7 */ + } GPOLY_ACCESS8BIT; + }; + union { /* offset: 0x8 */ + __IO uint32_t CTRL; /**< CRC Control register, offset: 0x8 */ + struct { /* offset: 0x8 */ + uint8_t RESERVED_0[3]; + __IO uint8_t CTRLHU; /**< CRC_CTRLHU register., offset: 0xB */ + } CTRL_ACCESS8BIT; + }; +} CRC_Type; + +/* ---------------------------------------------------------------------------- + -- CRC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CRC_Register_Masks CRC Register Masks + * @{ + */ + +/*! @name DATAL - CRC_DATAL register. */ +/*! @{ */ +#define CRC_DATAL_DATAL_MASK (0xFFFFU) +#define CRC_DATAL_DATAL_SHIFT (0U) +#define CRC_DATAL_DATAL(x) (((uint16_t)(((uint16_t)(x)) << CRC_DATAL_DATAL_SHIFT)) & CRC_DATAL_DATAL_MASK) +/*! @} */ + +/*! @name DATAH - CRC_DATAH register. */ +/*! @{ */ +#define CRC_DATAH_DATAH_MASK (0xFFFFU) +#define CRC_DATAH_DATAH_SHIFT (0U) +#define CRC_DATAH_DATAH(x) (((uint16_t)(((uint16_t)(x)) << CRC_DATAH_DATAH_SHIFT)) & CRC_DATAH_DATAH_MASK) +/*! @} */ + +/*! @name DATA - CRC Data register */ +/*! @{ */ +#define CRC_DATA_LL_MASK (0xFFU) +#define CRC_DATA_LL_SHIFT (0U) +#define CRC_DATA_LL(x) (((uint32_t)(((uint32_t)(x)) << CRC_DATA_LL_SHIFT)) & CRC_DATA_LL_MASK) +#define CRC_DATA_LU_MASK (0xFF00U) +#define CRC_DATA_LU_SHIFT (8U) +#define CRC_DATA_LU(x) (((uint32_t)(((uint32_t)(x)) << CRC_DATA_LU_SHIFT)) & CRC_DATA_LU_MASK) +#define CRC_DATA_HL_MASK (0xFF0000U) +#define CRC_DATA_HL_SHIFT (16U) +#define CRC_DATA_HL(x) (((uint32_t)(((uint32_t)(x)) << CRC_DATA_HL_SHIFT)) & CRC_DATA_HL_MASK) +#define CRC_DATA_HU_MASK (0xFF000000U) +#define CRC_DATA_HU_SHIFT (24U) +#define CRC_DATA_HU(x) (((uint32_t)(((uint32_t)(x)) << CRC_DATA_HU_SHIFT)) & CRC_DATA_HU_MASK) +/*! @} */ + +/*! @name DATALL - CRC_DATALL register. */ +/*! @{ */ +#define CRC_DATALL_DATALL_MASK (0xFFU) +#define CRC_DATALL_DATALL_SHIFT (0U) +#define CRC_DATALL_DATALL(x) (((uint8_t)(((uint8_t)(x)) << CRC_DATALL_DATALL_SHIFT)) & CRC_DATALL_DATALL_MASK) +/*! @} */ + +/*! @name DATALU - CRC_DATALU register. */ +/*! @{ */ +#define CRC_DATALU_DATALU_MASK (0xFFU) +#define CRC_DATALU_DATALU_SHIFT (0U) +#define CRC_DATALU_DATALU(x) (((uint8_t)(((uint8_t)(x)) << CRC_DATALU_DATALU_SHIFT)) & CRC_DATALU_DATALU_MASK) +/*! @} */ + +/*! @name DATAHL - CRC_DATAHL register. */ +/*! @{ */ +#define CRC_DATAHL_DATAHL_MASK (0xFFU) +#define CRC_DATAHL_DATAHL_SHIFT (0U) +#define CRC_DATAHL_DATAHL(x) (((uint8_t)(((uint8_t)(x)) << CRC_DATAHL_DATAHL_SHIFT)) & CRC_DATAHL_DATAHL_MASK) +/*! @} */ + +/*! @name DATAHU - CRC_DATAHU register. */ +/*! @{ */ +#define CRC_DATAHU_DATAHU_MASK (0xFFU) +#define CRC_DATAHU_DATAHU_SHIFT (0U) +#define CRC_DATAHU_DATAHU(x) (((uint8_t)(((uint8_t)(x)) << CRC_DATAHU_DATAHU_SHIFT)) & CRC_DATAHU_DATAHU_MASK) +/*! @} */ + +/*! @name GPOLYL - CRC_GPOLYL register. */ +/*! @{ */ +#define CRC_GPOLYL_GPOLYL_MASK (0xFFFFU) +#define CRC_GPOLYL_GPOLYL_SHIFT (0U) +#define CRC_GPOLYL_GPOLYL(x) (((uint16_t)(((uint16_t)(x)) << CRC_GPOLYL_GPOLYL_SHIFT)) & CRC_GPOLYL_GPOLYL_MASK) +/*! @} */ + +/*! @name GPOLYH - CRC_GPOLYH register. */ +/*! @{ */ +#define CRC_GPOLYH_GPOLYH_MASK (0xFFFFU) +#define CRC_GPOLYH_GPOLYH_SHIFT (0U) +#define CRC_GPOLYH_GPOLYH(x) (((uint16_t)(((uint16_t)(x)) << CRC_GPOLYH_GPOLYH_SHIFT)) & CRC_GPOLYH_GPOLYH_MASK) +/*! @} */ + +/*! @name GPOLY - CRC Polynomial register */ +/*! @{ */ +#define CRC_GPOLY_LOW_MASK (0xFFFFU) +#define CRC_GPOLY_LOW_SHIFT (0U) +#define CRC_GPOLY_LOW(x) (((uint32_t)(((uint32_t)(x)) << CRC_GPOLY_LOW_SHIFT)) & CRC_GPOLY_LOW_MASK) +#define CRC_GPOLY_HIGH_MASK (0xFFFF0000U) +#define CRC_GPOLY_HIGH_SHIFT (16U) +#define CRC_GPOLY_HIGH(x) (((uint32_t)(((uint32_t)(x)) << CRC_GPOLY_HIGH_SHIFT)) & CRC_GPOLY_HIGH_MASK) +/*! @} */ + +/*! @name GPOLYLL - CRC_GPOLYLL register. */ +/*! @{ */ +#define CRC_GPOLYLL_GPOLYLL_MASK (0xFFU) +#define CRC_GPOLYLL_GPOLYLL_SHIFT (0U) +#define CRC_GPOLYLL_GPOLYLL(x) (((uint8_t)(((uint8_t)(x)) << CRC_GPOLYLL_GPOLYLL_SHIFT)) & CRC_GPOLYLL_GPOLYLL_MASK) +/*! @} */ + +/*! @name GPOLYLU - CRC_GPOLYLU register. */ +/*! @{ */ +#define CRC_GPOLYLU_GPOLYLU_MASK (0xFFU) +#define CRC_GPOLYLU_GPOLYLU_SHIFT (0U) +#define CRC_GPOLYLU_GPOLYLU(x) (((uint8_t)(((uint8_t)(x)) << CRC_GPOLYLU_GPOLYLU_SHIFT)) & CRC_GPOLYLU_GPOLYLU_MASK) +/*! @} */ + +/*! @name GPOLYHL - CRC_GPOLYHL register. */ +/*! @{ */ +#define CRC_GPOLYHL_GPOLYHL_MASK (0xFFU) +#define CRC_GPOLYHL_GPOLYHL_SHIFT (0U) +#define CRC_GPOLYHL_GPOLYHL(x) (((uint8_t)(((uint8_t)(x)) << CRC_GPOLYHL_GPOLYHL_SHIFT)) & CRC_GPOLYHL_GPOLYHL_MASK) +/*! @} */ + +/*! @name GPOLYHU - CRC_GPOLYHU register. */ +/*! @{ */ +#define CRC_GPOLYHU_GPOLYHU_MASK (0xFFU) +#define CRC_GPOLYHU_GPOLYHU_SHIFT (0U) +#define CRC_GPOLYHU_GPOLYHU(x) (((uint8_t)(((uint8_t)(x)) << CRC_GPOLYHU_GPOLYHU_SHIFT)) & CRC_GPOLYHU_GPOLYHU_MASK) +/*! @} */ + +/*! @name CTRL - CRC Control register */ +/*! @{ */ +#define CRC_CTRL_TCRC_MASK (0x1000000U) +#define CRC_CTRL_TCRC_SHIFT (24U) +/*! TCRC + * 0b0..16-bit CRC protocol. + * 0b1..32-bit CRC protocol. + */ +#define CRC_CTRL_TCRC(x) (((uint32_t)(((uint32_t)(x)) << CRC_CTRL_TCRC_SHIFT)) & CRC_CTRL_TCRC_MASK) +#define CRC_CTRL_WAS_MASK (0x2000000U) +#define CRC_CTRL_WAS_SHIFT (25U) +/*! WAS - Write CRC Data Register As Seed + * 0b0..Writes to the CRC data register are data values. + * 0b1..Writes to the CRC data register are seed values. + */ +#define CRC_CTRL_WAS(x) (((uint32_t)(((uint32_t)(x)) << CRC_CTRL_WAS_SHIFT)) & CRC_CTRL_WAS_MASK) +#define CRC_CTRL_FXOR_MASK (0x4000000U) +#define CRC_CTRL_FXOR_SHIFT (26U) +/*! FXOR - Complement Read Of CRC Data Register + * 0b0..No XOR on reading. + * 0b1..Invert or complement the read value of the CRC Data register. + */ +#define CRC_CTRL_FXOR(x) (((uint32_t)(((uint32_t)(x)) << CRC_CTRL_FXOR_SHIFT)) & CRC_CTRL_FXOR_MASK) +#define CRC_CTRL_TOTR_MASK (0x30000000U) +#define CRC_CTRL_TOTR_SHIFT (28U) +/*! TOTR - Type Of Transpose For Read + * 0b00..No transposition. + * 0b01..Bits in bytes are transposed; bytes are not transposed. + * 0b10..Both bits in bytes and bytes are transposed. + * 0b11..Only bytes are transposed; no bits in a byte are transposed. + */ +#define CRC_CTRL_TOTR(x) (((uint32_t)(((uint32_t)(x)) << CRC_CTRL_TOTR_SHIFT)) & CRC_CTRL_TOTR_MASK) +#define CRC_CTRL_TOT_MASK (0xC0000000U) +#define CRC_CTRL_TOT_SHIFT (30U) +/*! TOT - Type Of Transpose For Writes + * 0b00..No transposition. + * 0b01..Bits in bytes are transposed; bytes are not transposed. + * 0b10..Both bits in bytes and bytes are transposed. + * 0b11..Only bytes are transposed; no bits in a byte are transposed. + */ +#define CRC_CTRL_TOT(x) (((uint32_t)(((uint32_t)(x)) << CRC_CTRL_TOT_SHIFT)) & CRC_CTRL_TOT_MASK) +/*! @} */ + +/*! @name CTRLHU - CRC_CTRLHU register. */ +/*! @{ */ +#define CRC_CTRLHU_TCRC_MASK (0x1U) +#define CRC_CTRLHU_TCRC_SHIFT (0U) +/*! TCRC + * 0b0..16-bit CRC protocol. + * 0b1..32-bit CRC protocol. + */ +#define CRC_CTRLHU_TCRC(x) (((uint8_t)(((uint8_t)(x)) << CRC_CTRLHU_TCRC_SHIFT)) & CRC_CTRLHU_TCRC_MASK) +#define CRC_CTRLHU_WAS_MASK (0x2U) +#define CRC_CTRLHU_WAS_SHIFT (1U) +/*! WAS + * 0b0..Writes to CRC data register are data values. + * 0b1..Writes to CRC data reguster are seed values. + */ +#define CRC_CTRLHU_WAS(x) (((uint8_t)(((uint8_t)(x)) << CRC_CTRLHU_WAS_SHIFT)) & CRC_CTRLHU_WAS_MASK) +#define CRC_CTRLHU_FXOR_MASK (0x4U) +#define CRC_CTRLHU_FXOR_SHIFT (2U) +/*! FXOR + * 0b0..No XOR on reading. + * 0b1..Invert or complement the read value of CRC data register. + */ +#define CRC_CTRLHU_FXOR(x) (((uint8_t)(((uint8_t)(x)) << CRC_CTRLHU_FXOR_SHIFT)) & CRC_CTRLHU_FXOR_MASK) +#define CRC_CTRLHU_TOTR_MASK (0x30U) +#define CRC_CTRLHU_TOTR_SHIFT (4U) +/*! TOTR + * 0b00..No Transposition. + * 0b01..Bits in bytes are transposed, bytes are not transposed. + * 0b10..Both bits in bytes and bytes are transposed. + * 0b11..Only bytes are transposed; no bits in a byte are transposed. + */ +#define CRC_CTRLHU_TOTR(x) (((uint8_t)(((uint8_t)(x)) << CRC_CTRLHU_TOTR_SHIFT)) & CRC_CTRLHU_TOTR_MASK) +#define CRC_CTRLHU_TOT_MASK (0xC0U) +#define CRC_CTRLHU_TOT_SHIFT (6U) +/*! TOT + * 0b00..No Transposition. + * 0b01..Bits in bytes are transposed, bytes are not transposed. + * 0b10..Both bits in bytes and bytes are transposed. + * 0b11..Only bytes are transposed; no bits in a byte are transposed. + */ +#define CRC_CTRLHU_TOT(x) (((uint8_t)(((uint8_t)(x)) << CRC_CTRLHU_TOT_SHIFT)) & CRC_CTRLHU_TOT_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group CRC_Register_Masks */ + + +/* CRC - Peripheral instance base addresses */ +/** Peripheral CRC base address */ +#define CRC_BASE (0x40032000u) +/** Peripheral CRC base pointer */ +#define CRC0 ((CRC_Type *)CRC_BASE) +/** Array initializer of CRC peripheral base addresses */ +#define CRC_BASE_ADDRS { CRC_BASE } +/** Array initializer of CRC peripheral base pointers */ +#define CRC_BASE_PTRS { CRC0 } + +/*! + * @} + */ /* end of group CRC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- DAC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DAC_Peripheral_Access_Layer DAC Peripheral Access Layer + * @{ + */ + +/** DAC - Register Layout Typedef */ +typedef struct { + struct { /* offset: 0x0, array step: 0x2 */ + __IO uint8_t DATL; /**< DAC Data Low Register, array offset: 0x0, array step: 0x2 */ + __IO uint8_t DATH; /**< DAC Data High Register, array offset: 0x1, array step: 0x2 */ + } DAT[16]; + __IO uint8_t SR; /**< DAC Status Register, offset: 0x20 */ + __IO uint8_t C0; /**< DAC Control Register, offset: 0x21 */ + __IO uint8_t C1; /**< DAC Control Register 1, offset: 0x22 */ + __IO uint8_t C2; /**< DAC Control Register 2, offset: 0x23 */ +} DAC_Type; + +/* ---------------------------------------------------------------------------- + -- DAC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DAC_Register_Masks DAC Register Masks + * @{ + */ + +/*! @name DATL - DAC Data Low Register */ +/*! @{ */ +#define DAC_DATL_DATA0_MASK (0xFFU) +#define DAC_DATL_DATA0_SHIFT (0U) +#define DAC_DATL_DATA0(x) (((uint8_t)(((uint8_t)(x)) << DAC_DATL_DATA0_SHIFT)) & DAC_DATL_DATA0_MASK) +/*! @} */ + +/* The count of DAC_DATL */ +#define DAC_DATL_COUNT (16U) + +/*! @name DATH - DAC Data High Register */ +/*! @{ */ +#define DAC_DATH_DATA1_MASK (0xFU) +#define DAC_DATH_DATA1_SHIFT (0U) +#define DAC_DATH_DATA1(x) (((uint8_t)(((uint8_t)(x)) << DAC_DATH_DATA1_SHIFT)) & DAC_DATH_DATA1_MASK) +/*! @} */ + +/* The count of DAC_DATH */ +#define DAC_DATH_COUNT (16U) + +/*! @name SR - DAC Status Register */ +/*! @{ */ +#define DAC_SR_DACBFRPBF_MASK (0x1U) +#define DAC_SR_DACBFRPBF_SHIFT (0U) +/*! DACBFRPBF - DAC Buffer Read Pointer Bottom Position Flag + * 0b0..The DAC buffer read pointer is not equal to C2[DACBFUP]. + * 0b1..The DAC buffer read pointer is equal to C2[DACBFUP]. + */ +#define DAC_SR_DACBFRPBF(x) (((uint8_t)(((uint8_t)(x)) << DAC_SR_DACBFRPBF_SHIFT)) & DAC_SR_DACBFRPBF_MASK) +#define DAC_SR_DACBFRPTF_MASK (0x2U) +#define DAC_SR_DACBFRPTF_SHIFT (1U) +/*! DACBFRPTF - DAC Buffer Read Pointer Top Position Flag + * 0b0..The DAC buffer read pointer is not zero. + * 0b1..The DAC buffer read pointer is zero. + */ +#define DAC_SR_DACBFRPTF(x) (((uint8_t)(((uint8_t)(x)) << DAC_SR_DACBFRPTF_SHIFT)) & DAC_SR_DACBFRPTF_MASK) +#define DAC_SR_DACBFWMF_MASK (0x4U) +#define DAC_SR_DACBFWMF_SHIFT (2U) +/*! DACBFWMF - DAC Buffer Watermark Flag + * 0b0..The DAC buffer read pointer has not reached the watermark level. + * 0b1..The DAC buffer read pointer has reached the watermark level. + */ +#define DAC_SR_DACBFWMF(x) (((uint8_t)(((uint8_t)(x)) << DAC_SR_DACBFWMF_SHIFT)) & DAC_SR_DACBFWMF_MASK) +/*! @} */ + +/*! @name C0 - DAC Control Register */ +/*! @{ */ +#define DAC_C0_DACBBIEN_MASK (0x1U) +#define DAC_C0_DACBBIEN_SHIFT (0U) +/*! DACBBIEN - DAC Buffer Read Pointer Bottom Flag Interrupt Enable + * 0b0..The DAC buffer read pointer bottom flag interrupt is disabled. + * 0b1..The DAC buffer read pointer bottom flag interrupt is enabled. + */ +#define DAC_C0_DACBBIEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACBBIEN_SHIFT)) & DAC_C0_DACBBIEN_MASK) +#define DAC_C0_DACBTIEN_MASK (0x2U) +#define DAC_C0_DACBTIEN_SHIFT (1U) +/*! DACBTIEN - DAC Buffer Read Pointer Top Flag Interrupt Enable + * 0b0..The DAC buffer read pointer top flag interrupt is disabled. + * 0b1..The DAC buffer read pointer top flag interrupt is enabled. + */ +#define DAC_C0_DACBTIEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACBTIEN_SHIFT)) & DAC_C0_DACBTIEN_MASK) +#define DAC_C0_DACBWIEN_MASK (0x4U) +#define DAC_C0_DACBWIEN_SHIFT (2U) +/*! DACBWIEN - DAC Buffer Watermark Interrupt Enable + * 0b0..The DAC buffer watermark interrupt is disabled. + * 0b1..The DAC buffer watermark interrupt is enabled. + */ +#define DAC_C0_DACBWIEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACBWIEN_SHIFT)) & DAC_C0_DACBWIEN_MASK) +#define DAC_C0_LPEN_MASK (0x8U) +#define DAC_C0_LPEN_SHIFT (3U) +/*! LPEN - DAC Low Power Control + * 0b0..High-Power mode + * 0b1..Low-Power mode + */ +#define DAC_C0_LPEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_LPEN_SHIFT)) & DAC_C0_LPEN_MASK) +#define DAC_C0_DACSWTRG_MASK (0x10U) +#define DAC_C0_DACSWTRG_SHIFT (4U) +/*! DACSWTRG - DAC Software Trigger + * 0b0..The DAC soft trigger is not valid. + * 0b1..The DAC soft trigger is valid. + */ +#define DAC_C0_DACSWTRG(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACSWTRG_SHIFT)) & DAC_C0_DACSWTRG_MASK) +#define DAC_C0_DACTRGSEL_MASK (0x20U) +#define DAC_C0_DACTRGSEL_SHIFT (5U) +/*! DACTRGSEL - DAC Trigger Select + * 0b0..The DAC hardware trigger is selected. + * 0b1..The DAC software trigger is selected. + */ +#define DAC_C0_DACTRGSEL(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACTRGSEL_SHIFT)) & DAC_C0_DACTRGSEL_MASK) +#define DAC_C0_DACRFS_MASK (0x40U) +#define DAC_C0_DACRFS_SHIFT (6U) +/*! DACRFS - DAC Reference Select + * 0b0..The DAC selects DACREF_1 as the reference voltage. + * 0b1..The DAC selects DACREF_2 as the reference voltage. + */ +#define DAC_C0_DACRFS(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACRFS_SHIFT)) & DAC_C0_DACRFS_MASK) +#define DAC_C0_DACEN_MASK (0x80U) +#define DAC_C0_DACEN_SHIFT (7U) +/*! DACEN - DAC Enable + * 0b0..The DAC system is disabled. + * 0b1..The DAC system is enabled. + */ +#define DAC_C0_DACEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C0_DACEN_SHIFT)) & DAC_C0_DACEN_MASK) +/*! @} */ + +/*! @name C1 - DAC Control Register 1 */ +/*! @{ */ +#define DAC_C1_DACBFEN_MASK (0x1U) +#define DAC_C1_DACBFEN_SHIFT (0U) +/*! DACBFEN - DAC Buffer Enable + * 0b0..Buffer read pointer is disabled. The converted data is always the first word of the buffer. + * 0b1..Buffer read pointer is enabled. The converted data is the word that the read pointer points to. It means converted data can be from any word of the buffer. + */ +#define DAC_C1_DACBFEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C1_DACBFEN_SHIFT)) & DAC_C1_DACBFEN_MASK) +#define DAC_C1_DACBFMD_MASK (0x6U) +#define DAC_C1_DACBFMD_SHIFT (1U) +/*! DACBFMD - DAC Buffer Work Mode Select + * 0b00..Normal mode + * 0b01..Swing mode + * 0b10..One-Time Scan mode + * 0b11..Reserved + */ +#define DAC_C1_DACBFMD(x) (((uint8_t)(((uint8_t)(x)) << DAC_C1_DACBFMD_SHIFT)) & DAC_C1_DACBFMD_MASK) +#define DAC_C1_DACBFWM_MASK (0x18U) +#define DAC_C1_DACBFWM_SHIFT (3U) +/*! DACBFWM - DAC Buffer Watermark Select + * 0b00..1 word + * 0b01..2 words + * 0b10..3 words + * 0b11..4 words + */ +#define DAC_C1_DACBFWM(x) (((uint8_t)(((uint8_t)(x)) << DAC_C1_DACBFWM_SHIFT)) & DAC_C1_DACBFWM_MASK) +#define DAC_C1_DMAEN_MASK (0x80U) +#define DAC_C1_DMAEN_SHIFT (7U) +/*! DMAEN - DMA Enable Select + * 0b0..DMA is disabled. + * 0b1..DMA is enabled. When DMA is enabled, the DMA request will be generated by original interrupts. The interrupts will not be presented on this module at the same time. + */ +#define DAC_C1_DMAEN(x) (((uint8_t)(((uint8_t)(x)) << DAC_C1_DMAEN_SHIFT)) & DAC_C1_DMAEN_MASK) +/*! @} */ + +/*! @name C2 - DAC Control Register 2 */ +/*! @{ */ +#define DAC_C2_DACBFUP_MASK (0xFU) +#define DAC_C2_DACBFUP_SHIFT (0U) +#define DAC_C2_DACBFUP(x) (((uint8_t)(((uint8_t)(x)) << DAC_C2_DACBFUP_SHIFT)) & DAC_C2_DACBFUP_MASK) +#define DAC_C2_DACBFRP_MASK (0xF0U) +#define DAC_C2_DACBFRP_SHIFT (4U) +#define DAC_C2_DACBFRP(x) (((uint8_t)(((uint8_t)(x)) << DAC_C2_DACBFRP_SHIFT)) & DAC_C2_DACBFRP_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group DAC_Register_Masks */ + + +/* DAC - Peripheral instance base addresses */ +/** Peripheral DAC0 base address */ +#define DAC0_BASE (0x400CC000u) +/** Peripheral DAC0 base pointer */ +#define DAC0 ((DAC_Type *)DAC0_BASE) +/** Peripheral DAC1 base address */ +#define DAC1_BASE (0x400CD000u) +/** Peripheral DAC1 base pointer */ +#define DAC1 ((DAC_Type *)DAC1_BASE) +/** Array initializer of DAC peripheral base addresses */ +#define DAC_BASE_ADDRS { DAC0_BASE, DAC1_BASE } +/** Array initializer of DAC peripheral base pointers */ +#define DAC_BASE_PTRS { DAC0, DAC1 } +/** Interrupt vectors for the DAC peripheral type */ +#define DAC_IRQS { DAC0_IRQn, DAC1_IRQn } + +/*! + * @} + */ /* end of group DAC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- DMA Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMA_Peripheral_Access_Layer DMA Peripheral Access Layer + * @{ + */ + +/** DMA - Register Layout Typedef */ +typedef struct { + __IO uint32_t CR; /**< Control Register, offset: 0x0 */ + __I uint32_t ES; /**< Error Status Register, offset: 0x4 */ + uint8_t RESERVED_0[4]; + __IO uint32_t ERQ; /**< Enable Request Register, offset: 0xC */ + uint8_t RESERVED_1[4]; + __IO uint32_t EEI; /**< Enable Error Interrupt Register, offset: 0x14 */ + __O uint8_t CEEI; /**< Clear Enable Error Interrupt Register, offset: 0x18 */ + __O uint8_t SEEI; /**< Set Enable Error Interrupt Register, offset: 0x19 */ + __O uint8_t CERQ; /**< Clear Enable Request Register, offset: 0x1A */ + __O uint8_t SERQ; /**< Set Enable Request Register, offset: 0x1B */ + __O uint8_t CDNE; /**< Clear DONE Status Bit Register, offset: 0x1C */ + __O uint8_t SSRT; /**< Set START Bit Register, offset: 0x1D */ + __O uint8_t CERR; /**< Clear Error Register, offset: 0x1E */ + __O uint8_t CINT; /**< Clear Interrupt Request Register, offset: 0x1F */ + uint8_t RESERVED_2[4]; + __IO uint32_t INT; /**< Interrupt Request Register, offset: 0x24 */ + uint8_t RESERVED_3[4]; + __IO uint32_t ERR; /**< Error Register, offset: 0x2C */ + uint8_t RESERVED_4[4]; + __I uint32_t HRS; /**< Hardware Request Status Register, offset: 0x34 */ + uint8_t RESERVED_5[200]; + __IO uint8_t DCHPRI3; /**< Channel n Priority Register, offset: 0x100 */ + __IO uint8_t DCHPRI2; /**< Channel n Priority Register, offset: 0x101 */ + __IO uint8_t DCHPRI1; /**< Channel n Priority Register, offset: 0x102 */ + __IO uint8_t DCHPRI0; /**< Channel n Priority Register, offset: 0x103 */ + __IO uint8_t DCHPRI7; /**< Channel n Priority Register, offset: 0x104 */ + __IO uint8_t DCHPRI6; /**< Channel n Priority Register, offset: 0x105 */ + __IO uint8_t DCHPRI5; /**< Channel n Priority Register, offset: 0x106 */ + __IO uint8_t DCHPRI4; /**< Channel n Priority Register, offset: 0x107 */ + __IO uint8_t DCHPRI11; /**< Channel n Priority Register, offset: 0x108 */ + __IO uint8_t DCHPRI10; /**< Channel n Priority Register, offset: 0x109 */ + __IO uint8_t DCHPRI9; /**< Channel n Priority Register, offset: 0x10A */ + __IO uint8_t DCHPRI8; /**< Channel n Priority Register, offset: 0x10B */ + __IO uint8_t DCHPRI15; /**< Channel n Priority Register, offset: 0x10C */ + __IO uint8_t DCHPRI14; /**< Channel n Priority Register, offset: 0x10D */ + __IO uint8_t DCHPRI13; /**< Channel n Priority Register, offset: 0x10E */ + __IO uint8_t DCHPRI12; /**< Channel n Priority Register, offset: 0x10F */ + uint8_t RESERVED_6[3824]; + struct { /* offset: 0x1000, array step: 0x20 */ + __IO uint32_t SADDR; /**< TCD Source Address, array offset: 0x1000, array step: 0x20 */ + __IO uint16_t SOFF; /**< TCD Signed Source Address Offset, array offset: 0x1004, array step: 0x20 */ + __IO uint16_t ATTR; /**< TCD Transfer Attributes, array offset: 0x1006, array step: 0x20 */ + union { /* offset: 0x1008, array step: 0x20 */ + __IO uint32_t NBYTES_MLNO; /**< TCD Minor Byte Count (Minor Loop Disabled), array offset: 0x1008, array step: 0x20 */ + __IO uint32_t NBYTES_MLOFFNO; /**< TCD Signed Minor Loop Offset (Minor Loop Enabled and Offset Disabled), array offset: 0x1008, array step: 0x20 */ + __IO uint32_t NBYTES_MLOFFYES; /**< TCD Signed Minor Loop Offset (Minor Loop and Offset Enabled), array offset: 0x1008, array step: 0x20 */ + }; + __IO uint32_t SLAST; /**< TCD Last Source Address Adjustment, array offset: 0x100C, array step: 0x20 */ + __IO uint32_t DADDR; /**< TCD Destination Address, array offset: 0x1010, array step: 0x20 */ + __IO uint16_t DOFF; /**< TCD Signed Destination Address Offset, array offset: 0x1014, array step: 0x20 */ + union { /* offset: 0x1016, array step: 0x20 */ + __IO uint16_t CITER_ELINKNO; /**< TCD Current Minor Loop Link, Major Loop Count (Channel Linking Disabled), array offset: 0x1016, array step: 0x20 */ + __IO uint16_t CITER_ELINKYES; /**< TCD Current Minor Loop Link, Major Loop Count (Channel Linking Enabled), array offset: 0x1016, array step: 0x20 */ + }; + __IO uint32_t DLAST_SGA; /**< TCD Last Destination Address Adjustment/Scatter Gather Address, array offset: 0x1018, array step: 0x20 */ + __IO uint16_t CSR; /**< TCD Control and Status, array offset: 0x101C, array step: 0x20 */ + union { /* offset: 0x101E, array step: 0x20 */ + __IO uint16_t BITER_ELINKNO; /**< TCD Beginning Minor Loop Link, Major Loop Count (Channel Linking Disabled), array offset: 0x101E, array step: 0x20 */ + __IO uint16_t BITER_ELINKYES; /**< TCD Beginning Minor Loop Link, Major Loop Count (Channel Linking Enabled), array offset: 0x101E, array step: 0x20 */ + }; + } TCD[16]; +} DMA_Type; + +/* ---------------------------------------------------------------------------- + -- DMA Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMA_Register_Masks DMA Register Masks + * @{ + */ + +/*! @name CR - Control Register */ +/*! @{ */ +#define DMA_CR_EDBG_MASK (0x2U) +#define DMA_CR_EDBG_SHIFT (1U) +/*! EDBG - Enable Debug + * 0b0..When in debug mode, the DMA continues to operate. + * 0b1..When in debug mode, the DMA stalls the start of a new channel. Executing channels are allowed to complete. Channel execution resumes when the system exits debug mode or the EDBG bit is cleared. + */ +#define DMA_CR_EDBG(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_EDBG_SHIFT)) & DMA_CR_EDBG_MASK) +#define DMA_CR_ERCA_MASK (0x4U) +#define DMA_CR_ERCA_SHIFT (2U) +/*! ERCA - Enable Round Robin Channel Arbitration + * 0b0..Fixed priority arbitration is used for channel selection . + * 0b1..Round robin arbitration is used for channel selection . + */ +#define DMA_CR_ERCA(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_ERCA_SHIFT)) & DMA_CR_ERCA_MASK) +#define DMA_CR_HOE_MASK (0x10U) +#define DMA_CR_HOE_SHIFT (4U) +/*! HOE - Halt On Error + * 0b0..Normal operation + * 0b1..Any error causes the HALT bit to set. Subsequently, all service requests are ignored until the HALT bit is cleared. + */ +#define DMA_CR_HOE(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_HOE_SHIFT)) & DMA_CR_HOE_MASK) +#define DMA_CR_HALT_MASK (0x20U) +#define DMA_CR_HALT_SHIFT (5U) +/*! HALT - Halt DMA Operations + * 0b0..Normal operation + * 0b1..Stall the start of any new channels. Executing channels are allowed to complete. Channel execution resumes when this bit is cleared. + */ +#define DMA_CR_HALT(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_HALT_SHIFT)) & DMA_CR_HALT_MASK) +#define DMA_CR_CLM_MASK (0x40U) +#define DMA_CR_CLM_SHIFT (6U) +/*! CLM - Continuous Link Mode + * 0b0..A minor loop channel link made to itself goes through channel arbitration before being activated again. + * 0b1..A minor loop channel link made to itself does not go through channel arbitration before being activated again. Upon minor loop completion, the channel activates again if that channel has a minor loop channel link enabled and the link channel is itself. This effectively applies the minor loop offsets and restarts the next minor loop. + */ +#define DMA_CR_CLM(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_CLM_SHIFT)) & DMA_CR_CLM_MASK) +#define DMA_CR_EMLM_MASK (0x80U) +#define DMA_CR_EMLM_SHIFT (7U) +/*! EMLM - Enable Minor Loop Mapping + * 0b0..Disabled. TCDn.word2 is defined as a 32-bit NBYTES field. + * 0b1..Enabled. TCDn.word2 is redefined to include individual enable fields, an offset field, and the NBYTES field. The individual enable fields allow the minor loop offset to be applied to the source address, the destination address, or both. The NBYTES field is reduced when either offset is enabled. + */ +#define DMA_CR_EMLM(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_EMLM_SHIFT)) & DMA_CR_EMLM_MASK) +#define DMA_CR_ECX_MASK (0x10000U) +#define DMA_CR_ECX_SHIFT (16U) +/*! ECX - Error Cancel Transfer + * 0b0..Normal operation + * 0b1..Cancel the remaining data transfer in the same fashion as the CX bit. Stop the executing channel and force the minor loop to finish. The cancel takes effect after the last write of the current read/write sequence. The ECX bit clears itself after the cancel is honored. In addition to cancelling the transfer, ECX treats the cancel as an error condition, thus updating the Error Status register (DMAx_ES) and generating an optional error interrupt. + */ +#define DMA_CR_ECX(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_ECX_SHIFT)) & DMA_CR_ECX_MASK) +#define DMA_CR_CX_MASK (0x20000U) +#define DMA_CR_CX_SHIFT (17U) +/*! CX - Cancel Transfer + * 0b0..Normal operation + * 0b1..Cancel the remaining data transfer. Stop the executing channel and force the minor loop to finish. The cancel takes effect after the last write of the current read/write sequence. The CX bit clears itself after the cancel has been honored. This cancel retires the channel normally as if the minor loop was completed. + */ +#define DMA_CR_CX(x) (((uint32_t)(((uint32_t)(x)) << DMA_CR_CX_SHIFT)) & DMA_CR_CX_MASK) +/*! @} */ + +/*! @name ES - Error Status Register */ +/*! @{ */ +#define DMA_ES_DBE_MASK (0x1U) +#define DMA_ES_DBE_SHIFT (0U) +/*! DBE - Destination Bus Error + * 0b0..No destination bus error + * 0b1..The last recorded error was a bus error on a destination write + */ +#define DMA_ES_DBE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_DBE_SHIFT)) & DMA_ES_DBE_MASK) +#define DMA_ES_SBE_MASK (0x2U) +#define DMA_ES_SBE_SHIFT (1U) +/*! SBE - Source Bus Error + * 0b0..No source bus error + * 0b1..The last recorded error was a bus error on a source read + */ +#define DMA_ES_SBE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_SBE_SHIFT)) & DMA_ES_SBE_MASK) +#define DMA_ES_SGE_MASK (0x4U) +#define DMA_ES_SGE_SHIFT (2U) +/*! SGE - Scatter/Gather Configuration Error + * 0b0..No scatter/gather configuration error + * 0b1..The last recorded error was a configuration error detected in the TCDn_DLASTSGA field. This field is checked at the beginning of a scatter/gather operation after major loop completion if TCDn_CSR[ESG] is enabled. TCDn_DLASTSGA is not on a 32 byte boundary. + */ +#define DMA_ES_SGE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_SGE_SHIFT)) & DMA_ES_SGE_MASK) +#define DMA_ES_NCE_MASK (0x8U) +#define DMA_ES_NCE_SHIFT (3U) +/*! NCE - NBYTES/CITER Configuration Error + * 0b0..No NBYTES/CITER configuration error + * 0b1..The last recorded error was a configuration error detected in the TCDn_NBYTES or TCDn_CITER fields. TCDn_NBYTES is not a multiple of TCDn_ATTR[SSIZE] and TCDn_ATTR[DSIZE], or TCDn_CITER[CITER] is equal to zero, or TCDn_CITER[ELINK] is not equal to TCDn_BITER[ELINK] + */ +#define DMA_ES_NCE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_NCE_SHIFT)) & DMA_ES_NCE_MASK) +#define DMA_ES_DOE_MASK (0x10U) +#define DMA_ES_DOE_SHIFT (4U) +/*! DOE - Destination Offset Error + * 0b0..No destination offset configuration error + * 0b1..The last recorded error was a configuration error detected in the TCDn_DOFF field. TCDn_DOFF is inconsistent with TCDn_ATTR[DSIZE]. + */ +#define DMA_ES_DOE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_DOE_SHIFT)) & DMA_ES_DOE_MASK) +#define DMA_ES_DAE_MASK (0x20U) +#define DMA_ES_DAE_SHIFT (5U) +/*! DAE - Destination Address Error + * 0b0..No destination address configuration error + * 0b1..The last recorded error was a configuration error detected in the TCDn_DADDR field. TCDn_DADDR is inconsistent with TCDn_ATTR[DSIZE]. + */ +#define DMA_ES_DAE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_DAE_SHIFT)) & DMA_ES_DAE_MASK) +#define DMA_ES_SOE_MASK (0x40U) +#define DMA_ES_SOE_SHIFT (6U) +/*! SOE - Source Offset Error + * 0b0..No source offset configuration error + * 0b1..The last recorded error was a configuration error detected in the TCDn_SOFF field. TCDn_SOFF is inconsistent with TCDn_ATTR[SSIZE]. + */ +#define DMA_ES_SOE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_SOE_SHIFT)) & DMA_ES_SOE_MASK) +#define DMA_ES_SAE_MASK (0x80U) +#define DMA_ES_SAE_SHIFT (7U) +/*! SAE - Source Address Error + * 0b0..No source address configuration error. + * 0b1..The last recorded error was a configuration error detected in the TCDn_SADDR field. TCDn_SADDR is inconsistent with TCDn_ATTR[SSIZE]. + */ +#define DMA_ES_SAE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_SAE_SHIFT)) & DMA_ES_SAE_MASK) +#define DMA_ES_ERRCHN_MASK (0xF00U) +#define DMA_ES_ERRCHN_SHIFT (8U) +#define DMA_ES_ERRCHN(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_ERRCHN_SHIFT)) & DMA_ES_ERRCHN_MASK) +#define DMA_ES_CPE_MASK (0x4000U) +#define DMA_ES_CPE_SHIFT (14U) +/*! CPE - Channel Priority Error + * 0b0..No channel priority error + * 0b1..The last recorded error was a configuration error in the channel priorities . Channel priorities are not unique. + */ +#define DMA_ES_CPE(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_CPE_SHIFT)) & DMA_ES_CPE_MASK) +#define DMA_ES_ECX_MASK (0x10000U) +#define DMA_ES_ECX_SHIFT (16U) +/*! ECX - Transfer Canceled + * 0b0..No canceled transfers + * 0b1..The last recorded entry was a canceled transfer by the error cancel transfer input + */ +#define DMA_ES_ECX(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_ECX_SHIFT)) & DMA_ES_ECX_MASK) +#define DMA_ES_VLD_MASK (0x80000000U) +#define DMA_ES_VLD_SHIFT (31U) +/*! VLD + * 0b0..No ERR bits are set + * 0b1..At least one ERR bit is set indicating a valid error exists that has not been cleared + */ +#define DMA_ES_VLD(x) (((uint32_t)(((uint32_t)(x)) << DMA_ES_VLD_SHIFT)) & DMA_ES_VLD_MASK) +/*! @} */ + +/*! @name ERQ - Enable Request Register */ +/*! @{ */ +#define DMA_ERQ_ERQ0_MASK (0x1U) +#define DMA_ERQ_ERQ0_SHIFT (0U) +/*! ERQ0 - Enable DMA Request 0 + * 0b0..The DMA request signal for the corresponding channel is disabled + * 0b1..The DMA request signal for the corresponding channel is enabled + */ +#define DMA_ERQ_ERQ0(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ0_SHIFT)) & DMA_ERQ_ERQ0_MASK) +#define DMA_ERQ_ERQ1_MASK (0x2U) +#define DMA_ERQ_ERQ1_SHIFT (1U) +/*! ERQ1 - Enable DMA Request 1 + * 0b0..The DMA request signal for the corresponding channel is disabled + * 0b1..The DMA request signal for the corresponding channel is enabled + */ +#define DMA_ERQ_ERQ1(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ1_SHIFT)) & DMA_ERQ_ERQ1_MASK) +#define DMA_ERQ_ERQ2_MASK (0x4U) +#define DMA_ERQ_ERQ2_SHIFT (2U) +/*! ERQ2 - Enable DMA Request 2 + * 0b0..The DMA request signal for the corresponding channel is disabled + * 0b1..The DMA request signal for the corresponding channel is enabled + */ +#define DMA_ERQ_ERQ2(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ2_SHIFT)) & DMA_ERQ_ERQ2_MASK) +#define DMA_ERQ_ERQ3_MASK (0x8U) +#define DMA_ERQ_ERQ3_SHIFT (3U) +/*! ERQ3 - Enable DMA Request 3 + * 0b0..The DMA request signal for the corresponding channel is disabled + * 0b1..The DMA request signal for the corresponding channel is enabled + */ +#define DMA_ERQ_ERQ3(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ3_SHIFT)) & DMA_ERQ_ERQ3_MASK) +#define DMA_ERQ_ERQ4_MASK (0x10U) +#define DMA_ERQ_ERQ4_SHIFT (4U) +/*! ERQ4 - Enable DMA Request 4 + * 0b0..The DMA request signal for the corresponding channel is disabled + * 0b1..The DMA request signal for the corresponding channel is enabled + */ +#define DMA_ERQ_ERQ4(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ4_SHIFT)) & DMA_ERQ_ERQ4_MASK) +#define DMA_ERQ_ERQ5_MASK (0x20U) +#define DMA_ERQ_ERQ5_SHIFT (5U) +/*! ERQ5 - Enable DMA Request 5 + * 0b0..The DMA request signal for the corresponding channel is disabled + * 0b1..The DMA request signal for the corresponding channel is enabled + */ +#define DMA_ERQ_ERQ5(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ5_SHIFT)) & DMA_ERQ_ERQ5_MASK) +#define DMA_ERQ_ERQ6_MASK (0x40U) +#define DMA_ERQ_ERQ6_SHIFT (6U) +/*! ERQ6 - Enable DMA Request 6 + * 0b0..The DMA request signal for the corresponding channel is disabled + * 0b1..The DMA request signal for the corresponding channel is enabled + */ +#define DMA_ERQ_ERQ6(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ6_SHIFT)) & DMA_ERQ_ERQ6_MASK) +#define DMA_ERQ_ERQ7_MASK (0x80U) +#define DMA_ERQ_ERQ7_SHIFT (7U) +/*! ERQ7 - Enable DMA Request 7 + * 0b0..The DMA request signal for the corresponding channel is disabled + * 0b1..The DMA request signal for the corresponding channel is enabled + */ +#define DMA_ERQ_ERQ7(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ7_SHIFT)) & DMA_ERQ_ERQ7_MASK) +#define DMA_ERQ_ERQ8_MASK (0x100U) +#define DMA_ERQ_ERQ8_SHIFT (8U) +/*! ERQ8 - Enable DMA Request 8 + * 0b0..The DMA request signal for the corresponding channel is disabled + * 0b1..The DMA request signal for the corresponding channel is enabled + */ +#define DMA_ERQ_ERQ8(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ8_SHIFT)) & DMA_ERQ_ERQ8_MASK) +#define DMA_ERQ_ERQ9_MASK (0x200U) +#define DMA_ERQ_ERQ9_SHIFT (9U) +/*! ERQ9 - Enable DMA Request 9 + * 0b0..The DMA request signal for the corresponding channel is disabled + * 0b1..The DMA request signal for the corresponding channel is enabled + */ +#define DMA_ERQ_ERQ9(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ9_SHIFT)) & DMA_ERQ_ERQ9_MASK) +#define DMA_ERQ_ERQ10_MASK (0x400U) +#define DMA_ERQ_ERQ10_SHIFT (10U) +/*! ERQ10 - Enable DMA Request 10 + * 0b0..The DMA request signal for the corresponding channel is disabled + * 0b1..The DMA request signal for the corresponding channel is enabled + */ +#define DMA_ERQ_ERQ10(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ10_SHIFT)) & DMA_ERQ_ERQ10_MASK) +#define DMA_ERQ_ERQ11_MASK (0x800U) +#define DMA_ERQ_ERQ11_SHIFT (11U) +/*! ERQ11 - Enable DMA Request 11 + * 0b0..The DMA request signal for the corresponding channel is disabled + * 0b1..The DMA request signal for the corresponding channel is enabled + */ +#define DMA_ERQ_ERQ11(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ11_SHIFT)) & DMA_ERQ_ERQ11_MASK) +#define DMA_ERQ_ERQ12_MASK (0x1000U) +#define DMA_ERQ_ERQ12_SHIFT (12U) +/*! ERQ12 - Enable DMA Request 12 + * 0b0..The DMA request signal for the corresponding channel is disabled + * 0b1..The DMA request signal for the corresponding channel is enabled + */ +#define DMA_ERQ_ERQ12(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ12_SHIFT)) & DMA_ERQ_ERQ12_MASK) +#define DMA_ERQ_ERQ13_MASK (0x2000U) +#define DMA_ERQ_ERQ13_SHIFT (13U) +/*! ERQ13 - Enable DMA Request 13 + * 0b0..The DMA request signal for the corresponding channel is disabled + * 0b1..The DMA request signal for the corresponding channel is enabled + */ +#define DMA_ERQ_ERQ13(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ13_SHIFT)) & DMA_ERQ_ERQ13_MASK) +#define DMA_ERQ_ERQ14_MASK (0x4000U) +#define DMA_ERQ_ERQ14_SHIFT (14U) +/*! ERQ14 - Enable DMA Request 14 + * 0b0..The DMA request signal for the corresponding channel is disabled + * 0b1..The DMA request signal for the corresponding channel is enabled + */ +#define DMA_ERQ_ERQ14(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ14_SHIFT)) & DMA_ERQ_ERQ14_MASK) +#define DMA_ERQ_ERQ15_MASK (0x8000U) +#define DMA_ERQ_ERQ15_SHIFT (15U) +/*! ERQ15 - Enable DMA Request 15 + * 0b0..The DMA request signal for the corresponding channel is disabled + * 0b1..The DMA request signal for the corresponding channel is enabled + */ +#define DMA_ERQ_ERQ15(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERQ_ERQ15_SHIFT)) & DMA_ERQ_ERQ15_MASK) +/*! @} */ + +/*! @name EEI - Enable Error Interrupt Register */ +/*! @{ */ +#define DMA_EEI_EEI0_MASK (0x1U) +#define DMA_EEI_EEI0_SHIFT (0U) +/*! EEI0 - Enable Error Interrupt 0 + * 0b0..The error signal for corresponding channel does not generate an error interrupt + * 0b1..The assertion of the error signal for corresponding channel generates an error interrupt request + */ +#define DMA_EEI_EEI0(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI0_SHIFT)) & DMA_EEI_EEI0_MASK) +#define DMA_EEI_EEI1_MASK (0x2U) +#define DMA_EEI_EEI1_SHIFT (1U) +/*! EEI1 - Enable Error Interrupt 1 + * 0b0..The error signal for corresponding channel does not generate an error interrupt + * 0b1..The assertion of the error signal for corresponding channel generates an error interrupt request + */ +#define DMA_EEI_EEI1(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI1_SHIFT)) & DMA_EEI_EEI1_MASK) +#define DMA_EEI_EEI2_MASK (0x4U) +#define DMA_EEI_EEI2_SHIFT (2U) +/*! EEI2 - Enable Error Interrupt 2 + * 0b0..The error signal for corresponding channel does not generate an error interrupt + * 0b1..The assertion of the error signal for corresponding channel generates an error interrupt request + */ +#define DMA_EEI_EEI2(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI2_SHIFT)) & DMA_EEI_EEI2_MASK) +#define DMA_EEI_EEI3_MASK (0x8U) +#define DMA_EEI_EEI3_SHIFT (3U) +/*! EEI3 - Enable Error Interrupt 3 + * 0b0..The error signal for corresponding channel does not generate an error interrupt + * 0b1..The assertion of the error signal for corresponding channel generates an error interrupt request + */ +#define DMA_EEI_EEI3(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI3_SHIFT)) & DMA_EEI_EEI3_MASK) +#define DMA_EEI_EEI4_MASK (0x10U) +#define DMA_EEI_EEI4_SHIFT (4U) +/*! EEI4 - Enable Error Interrupt 4 + * 0b0..The error signal for corresponding channel does not generate an error interrupt + * 0b1..The assertion of the error signal for corresponding channel generates an error interrupt request + */ +#define DMA_EEI_EEI4(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI4_SHIFT)) & DMA_EEI_EEI4_MASK) +#define DMA_EEI_EEI5_MASK (0x20U) +#define DMA_EEI_EEI5_SHIFT (5U) +/*! EEI5 - Enable Error Interrupt 5 + * 0b0..The error signal for corresponding channel does not generate an error interrupt + * 0b1..The assertion of the error signal for corresponding channel generates an error interrupt request + */ +#define DMA_EEI_EEI5(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI5_SHIFT)) & DMA_EEI_EEI5_MASK) +#define DMA_EEI_EEI6_MASK (0x40U) +#define DMA_EEI_EEI6_SHIFT (6U) +/*! EEI6 - Enable Error Interrupt 6 + * 0b0..The error signal for corresponding channel does not generate an error interrupt + * 0b1..The assertion of the error signal for corresponding channel generates an error interrupt request + */ +#define DMA_EEI_EEI6(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI6_SHIFT)) & DMA_EEI_EEI6_MASK) +#define DMA_EEI_EEI7_MASK (0x80U) +#define DMA_EEI_EEI7_SHIFT (7U) +/*! EEI7 - Enable Error Interrupt 7 + * 0b0..The error signal for corresponding channel does not generate an error interrupt + * 0b1..The assertion of the error signal for corresponding channel generates an error interrupt request + */ +#define DMA_EEI_EEI7(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI7_SHIFT)) & DMA_EEI_EEI7_MASK) +#define DMA_EEI_EEI8_MASK (0x100U) +#define DMA_EEI_EEI8_SHIFT (8U) +/*! EEI8 - Enable Error Interrupt 8 + * 0b0..The error signal for corresponding channel does not generate an error interrupt + * 0b1..The assertion of the error signal for corresponding channel generates an error interrupt request + */ +#define DMA_EEI_EEI8(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI8_SHIFT)) & DMA_EEI_EEI8_MASK) +#define DMA_EEI_EEI9_MASK (0x200U) +#define DMA_EEI_EEI9_SHIFT (9U) +/*! EEI9 - Enable Error Interrupt 9 + * 0b0..The error signal for corresponding channel does not generate an error interrupt + * 0b1..The assertion of the error signal for corresponding channel generates an error interrupt request + */ +#define DMA_EEI_EEI9(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI9_SHIFT)) & DMA_EEI_EEI9_MASK) +#define DMA_EEI_EEI10_MASK (0x400U) +#define DMA_EEI_EEI10_SHIFT (10U) +/*! EEI10 - Enable Error Interrupt 10 + * 0b0..The error signal for corresponding channel does not generate an error interrupt + * 0b1..The assertion of the error signal for corresponding channel generates an error interrupt request + */ +#define DMA_EEI_EEI10(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI10_SHIFT)) & DMA_EEI_EEI10_MASK) +#define DMA_EEI_EEI11_MASK (0x800U) +#define DMA_EEI_EEI11_SHIFT (11U) +/*! EEI11 - Enable Error Interrupt 11 + * 0b0..The error signal for corresponding channel does not generate an error interrupt + * 0b1..The assertion of the error signal for corresponding channel generates an error interrupt request + */ +#define DMA_EEI_EEI11(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI11_SHIFT)) & DMA_EEI_EEI11_MASK) +#define DMA_EEI_EEI12_MASK (0x1000U) +#define DMA_EEI_EEI12_SHIFT (12U) +/*! EEI12 - Enable Error Interrupt 12 + * 0b0..The error signal for corresponding channel does not generate an error interrupt + * 0b1..The assertion of the error signal for corresponding channel generates an error interrupt request + */ +#define DMA_EEI_EEI12(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI12_SHIFT)) & DMA_EEI_EEI12_MASK) +#define DMA_EEI_EEI13_MASK (0x2000U) +#define DMA_EEI_EEI13_SHIFT (13U) +/*! EEI13 - Enable Error Interrupt 13 + * 0b0..The error signal for corresponding channel does not generate an error interrupt + * 0b1..The assertion of the error signal for corresponding channel generates an error interrupt request + */ +#define DMA_EEI_EEI13(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI13_SHIFT)) & DMA_EEI_EEI13_MASK) +#define DMA_EEI_EEI14_MASK (0x4000U) +#define DMA_EEI_EEI14_SHIFT (14U) +/*! EEI14 - Enable Error Interrupt 14 + * 0b0..The error signal for corresponding channel does not generate an error interrupt + * 0b1..The assertion of the error signal for corresponding channel generates an error interrupt request + */ +#define DMA_EEI_EEI14(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI14_SHIFT)) & DMA_EEI_EEI14_MASK) +#define DMA_EEI_EEI15_MASK (0x8000U) +#define DMA_EEI_EEI15_SHIFT (15U) +/*! EEI15 - Enable Error Interrupt 15 + * 0b0..The error signal for corresponding channel does not generate an error interrupt + * 0b1..The assertion of the error signal for corresponding channel generates an error interrupt request + */ +#define DMA_EEI_EEI15(x) (((uint32_t)(((uint32_t)(x)) << DMA_EEI_EEI15_SHIFT)) & DMA_EEI_EEI15_MASK) +/*! @} */ + +/*! @name CEEI - Clear Enable Error Interrupt Register */ +/*! @{ */ +#define DMA_CEEI_CEEI_MASK (0xFU) +#define DMA_CEEI_CEEI_SHIFT (0U) +#define DMA_CEEI_CEEI(x) (((uint8_t)(((uint8_t)(x)) << DMA_CEEI_CEEI_SHIFT)) & DMA_CEEI_CEEI_MASK) +#define DMA_CEEI_CAEE_MASK (0x40U) +#define DMA_CEEI_CAEE_SHIFT (6U) +/*! CAEE - Clear All Enable Error Interrupts + * 0b0..Clear only the EEI bit specified in the CEEI field + * 0b1..Clear all bits in EEI + */ +#define DMA_CEEI_CAEE(x) (((uint8_t)(((uint8_t)(x)) << DMA_CEEI_CAEE_SHIFT)) & DMA_CEEI_CAEE_MASK) +#define DMA_CEEI_NOP_MASK (0x80U) +#define DMA_CEEI_NOP_SHIFT (7U) +/*! NOP - No Op enable + * 0b0..Normal operation + * 0b1..No operation, ignore the other bits in this register + */ +#define DMA_CEEI_NOP(x) (((uint8_t)(((uint8_t)(x)) << DMA_CEEI_NOP_SHIFT)) & DMA_CEEI_NOP_MASK) +/*! @} */ + +/*! @name SEEI - Set Enable Error Interrupt Register */ +/*! @{ */ +#define DMA_SEEI_SEEI_MASK (0xFU) +#define DMA_SEEI_SEEI_SHIFT (0U) +#define DMA_SEEI_SEEI(x) (((uint8_t)(((uint8_t)(x)) << DMA_SEEI_SEEI_SHIFT)) & DMA_SEEI_SEEI_MASK) +#define DMA_SEEI_SAEE_MASK (0x40U) +#define DMA_SEEI_SAEE_SHIFT (6U) +/*! SAEE - Sets All Enable Error Interrupts + * 0b0..Set only the EEI bit specified in the SEEI field. + * 0b1..Sets all bits in EEI + */ +#define DMA_SEEI_SAEE(x) (((uint8_t)(((uint8_t)(x)) << DMA_SEEI_SAEE_SHIFT)) & DMA_SEEI_SAEE_MASK) +#define DMA_SEEI_NOP_MASK (0x80U) +#define DMA_SEEI_NOP_SHIFT (7U) +/*! NOP - No Op enable + * 0b0..Normal operation + * 0b1..No operation, ignore the other bits in this register + */ +#define DMA_SEEI_NOP(x) (((uint8_t)(((uint8_t)(x)) << DMA_SEEI_NOP_SHIFT)) & DMA_SEEI_NOP_MASK) +/*! @} */ + +/*! @name CERQ - Clear Enable Request Register */ +/*! @{ */ +#define DMA_CERQ_CERQ_MASK (0xFU) +#define DMA_CERQ_CERQ_SHIFT (0U) +#define DMA_CERQ_CERQ(x) (((uint8_t)(((uint8_t)(x)) << DMA_CERQ_CERQ_SHIFT)) & DMA_CERQ_CERQ_MASK) +#define DMA_CERQ_CAER_MASK (0x40U) +#define DMA_CERQ_CAER_SHIFT (6U) +/*! CAER - Clear All Enable Requests + * 0b0..Clear only the ERQ bit specified in the CERQ field + * 0b1..Clear all bits in ERQ + */ +#define DMA_CERQ_CAER(x) (((uint8_t)(((uint8_t)(x)) << DMA_CERQ_CAER_SHIFT)) & DMA_CERQ_CAER_MASK) +#define DMA_CERQ_NOP_MASK (0x80U) +#define DMA_CERQ_NOP_SHIFT (7U) +/*! NOP - No Op enable + * 0b0..Normal operation + * 0b1..No operation, ignore the other bits in this register + */ +#define DMA_CERQ_NOP(x) (((uint8_t)(((uint8_t)(x)) << DMA_CERQ_NOP_SHIFT)) & DMA_CERQ_NOP_MASK) +/*! @} */ + +/*! @name SERQ - Set Enable Request Register */ +/*! @{ */ +#define DMA_SERQ_SERQ_MASK (0xFU) +#define DMA_SERQ_SERQ_SHIFT (0U) +#define DMA_SERQ_SERQ(x) (((uint8_t)(((uint8_t)(x)) << DMA_SERQ_SERQ_SHIFT)) & DMA_SERQ_SERQ_MASK) +#define DMA_SERQ_SAER_MASK (0x40U) +#define DMA_SERQ_SAER_SHIFT (6U) +/*! SAER - Set All Enable Requests + * 0b0..Set only the ERQ bit specified in the SERQ field + * 0b1..Set all bits in ERQ + */ +#define DMA_SERQ_SAER(x) (((uint8_t)(((uint8_t)(x)) << DMA_SERQ_SAER_SHIFT)) & DMA_SERQ_SAER_MASK) +#define DMA_SERQ_NOP_MASK (0x80U) +#define DMA_SERQ_NOP_SHIFT (7U) +/*! NOP - No Op enable + * 0b0..Normal operation + * 0b1..No operation, ignore the other bits in this register + */ +#define DMA_SERQ_NOP(x) (((uint8_t)(((uint8_t)(x)) << DMA_SERQ_NOP_SHIFT)) & DMA_SERQ_NOP_MASK) +/*! @} */ + +/*! @name CDNE - Clear DONE Status Bit Register */ +/*! @{ */ +#define DMA_CDNE_CDNE_MASK (0xFU) +#define DMA_CDNE_CDNE_SHIFT (0U) +#define DMA_CDNE_CDNE(x) (((uint8_t)(((uint8_t)(x)) << DMA_CDNE_CDNE_SHIFT)) & DMA_CDNE_CDNE_MASK) +#define DMA_CDNE_CADN_MASK (0x40U) +#define DMA_CDNE_CADN_SHIFT (6U) +/*! CADN - Clears All DONE Bits + * 0b0..Clears only the TCDn_CSR[DONE] bit specified in the CDNE field + * 0b1..Clears all bits in TCDn_CSR[DONE] + */ +#define DMA_CDNE_CADN(x) (((uint8_t)(((uint8_t)(x)) << DMA_CDNE_CADN_SHIFT)) & DMA_CDNE_CADN_MASK) +#define DMA_CDNE_NOP_MASK (0x80U) +#define DMA_CDNE_NOP_SHIFT (7U) +/*! NOP - No Op enable + * 0b0..Normal operation + * 0b1..No operation, ignore the other bits in this register + */ +#define DMA_CDNE_NOP(x) (((uint8_t)(((uint8_t)(x)) << DMA_CDNE_NOP_SHIFT)) & DMA_CDNE_NOP_MASK) +/*! @} */ + +/*! @name SSRT - Set START Bit Register */ +/*! @{ */ +#define DMA_SSRT_SSRT_MASK (0xFU) +#define DMA_SSRT_SSRT_SHIFT (0U) +#define DMA_SSRT_SSRT(x) (((uint8_t)(((uint8_t)(x)) << DMA_SSRT_SSRT_SHIFT)) & DMA_SSRT_SSRT_MASK) +#define DMA_SSRT_SAST_MASK (0x40U) +#define DMA_SSRT_SAST_SHIFT (6U) +/*! SAST - Set All START Bits (activates all channels) + * 0b0..Set only the TCDn_CSR[START] bit specified in the SSRT field + * 0b1..Set all bits in TCDn_CSR[START] + */ +#define DMA_SSRT_SAST(x) (((uint8_t)(((uint8_t)(x)) << DMA_SSRT_SAST_SHIFT)) & DMA_SSRT_SAST_MASK) +#define DMA_SSRT_NOP_MASK (0x80U) +#define DMA_SSRT_NOP_SHIFT (7U) +/*! NOP - No Op enable + * 0b0..Normal operation + * 0b1..No operation, ignore the other bits in this register + */ +#define DMA_SSRT_NOP(x) (((uint8_t)(((uint8_t)(x)) << DMA_SSRT_NOP_SHIFT)) & DMA_SSRT_NOP_MASK) +/*! @} */ + +/*! @name CERR - Clear Error Register */ +/*! @{ */ +#define DMA_CERR_CERR_MASK (0xFU) +#define DMA_CERR_CERR_SHIFT (0U) +#define DMA_CERR_CERR(x) (((uint8_t)(((uint8_t)(x)) << DMA_CERR_CERR_SHIFT)) & DMA_CERR_CERR_MASK) +#define DMA_CERR_CAEI_MASK (0x40U) +#define DMA_CERR_CAEI_SHIFT (6U) +/*! CAEI - Clear All Error Indicators + * 0b0..Clear only the ERR bit specified in the CERR field + * 0b1..Clear all bits in ERR + */ +#define DMA_CERR_CAEI(x) (((uint8_t)(((uint8_t)(x)) << DMA_CERR_CAEI_SHIFT)) & DMA_CERR_CAEI_MASK) +#define DMA_CERR_NOP_MASK (0x80U) +#define DMA_CERR_NOP_SHIFT (7U) +/*! NOP - No Op enable + * 0b0..Normal operation + * 0b1..No operation, ignore the other bits in this register + */ +#define DMA_CERR_NOP(x) (((uint8_t)(((uint8_t)(x)) << DMA_CERR_NOP_SHIFT)) & DMA_CERR_NOP_MASK) +/*! @} */ + +/*! @name CINT - Clear Interrupt Request Register */ +/*! @{ */ +#define DMA_CINT_CINT_MASK (0xFU) +#define DMA_CINT_CINT_SHIFT (0U) +#define DMA_CINT_CINT(x) (((uint8_t)(((uint8_t)(x)) << DMA_CINT_CINT_SHIFT)) & DMA_CINT_CINT_MASK) +#define DMA_CINT_CAIR_MASK (0x40U) +#define DMA_CINT_CAIR_SHIFT (6U) +/*! CAIR - Clear All Interrupt Requests + * 0b0..Clear only the INT bit specified in the CINT field + * 0b1..Clear all bits in INT + */ +#define DMA_CINT_CAIR(x) (((uint8_t)(((uint8_t)(x)) << DMA_CINT_CAIR_SHIFT)) & DMA_CINT_CAIR_MASK) +#define DMA_CINT_NOP_MASK (0x80U) +#define DMA_CINT_NOP_SHIFT (7U) +/*! NOP - No Op enable + * 0b0..Normal operation + * 0b1..No operation, ignore the other bits in this register + */ +#define DMA_CINT_NOP(x) (((uint8_t)(((uint8_t)(x)) << DMA_CINT_NOP_SHIFT)) & DMA_CINT_NOP_MASK) +/*! @} */ + +/*! @name INT - Interrupt Request Register */ +/*! @{ */ +#define DMA_INT_INT0_MASK (0x1U) +#define DMA_INT_INT0_SHIFT (0U) +/*! INT0 - Interrupt Request 0 + * 0b0..The interrupt request for corresponding channel is cleared + * 0b1..The interrupt request for corresponding channel is active + */ +#define DMA_INT_INT0(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT0_SHIFT)) & DMA_INT_INT0_MASK) +#define DMA_INT_INT1_MASK (0x2U) +#define DMA_INT_INT1_SHIFT (1U) +/*! INT1 - Interrupt Request 1 + * 0b0..The interrupt request for corresponding channel is cleared + * 0b1..The interrupt request for corresponding channel is active + */ +#define DMA_INT_INT1(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT1_SHIFT)) & DMA_INT_INT1_MASK) +#define DMA_INT_INT2_MASK (0x4U) +#define DMA_INT_INT2_SHIFT (2U) +/*! INT2 - Interrupt Request 2 + * 0b0..The interrupt request for corresponding channel is cleared + * 0b1..The interrupt request for corresponding channel is active + */ +#define DMA_INT_INT2(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT2_SHIFT)) & DMA_INT_INT2_MASK) +#define DMA_INT_INT3_MASK (0x8U) +#define DMA_INT_INT3_SHIFT (3U) +/*! INT3 - Interrupt Request 3 + * 0b0..The interrupt request for corresponding channel is cleared + * 0b1..The interrupt request for corresponding channel is active + */ +#define DMA_INT_INT3(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT3_SHIFT)) & DMA_INT_INT3_MASK) +#define DMA_INT_INT4_MASK (0x10U) +#define DMA_INT_INT4_SHIFT (4U) +/*! INT4 - Interrupt Request 4 + * 0b0..The interrupt request for corresponding channel is cleared + * 0b1..The interrupt request for corresponding channel is active + */ +#define DMA_INT_INT4(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT4_SHIFT)) & DMA_INT_INT4_MASK) +#define DMA_INT_INT5_MASK (0x20U) +#define DMA_INT_INT5_SHIFT (5U) +/*! INT5 - Interrupt Request 5 + * 0b0..The interrupt request for corresponding channel is cleared + * 0b1..The interrupt request for corresponding channel is active + */ +#define DMA_INT_INT5(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT5_SHIFT)) & DMA_INT_INT5_MASK) +#define DMA_INT_INT6_MASK (0x40U) +#define DMA_INT_INT6_SHIFT (6U) +/*! INT6 - Interrupt Request 6 + * 0b0..The interrupt request for corresponding channel is cleared + * 0b1..The interrupt request for corresponding channel is active + */ +#define DMA_INT_INT6(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT6_SHIFT)) & DMA_INT_INT6_MASK) +#define DMA_INT_INT7_MASK (0x80U) +#define DMA_INT_INT7_SHIFT (7U) +/*! INT7 - Interrupt Request 7 + * 0b0..The interrupt request for corresponding channel is cleared + * 0b1..The interrupt request for corresponding channel is active + */ +#define DMA_INT_INT7(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT7_SHIFT)) & DMA_INT_INT7_MASK) +#define DMA_INT_INT8_MASK (0x100U) +#define DMA_INT_INT8_SHIFT (8U) +/*! INT8 - Interrupt Request 8 + * 0b0..The interrupt request for corresponding channel is cleared + * 0b1..The interrupt request for corresponding channel is active + */ +#define DMA_INT_INT8(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT8_SHIFT)) & DMA_INT_INT8_MASK) +#define DMA_INT_INT9_MASK (0x200U) +#define DMA_INT_INT9_SHIFT (9U) +/*! INT9 - Interrupt Request 9 + * 0b0..The interrupt request for corresponding channel is cleared + * 0b1..The interrupt request for corresponding channel is active + */ +#define DMA_INT_INT9(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT9_SHIFT)) & DMA_INT_INT9_MASK) +#define DMA_INT_INT10_MASK (0x400U) +#define DMA_INT_INT10_SHIFT (10U) +/*! INT10 - Interrupt Request 10 + * 0b0..The interrupt request for corresponding channel is cleared + * 0b1..The interrupt request for corresponding channel is active + */ +#define DMA_INT_INT10(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT10_SHIFT)) & DMA_INT_INT10_MASK) +#define DMA_INT_INT11_MASK (0x800U) +#define DMA_INT_INT11_SHIFT (11U) +/*! INT11 - Interrupt Request 11 + * 0b0..The interrupt request for corresponding channel is cleared + * 0b1..The interrupt request for corresponding channel is active + */ +#define DMA_INT_INT11(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT11_SHIFT)) & DMA_INT_INT11_MASK) +#define DMA_INT_INT12_MASK (0x1000U) +#define DMA_INT_INT12_SHIFT (12U) +/*! INT12 - Interrupt Request 12 + * 0b0..The interrupt request for corresponding channel is cleared + * 0b1..The interrupt request for corresponding channel is active + */ +#define DMA_INT_INT12(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT12_SHIFT)) & DMA_INT_INT12_MASK) +#define DMA_INT_INT13_MASK (0x2000U) +#define DMA_INT_INT13_SHIFT (13U) +/*! INT13 - Interrupt Request 13 + * 0b0..The interrupt request for corresponding channel is cleared + * 0b1..The interrupt request for corresponding channel is active + */ +#define DMA_INT_INT13(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT13_SHIFT)) & DMA_INT_INT13_MASK) +#define DMA_INT_INT14_MASK (0x4000U) +#define DMA_INT_INT14_SHIFT (14U) +/*! INT14 - Interrupt Request 14 + * 0b0..The interrupt request for corresponding channel is cleared + * 0b1..The interrupt request for corresponding channel is active + */ +#define DMA_INT_INT14(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT14_SHIFT)) & DMA_INT_INT14_MASK) +#define DMA_INT_INT15_MASK (0x8000U) +#define DMA_INT_INT15_SHIFT (15U) +/*! INT15 - Interrupt Request 15 + * 0b0..The interrupt request for corresponding channel is cleared + * 0b1..The interrupt request for corresponding channel is active + */ +#define DMA_INT_INT15(x) (((uint32_t)(((uint32_t)(x)) << DMA_INT_INT15_SHIFT)) & DMA_INT_INT15_MASK) +/*! @} */ + +/*! @name ERR - Error Register */ +/*! @{ */ +#define DMA_ERR_ERR0_MASK (0x1U) +#define DMA_ERR_ERR0_SHIFT (0U) +/*! ERR0 - Error In Channel 0 + * 0b0..An error in the corresponding channel has not occurred + * 0b1..An error in the corresponding channel has occurred + */ +#define DMA_ERR_ERR0(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR0_SHIFT)) & DMA_ERR_ERR0_MASK) +#define DMA_ERR_ERR1_MASK (0x2U) +#define DMA_ERR_ERR1_SHIFT (1U) +/*! ERR1 - Error In Channel 1 + * 0b0..An error in the corresponding channel has not occurred + * 0b1..An error in the corresponding channel has occurred + */ +#define DMA_ERR_ERR1(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR1_SHIFT)) & DMA_ERR_ERR1_MASK) +#define DMA_ERR_ERR2_MASK (0x4U) +#define DMA_ERR_ERR2_SHIFT (2U) +/*! ERR2 - Error In Channel 2 + * 0b0..An error in the corresponding channel has not occurred + * 0b1..An error in the corresponding channel has occurred + */ +#define DMA_ERR_ERR2(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR2_SHIFT)) & DMA_ERR_ERR2_MASK) +#define DMA_ERR_ERR3_MASK (0x8U) +#define DMA_ERR_ERR3_SHIFT (3U) +/*! ERR3 - Error In Channel 3 + * 0b0..An error in the corresponding channel has not occurred + * 0b1..An error in the corresponding channel has occurred + */ +#define DMA_ERR_ERR3(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR3_SHIFT)) & DMA_ERR_ERR3_MASK) +#define DMA_ERR_ERR4_MASK (0x10U) +#define DMA_ERR_ERR4_SHIFT (4U) +/*! ERR4 - Error In Channel 4 + * 0b0..An error in the corresponding channel has not occurred + * 0b1..An error in the corresponding channel has occurred + */ +#define DMA_ERR_ERR4(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR4_SHIFT)) & DMA_ERR_ERR4_MASK) +#define DMA_ERR_ERR5_MASK (0x20U) +#define DMA_ERR_ERR5_SHIFT (5U) +/*! ERR5 - Error In Channel 5 + * 0b0..An error in the corresponding channel has not occurred + * 0b1..An error in the corresponding channel has occurred + */ +#define DMA_ERR_ERR5(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR5_SHIFT)) & DMA_ERR_ERR5_MASK) +#define DMA_ERR_ERR6_MASK (0x40U) +#define DMA_ERR_ERR6_SHIFT (6U) +/*! ERR6 - Error In Channel 6 + * 0b0..An error in the corresponding channel has not occurred + * 0b1..An error in the corresponding channel has occurred + */ +#define DMA_ERR_ERR6(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR6_SHIFT)) & DMA_ERR_ERR6_MASK) +#define DMA_ERR_ERR7_MASK (0x80U) +#define DMA_ERR_ERR7_SHIFT (7U) +/*! ERR7 - Error In Channel 7 + * 0b0..An error in the corresponding channel has not occurred + * 0b1..An error in the corresponding channel has occurred + */ +#define DMA_ERR_ERR7(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR7_SHIFT)) & DMA_ERR_ERR7_MASK) +#define DMA_ERR_ERR8_MASK (0x100U) +#define DMA_ERR_ERR8_SHIFT (8U) +/*! ERR8 - Error In Channel 8 + * 0b0..An error in the corresponding channel has not occurred + * 0b1..An error in the corresponding channel has occurred + */ +#define DMA_ERR_ERR8(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR8_SHIFT)) & DMA_ERR_ERR8_MASK) +#define DMA_ERR_ERR9_MASK (0x200U) +#define DMA_ERR_ERR9_SHIFT (9U) +/*! ERR9 - Error In Channel 9 + * 0b0..An error in the corresponding channel has not occurred + * 0b1..An error in the corresponding channel has occurred + */ +#define DMA_ERR_ERR9(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR9_SHIFT)) & DMA_ERR_ERR9_MASK) +#define DMA_ERR_ERR10_MASK (0x400U) +#define DMA_ERR_ERR10_SHIFT (10U) +/*! ERR10 - Error In Channel 10 + * 0b0..An error in the corresponding channel has not occurred + * 0b1..An error in the corresponding channel has occurred + */ +#define DMA_ERR_ERR10(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR10_SHIFT)) & DMA_ERR_ERR10_MASK) +#define DMA_ERR_ERR11_MASK (0x800U) +#define DMA_ERR_ERR11_SHIFT (11U) +/*! ERR11 - Error In Channel 11 + * 0b0..An error in the corresponding channel has not occurred + * 0b1..An error in the corresponding channel has occurred + */ +#define DMA_ERR_ERR11(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR11_SHIFT)) & DMA_ERR_ERR11_MASK) +#define DMA_ERR_ERR12_MASK (0x1000U) +#define DMA_ERR_ERR12_SHIFT (12U) +/*! ERR12 - Error In Channel 12 + * 0b0..An error in the corresponding channel has not occurred + * 0b1..An error in the corresponding channel has occurred + */ +#define DMA_ERR_ERR12(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR12_SHIFT)) & DMA_ERR_ERR12_MASK) +#define DMA_ERR_ERR13_MASK (0x2000U) +#define DMA_ERR_ERR13_SHIFT (13U) +/*! ERR13 - Error In Channel 13 + * 0b0..An error in the corresponding channel has not occurred + * 0b1..An error in the corresponding channel has occurred + */ +#define DMA_ERR_ERR13(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR13_SHIFT)) & DMA_ERR_ERR13_MASK) +#define DMA_ERR_ERR14_MASK (0x4000U) +#define DMA_ERR_ERR14_SHIFT (14U) +/*! ERR14 - Error In Channel 14 + * 0b0..An error in the corresponding channel has not occurred + * 0b1..An error in the corresponding channel has occurred + */ +#define DMA_ERR_ERR14(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR14_SHIFT)) & DMA_ERR_ERR14_MASK) +#define DMA_ERR_ERR15_MASK (0x8000U) +#define DMA_ERR_ERR15_SHIFT (15U) +/*! ERR15 - Error In Channel 15 + * 0b0..An error in the corresponding channel has not occurred + * 0b1..An error in the corresponding channel has occurred + */ +#define DMA_ERR_ERR15(x) (((uint32_t)(((uint32_t)(x)) << DMA_ERR_ERR15_SHIFT)) & DMA_ERR_ERR15_MASK) +/*! @} */ + +/*! @name HRS - Hardware Request Status Register */ +/*! @{ */ +#define DMA_HRS_HRS0_MASK (0x1U) +#define DMA_HRS_HRS0_SHIFT (0U) +/*! HRS0 - Hardware Request Status Channel 0 + * 0b0..A hardware service request for channel 0 is not present + * 0b1..A hardware service request for channel 0 is present + */ +#define DMA_HRS_HRS0(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS0_SHIFT)) & DMA_HRS_HRS0_MASK) +#define DMA_HRS_HRS1_MASK (0x2U) +#define DMA_HRS_HRS1_SHIFT (1U) +/*! HRS1 - Hardware Request Status Channel 1 + * 0b0..A hardware service request for channel 1 is not present + * 0b1..A hardware service request for channel 1 is present + */ +#define DMA_HRS_HRS1(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS1_SHIFT)) & DMA_HRS_HRS1_MASK) +#define DMA_HRS_HRS2_MASK (0x4U) +#define DMA_HRS_HRS2_SHIFT (2U) +/*! HRS2 - Hardware Request Status Channel 2 + * 0b0..A hardware service request for channel 2 is not present + * 0b1..A hardware service request for channel 2 is present + */ +#define DMA_HRS_HRS2(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS2_SHIFT)) & DMA_HRS_HRS2_MASK) +#define DMA_HRS_HRS3_MASK (0x8U) +#define DMA_HRS_HRS3_SHIFT (3U) +/*! HRS3 - Hardware Request Status Channel 3 + * 0b0..A hardware service request for channel 3 is not present + * 0b1..A hardware service request for channel 3 is present + */ +#define DMA_HRS_HRS3(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS3_SHIFT)) & DMA_HRS_HRS3_MASK) +#define DMA_HRS_HRS4_MASK (0x10U) +#define DMA_HRS_HRS4_SHIFT (4U) +/*! HRS4 - Hardware Request Status Channel 4 + * 0b0..A hardware service request for channel 4 is not present + * 0b1..A hardware service request for channel 4 is present + */ +#define DMA_HRS_HRS4(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS4_SHIFT)) & DMA_HRS_HRS4_MASK) +#define DMA_HRS_HRS5_MASK (0x20U) +#define DMA_HRS_HRS5_SHIFT (5U) +/*! HRS5 - Hardware Request Status Channel 5 + * 0b0..A hardware service request for channel 5 is not present + * 0b1..A hardware service request for channel 5 is present + */ +#define DMA_HRS_HRS5(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS5_SHIFT)) & DMA_HRS_HRS5_MASK) +#define DMA_HRS_HRS6_MASK (0x40U) +#define DMA_HRS_HRS6_SHIFT (6U) +/*! HRS6 - Hardware Request Status Channel 6 + * 0b0..A hardware service request for channel 6 is not present + * 0b1..A hardware service request for channel 6 is present + */ +#define DMA_HRS_HRS6(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS6_SHIFT)) & DMA_HRS_HRS6_MASK) +#define DMA_HRS_HRS7_MASK (0x80U) +#define DMA_HRS_HRS7_SHIFT (7U) +/*! HRS7 - Hardware Request Status Channel 7 + * 0b0..A hardware service request for channel 7 is not present + * 0b1..A hardware service request for channel 7 is present + */ +#define DMA_HRS_HRS7(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS7_SHIFT)) & DMA_HRS_HRS7_MASK) +#define DMA_HRS_HRS8_MASK (0x100U) +#define DMA_HRS_HRS8_SHIFT (8U) +/*! HRS8 - Hardware Request Status Channel 8 + * 0b0..A hardware service request for channel 8 is not present + * 0b1..A hardware service request for channel 8 is present + */ +#define DMA_HRS_HRS8(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS8_SHIFT)) & DMA_HRS_HRS8_MASK) +#define DMA_HRS_HRS9_MASK (0x200U) +#define DMA_HRS_HRS9_SHIFT (9U) +/*! HRS9 - Hardware Request Status Channel 9 + * 0b0..A hardware service request for channel 9 is not present + * 0b1..A hardware service request for channel 9 is present + */ +#define DMA_HRS_HRS9(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS9_SHIFT)) & DMA_HRS_HRS9_MASK) +#define DMA_HRS_HRS10_MASK (0x400U) +#define DMA_HRS_HRS10_SHIFT (10U) +/*! HRS10 - Hardware Request Status Channel 10 + * 0b0..A hardware service request for channel 10 is not present + * 0b1..A hardware service request for channel 10 is present + */ +#define DMA_HRS_HRS10(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS10_SHIFT)) & DMA_HRS_HRS10_MASK) +#define DMA_HRS_HRS11_MASK (0x800U) +#define DMA_HRS_HRS11_SHIFT (11U) +/*! HRS11 - Hardware Request Status Channel 11 + * 0b0..A hardware service request for channel 11 is not present + * 0b1..A hardware service request for channel 11 is present + */ +#define DMA_HRS_HRS11(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS11_SHIFT)) & DMA_HRS_HRS11_MASK) +#define DMA_HRS_HRS12_MASK (0x1000U) +#define DMA_HRS_HRS12_SHIFT (12U) +/*! HRS12 - Hardware Request Status Channel 12 + * 0b0..A hardware service request for channel 12 is not present + * 0b1..A hardware service request for channel 12 is present + */ +#define DMA_HRS_HRS12(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS12_SHIFT)) & DMA_HRS_HRS12_MASK) +#define DMA_HRS_HRS13_MASK (0x2000U) +#define DMA_HRS_HRS13_SHIFT (13U) +/*! HRS13 - Hardware Request Status Channel 13 + * 0b0..A hardware service request for channel 13 is not present + * 0b1..A hardware service request for channel 13 is present + */ +#define DMA_HRS_HRS13(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS13_SHIFT)) & DMA_HRS_HRS13_MASK) +#define DMA_HRS_HRS14_MASK (0x4000U) +#define DMA_HRS_HRS14_SHIFT (14U) +/*! HRS14 - Hardware Request Status Channel 14 + * 0b0..A hardware service request for channel 14 is not present + * 0b1..A hardware service request for channel 14 is present + */ +#define DMA_HRS_HRS14(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS14_SHIFT)) & DMA_HRS_HRS14_MASK) +#define DMA_HRS_HRS15_MASK (0x8000U) +#define DMA_HRS_HRS15_SHIFT (15U) +/*! HRS15 - Hardware Request Status Channel 15 + * 0b0..A hardware service request for channel 15 is not present + * 0b1..A hardware service request for channel 15 is present + */ +#define DMA_HRS_HRS15(x) (((uint32_t)(((uint32_t)(x)) << DMA_HRS_HRS15_SHIFT)) & DMA_HRS_HRS15_MASK) +/*! @} */ + +/*! @name DCHPRI3 - Channel n Priority Register */ +/*! @{ */ +#define DMA_DCHPRI3_CHPRI_MASK (0xFU) +#define DMA_DCHPRI3_CHPRI_SHIFT (0U) +#define DMA_DCHPRI3_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI3_CHPRI_SHIFT)) & DMA_DCHPRI3_CHPRI_MASK) +#define DMA_DCHPRI3_DPA_MASK (0x40U) +#define DMA_DCHPRI3_DPA_SHIFT (6U) +/*! DPA - Disable Preempt Ability + * 0b0..Channel n can suspend a lower priority channel + * 0b1..Channel n cannot suspend any channel, regardless of channel priority + */ +#define DMA_DCHPRI3_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI3_DPA_SHIFT)) & DMA_DCHPRI3_DPA_MASK) +#define DMA_DCHPRI3_ECP_MASK (0x80U) +#define DMA_DCHPRI3_ECP_SHIFT (7U) +/*! ECP - Enable Channel Preemption + * 0b0..Channel n cannot be suspended by a higher priority channel's service request + * 0b1..Channel n can be temporarily suspended by the service request of a higher priority channel + */ +#define DMA_DCHPRI3_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI3_ECP_SHIFT)) & DMA_DCHPRI3_ECP_MASK) +/*! @} */ + +/*! @name DCHPRI2 - Channel n Priority Register */ +/*! @{ */ +#define DMA_DCHPRI2_CHPRI_MASK (0xFU) +#define DMA_DCHPRI2_CHPRI_SHIFT (0U) +#define DMA_DCHPRI2_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI2_CHPRI_SHIFT)) & DMA_DCHPRI2_CHPRI_MASK) +#define DMA_DCHPRI2_DPA_MASK (0x40U) +#define DMA_DCHPRI2_DPA_SHIFT (6U) +/*! DPA - Disable Preempt Ability + * 0b0..Channel n can suspend a lower priority channel + * 0b1..Channel n cannot suspend any channel, regardless of channel priority + */ +#define DMA_DCHPRI2_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI2_DPA_SHIFT)) & DMA_DCHPRI2_DPA_MASK) +#define DMA_DCHPRI2_ECP_MASK (0x80U) +#define DMA_DCHPRI2_ECP_SHIFT (7U) +/*! ECP - Enable Channel Preemption + * 0b0..Channel n cannot be suspended by a higher priority channel's service request + * 0b1..Channel n can be temporarily suspended by the service request of a higher priority channel + */ +#define DMA_DCHPRI2_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI2_ECP_SHIFT)) & DMA_DCHPRI2_ECP_MASK) +/*! @} */ + +/*! @name DCHPRI1 - Channel n Priority Register */ +/*! @{ */ +#define DMA_DCHPRI1_CHPRI_MASK (0xFU) +#define DMA_DCHPRI1_CHPRI_SHIFT (0U) +#define DMA_DCHPRI1_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI1_CHPRI_SHIFT)) & DMA_DCHPRI1_CHPRI_MASK) +#define DMA_DCHPRI1_DPA_MASK (0x40U) +#define DMA_DCHPRI1_DPA_SHIFT (6U) +/*! DPA - Disable Preempt Ability + * 0b0..Channel n can suspend a lower priority channel + * 0b1..Channel n cannot suspend any channel, regardless of channel priority + */ +#define DMA_DCHPRI1_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI1_DPA_SHIFT)) & DMA_DCHPRI1_DPA_MASK) +#define DMA_DCHPRI1_ECP_MASK (0x80U) +#define DMA_DCHPRI1_ECP_SHIFT (7U) +/*! ECP - Enable Channel Preemption + * 0b0..Channel n cannot be suspended by a higher priority channel's service request + * 0b1..Channel n can be temporarily suspended by the service request of a higher priority channel + */ +#define DMA_DCHPRI1_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI1_ECP_SHIFT)) & DMA_DCHPRI1_ECP_MASK) +/*! @} */ + +/*! @name DCHPRI0 - Channel n Priority Register */ +/*! @{ */ +#define DMA_DCHPRI0_CHPRI_MASK (0xFU) +#define DMA_DCHPRI0_CHPRI_SHIFT (0U) +#define DMA_DCHPRI0_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI0_CHPRI_SHIFT)) & DMA_DCHPRI0_CHPRI_MASK) +#define DMA_DCHPRI0_DPA_MASK (0x40U) +#define DMA_DCHPRI0_DPA_SHIFT (6U) +/*! DPA - Disable Preempt Ability + * 0b0..Channel n can suspend a lower priority channel + * 0b1..Channel n cannot suspend any channel, regardless of channel priority + */ +#define DMA_DCHPRI0_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI0_DPA_SHIFT)) & DMA_DCHPRI0_DPA_MASK) +#define DMA_DCHPRI0_ECP_MASK (0x80U) +#define DMA_DCHPRI0_ECP_SHIFT (7U) +/*! ECP - Enable Channel Preemption + * 0b0..Channel n cannot be suspended by a higher priority channel's service request + * 0b1..Channel n can be temporarily suspended by the service request of a higher priority channel + */ +#define DMA_DCHPRI0_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI0_ECP_SHIFT)) & DMA_DCHPRI0_ECP_MASK) +/*! @} */ + +/*! @name DCHPRI7 - Channel n Priority Register */ +/*! @{ */ +#define DMA_DCHPRI7_CHPRI_MASK (0xFU) +#define DMA_DCHPRI7_CHPRI_SHIFT (0U) +#define DMA_DCHPRI7_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI7_CHPRI_SHIFT)) & DMA_DCHPRI7_CHPRI_MASK) +#define DMA_DCHPRI7_DPA_MASK (0x40U) +#define DMA_DCHPRI7_DPA_SHIFT (6U) +/*! DPA - Disable Preempt Ability + * 0b0..Channel n can suspend a lower priority channel + * 0b1..Channel n cannot suspend any channel, regardless of channel priority + */ +#define DMA_DCHPRI7_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI7_DPA_SHIFT)) & DMA_DCHPRI7_DPA_MASK) +#define DMA_DCHPRI7_ECP_MASK (0x80U) +#define DMA_DCHPRI7_ECP_SHIFT (7U) +/*! ECP - Enable Channel Preemption + * 0b0..Channel n cannot be suspended by a higher priority channel's service request + * 0b1..Channel n can be temporarily suspended by the service request of a higher priority channel + */ +#define DMA_DCHPRI7_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI7_ECP_SHIFT)) & DMA_DCHPRI7_ECP_MASK) +/*! @} */ + +/*! @name DCHPRI6 - Channel n Priority Register */ +/*! @{ */ +#define DMA_DCHPRI6_CHPRI_MASK (0xFU) +#define DMA_DCHPRI6_CHPRI_SHIFT (0U) +#define DMA_DCHPRI6_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI6_CHPRI_SHIFT)) & DMA_DCHPRI6_CHPRI_MASK) +#define DMA_DCHPRI6_DPA_MASK (0x40U) +#define DMA_DCHPRI6_DPA_SHIFT (6U) +/*! DPA - Disable Preempt Ability + * 0b0..Channel n can suspend a lower priority channel + * 0b1..Channel n cannot suspend any channel, regardless of channel priority + */ +#define DMA_DCHPRI6_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI6_DPA_SHIFT)) & DMA_DCHPRI6_DPA_MASK) +#define DMA_DCHPRI6_ECP_MASK (0x80U) +#define DMA_DCHPRI6_ECP_SHIFT (7U) +/*! ECP - Enable Channel Preemption + * 0b0..Channel n cannot be suspended by a higher priority channel's service request + * 0b1..Channel n can be temporarily suspended by the service request of a higher priority channel + */ +#define DMA_DCHPRI6_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI6_ECP_SHIFT)) & DMA_DCHPRI6_ECP_MASK) +/*! @} */ + +/*! @name DCHPRI5 - Channel n Priority Register */ +/*! @{ */ +#define DMA_DCHPRI5_CHPRI_MASK (0xFU) +#define DMA_DCHPRI5_CHPRI_SHIFT (0U) +#define DMA_DCHPRI5_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI5_CHPRI_SHIFT)) & DMA_DCHPRI5_CHPRI_MASK) +#define DMA_DCHPRI5_DPA_MASK (0x40U) +#define DMA_DCHPRI5_DPA_SHIFT (6U) +/*! DPA - Disable Preempt Ability + * 0b0..Channel n can suspend a lower priority channel + * 0b1..Channel n cannot suspend any channel, regardless of channel priority + */ +#define DMA_DCHPRI5_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI5_DPA_SHIFT)) & DMA_DCHPRI5_DPA_MASK) +#define DMA_DCHPRI5_ECP_MASK (0x80U) +#define DMA_DCHPRI5_ECP_SHIFT (7U) +/*! ECP - Enable Channel Preemption + * 0b0..Channel n cannot be suspended by a higher priority channel's service request + * 0b1..Channel n can be temporarily suspended by the service request of a higher priority channel + */ +#define DMA_DCHPRI5_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI5_ECP_SHIFT)) & DMA_DCHPRI5_ECP_MASK) +/*! @} */ + +/*! @name DCHPRI4 - Channel n Priority Register */ +/*! @{ */ +#define DMA_DCHPRI4_CHPRI_MASK (0xFU) +#define DMA_DCHPRI4_CHPRI_SHIFT (0U) +#define DMA_DCHPRI4_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI4_CHPRI_SHIFT)) & DMA_DCHPRI4_CHPRI_MASK) +#define DMA_DCHPRI4_DPA_MASK (0x40U) +#define DMA_DCHPRI4_DPA_SHIFT (6U) +/*! DPA - Disable Preempt Ability + * 0b0..Channel n can suspend a lower priority channel + * 0b1..Channel n cannot suspend any channel, regardless of channel priority + */ +#define DMA_DCHPRI4_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI4_DPA_SHIFT)) & DMA_DCHPRI4_DPA_MASK) +#define DMA_DCHPRI4_ECP_MASK (0x80U) +#define DMA_DCHPRI4_ECP_SHIFT (7U) +/*! ECP - Enable Channel Preemption + * 0b0..Channel n cannot be suspended by a higher priority channel's service request + * 0b1..Channel n can be temporarily suspended by the service request of a higher priority channel + */ +#define DMA_DCHPRI4_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI4_ECP_SHIFT)) & DMA_DCHPRI4_ECP_MASK) +/*! @} */ + +/*! @name DCHPRI11 - Channel n Priority Register */ +/*! @{ */ +#define DMA_DCHPRI11_CHPRI_MASK (0xFU) +#define DMA_DCHPRI11_CHPRI_SHIFT (0U) +#define DMA_DCHPRI11_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI11_CHPRI_SHIFT)) & DMA_DCHPRI11_CHPRI_MASK) +#define DMA_DCHPRI11_DPA_MASK (0x40U) +#define DMA_DCHPRI11_DPA_SHIFT (6U) +/*! DPA - Disable Preempt Ability + * 0b0..Channel n can suspend a lower priority channel + * 0b1..Channel n cannot suspend any channel, regardless of channel priority + */ +#define DMA_DCHPRI11_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI11_DPA_SHIFT)) & DMA_DCHPRI11_DPA_MASK) +#define DMA_DCHPRI11_ECP_MASK (0x80U) +#define DMA_DCHPRI11_ECP_SHIFT (7U) +/*! ECP - Enable Channel Preemption + * 0b0..Channel n cannot be suspended by a higher priority channel's service request + * 0b1..Channel n can be temporarily suspended by the service request of a higher priority channel + */ +#define DMA_DCHPRI11_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI11_ECP_SHIFT)) & DMA_DCHPRI11_ECP_MASK) +/*! @} */ + +/*! @name DCHPRI10 - Channel n Priority Register */ +/*! @{ */ +#define DMA_DCHPRI10_CHPRI_MASK (0xFU) +#define DMA_DCHPRI10_CHPRI_SHIFT (0U) +#define DMA_DCHPRI10_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI10_CHPRI_SHIFT)) & DMA_DCHPRI10_CHPRI_MASK) +#define DMA_DCHPRI10_DPA_MASK (0x40U) +#define DMA_DCHPRI10_DPA_SHIFT (6U) +/*! DPA - Disable Preempt Ability + * 0b0..Channel n can suspend a lower priority channel + * 0b1..Channel n cannot suspend any channel, regardless of channel priority + */ +#define DMA_DCHPRI10_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI10_DPA_SHIFT)) & DMA_DCHPRI10_DPA_MASK) +#define DMA_DCHPRI10_ECP_MASK (0x80U) +#define DMA_DCHPRI10_ECP_SHIFT (7U) +/*! ECP - Enable Channel Preemption + * 0b0..Channel n cannot be suspended by a higher priority channel's service request + * 0b1..Channel n can be temporarily suspended by the service request of a higher priority channel + */ +#define DMA_DCHPRI10_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI10_ECP_SHIFT)) & DMA_DCHPRI10_ECP_MASK) +/*! @} */ + +/*! @name DCHPRI9 - Channel n Priority Register */ +/*! @{ */ +#define DMA_DCHPRI9_CHPRI_MASK (0xFU) +#define DMA_DCHPRI9_CHPRI_SHIFT (0U) +#define DMA_DCHPRI9_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI9_CHPRI_SHIFT)) & DMA_DCHPRI9_CHPRI_MASK) +#define DMA_DCHPRI9_DPA_MASK (0x40U) +#define DMA_DCHPRI9_DPA_SHIFT (6U) +/*! DPA - Disable Preempt Ability + * 0b0..Channel n can suspend a lower priority channel + * 0b1..Channel n cannot suspend any channel, regardless of channel priority + */ +#define DMA_DCHPRI9_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI9_DPA_SHIFT)) & DMA_DCHPRI9_DPA_MASK) +#define DMA_DCHPRI9_ECP_MASK (0x80U) +#define DMA_DCHPRI9_ECP_SHIFT (7U) +/*! ECP - Enable Channel Preemption + * 0b0..Channel n cannot be suspended by a higher priority channel's service request + * 0b1..Channel n can be temporarily suspended by the service request of a higher priority channel + */ +#define DMA_DCHPRI9_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI9_ECP_SHIFT)) & DMA_DCHPRI9_ECP_MASK) +/*! @} */ + +/*! @name DCHPRI8 - Channel n Priority Register */ +/*! @{ */ +#define DMA_DCHPRI8_CHPRI_MASK (0xFU) +#define DMA_DCHPRI8_CHPRI_SHIFT (0U) +#define DMA_DCHPRI8_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI8_CHPRI_SHIFT)) & DMA_DCHPRI8_CHPRI_MASK) +#define DMA_DCHPRI8_DPA_MASK (0x40U) +#define DMA_DCHPRI8_DPA_SHIFT (6U) +/*! DPA - Disable Preempt Ability + * 0b0..Channel n can suspend a lower priority channel + * 0b1..Channel n cannot suspend any channel, regardless of channel priority + */ +#define DMA_DCHPRI8_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI8_DPA_SHIFT)) & DMA_DCHPRI8_DPA_MASK) +#define DMA_DCHPRI8_ECP_MASK (0x80U) +#define DMA_DCHPRI8_ECP_SHIFT (7U) +/*! ECP - Enable Channel Preemption + * 0b0..Channel n cannot be suspended by a higher priority channel's service request + * 0b1..Channel n can be temporarily suspended by the service request of a higher priority channel + */ +#define DMA_DCHPRI8_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI8_ECP_SHIFT)) & DMA_DCHPRI8_ECP_MASK) +/*! @} */ + +/*! @name DCHPRI15 - Channel n Priority Register */ +/*! @{ */ +#define DMA_DCHPRI15_CHPRI_MASK (0xFU) +#define DMA_DCHPRI15_CHPRI_SHIFT (0U) +#define DMA_DCHPRI15_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI15_CHPRI_SHIFT)) & DMA_DCHPRI15_CHPRI_MASK) +#define DMA_DCHPRI15_DPA_MASK (0x40U) +#define DMA_DCHPRI15_DPA_SHIFT (6U) +/*! DPA - Disable Preempt Ability + * 0b0..Channel n can suspend a lower priority channel + * 0b1..Channel n cannot suspend any channel, regardless of channel priority + */ +#define DMA_DCHPRI15_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI15_DPA_SHIFT)) & DMA_DCHPRI15_DPA_MASK) +#define DMA_DCHPRI15_ECP_MASK (0x80U) +#define DMA_DCHPRI15_ECP_SHIFT (7U) +/*! ECP - Enable Channel Preemption + * 0b0..Channel n cannot be suspended by a higher priority channel's service request + * 0b1..Channel n can be temporarily suspended by the service request of a higher priority channel + */ +#define DMA_DCHPRI15_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI15_ECP_SHIFT)) & DMA_DCHPRI15_ECP_MASK) +/*! @} */ + +/*! @name DCHPRI14 - Channel n Priority Register */ +/*! @{ */ +#define DMA_DCHPRI14_CHPRI_MASK (0xFU) +#define DMA_DCHPRI14_CHPRI_SHIFT (0U) +#define DMA_DCHPRI14_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI14_CHPRI_SHIFT)) & DMA_DCHPRI14_CHPRI_MASK) +#define DMA_DCHPRI14_DPA_MASK (0x40U) +#define DMA_DCHPRI14_DPA_SHIFT (6U) +/*! DPA - Disable Preempt Ability + * 0b0..Channel n can suspend a lower priority channel + * 0b1..Channel n cannot suspend any channel, regardless of channel priority + */ +#define DMA_DCHPRI14_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI14_DPA_SHIFT)) & DMA_DCHPRI14_DPA_MASK) +#define DMA_DCHPRI14_ECP_MASK (0x80U) +#define DMA_DCHPRI14_ECP_SHIFT (7U) +/*! ECP - Enable Channel Preemption + * 0b0..Channel n cannot be suspended by a higher priority channel's service request + * 0b1..Channel n can be temporarily suspended by the service request of a higher priority channel + */ +#define DMA_DCHPRI14_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI14_ECP_SHIFT)) & DMA_DCHPRI14_ECP_MASK) +/*! @} */ + +/*! @name DCHPRI13 - Channel n Priority Register */ +/*! @{ */ +#define DMA_DCHPRI13_CHPRI_MASK (0xFU) +#define DMA_DCHPRI13_CHPRI_SHIFT (0U) +#define DMA_DCHPRI13_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI13_CHPRI_SHIFT)) & DMA_DCHPRI13_CHPRI_MASK) +#define DMA_DCHPRI13_DPA_MASK (0x40U) +#define DMA_DCHPRI13_DPA_SHIFT (6U) +/*! DPA - Disable Preempt Ability + * 0b0..Channel n can suspend a lower priority channel + * 0b1..Channel n cannot suspend any channel, regardless of channel priority + */ +#define DMA_DCHPRI13_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI13_DPA_SHIFT)) & DMA_DCHPRI13_DPA_MASK) +#define DMA_DCHPRI13_ECP_MASK (0x80U) +#define DMA_DCHPRI13_ECP_SHIFT (7U) +/*! ECP - Enable Channel Preemption + * 0b0..Channel n cannot be suspended by a higher priority channel's service request + * 0b1..Channel n can be temporarily suspended by the service request of a higher priority channel + */ +#define DMA_DCHPRI13_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI13_ECP_SHIFT)) & DMA_DCHPRI13_ECP_MASK) +/*! @} */ + +/*! @name DCHPRI12 - Channel n Priority Register */ +/*! @{ */ +#define DMA_DCHPRI12_CHPRI_MASK (0xFU) +#define DMA_DCHPRI12_CHPRI_SHIFT (0U) +#define DMA_DCHPRI12_CHPRI(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI12_CHPRI_SHIFT)) & DMA_DCHPRI12_CHPRI_MASK) +#define DMA_DCHPRI12_DPA_MASK (0x40U) +#define DMA_DCHPRI12_DPA_SHIFT (6U) +/*! DPA - Disable Preempt Ability + * 0b0..Channel n can suspend a lower priority channel + * 0b1..Channel n cannot suspend any channel, regardless of channel priority + */ +#define DMA_DCHPRI12_DPA(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI12_DPA_SHIFT)) & DMA_DCHPRI12_DPA_MASK) +#define DMA_DCHPRI12_ECP_MASK (0x80U) +#define DMA_DCHPRI12_ECP_SHIFT (7U) +/*! ECP - Enable Channel Preemption + * 0b0..Channel n cannot be suspended by a higher priority channel's service request + * 0b1..Channel n can be temporarily suspended by the service request of a higher priority channel + */ +#define DMA_DCHPRI12_ECP(x) (((uint8_t)(((uint8_t)(x)) << DMA_DCHPRI12_ECP_SHIFT)) & DMA_DCHPRI12_ECP_MASK) +/*! @} */ + +/*! @name SADDR - TCD Source Address */ +/*! @{ */ +#define DMA_SADDR_SADDR_MASK (0xFFFFFFFFU) +#define DMA_SADDR_SADDR_SHIFT (0U) +#define DMA_SADDR_SADDR(x) (((uint32_t)(((uint32_t)(x)) << DMA_SADDR_SADDR_SHIFT)) & DMA_SADDR_SADDR_MASK) +/*! @} */ + +/* The count of DMA_SADDR */ +#define DMA_SADDR_COUNT (16U) + +/*! @name SOFF - TCD Signed Source Address Offset */ +/*! @{ */ +#define DMA_SOFF_SOFF_MASK (0xFFFFU) +#define DMA_SOFF_SOFF_SHIFT (0U) +#define DMA_SOFF_SOFF(x) (((uint16_t)(((uint16_t)(x)) << DMA_SOFF_SOFF_SHIFT)) & DMA_SOFF_SOFF_MASK) +/*! @} */ + +/* The count of DMA_SOFF */ +#define DMA_SOFF_COUNT (16U) + +/*! @name ATTR - TCD Transfer Attributes */ +/*! @{ */ +#define DMA_ATTR_DSIZE_MASK (0x7U) +#define DMA_ATTR_DSIZE_SHIFT (0U) +#define DMA_ATTR_DSIZE(x) (((uint16_t)(((uint16_t)(x)) << DMA_ATTR_DSIZE_SHIFT)) & DMA_ATTR_DSIZE_MASK) +#define DMA_ATTR_DMOD_MASK (0xF8U) +#define DMA_ATTR_DMOD_SHIFT (3U) +#define DMA_ATTR_DMOD(x) (((uint16_t)(((uint16_t)(x)) << DMA_ATTR_DMOD_SHIFT)) & DMA_ATTR_DMOD_MASK) +#define DMA_ATTR_SSIZE_MASK (0x700U) +#define DMA_ATTR_SSIZE_SHIFT (8U) +/*! SSIZE - Source data transfer size + * 0b000..8-bit + * 0b001..16-bit + * 0b010..32-bit + * 0b011..Reserved + * 0b100..16-byte + * 0b101..32-byte + * 0b110..Reserved + * 0b111..Reserved + */ +#define DMA_ATTR_SSIZE(x) (((uint16_t)(((uint16_t)(x)) << DMA_ATTR_SSIZE_SHIFT)) & DMA_ATTR_SSIZE_MASK) +#define DMA_ATTR_SMOD_MASK (0xF800U) +#define DMA_ATTR_SMOD_SHIFT (11U) +/*! SMOD - Source Address Modulo. + * 0b00000..Source address modulo feature is disabled + */ +#define DMA_ATTR_SMOD(x) (((uint16_t)(((uint16_t)(x)) << DMA_ATTR_SMOD_SHIFT)) & DMA_ATTR_SMOD_MASK) +/*! @} */ + +/* The count of DMA_ATTR */ +#define DMA_ATTR_COUNT (16U) + +/*! @name NBYTES_MLNO - TCD Minor Byte Count (Minor Loop Disabled) */ +/*! @{ */ +#define DMA_NBYTES_MLNO_NBYTES_MASK (0xFFFFFFFFU) +#define DMA_NBYTES_MLNO_NBYTES_SHIFT (0U) +#define DMA_NBYTES_MLNO_NBYTES(x) (((uint32_t)(((uint32_t)(x)) << DMA_NBYTES_MLNO_NBYTES_SHIFT)) & DMA_NBYTES_MLNO_NBYTES_MASK) +/*! @} */ + +/* The count of DMA_NBYTES_MLNO */ +#define DMA_NBYTES_MLNO_COUNT (16U) + +/*! @name NBYTES_MLOFFNO - TCD Signed Minor Loop Offset (Minor Loop Enabled and Offset Disabled) */ +/*! @{ */ +#define DMA_NBYTES_MLOFFNO_NBYTES_MASK (0x3FFFFFFFU) +#define DMA_NBYTES_MLOFFNO_NBYTES_SHIFT (0U) +#define DMA_NBYTES_MLOFFNO_NBYTES(x) (((uint32_t)(((uint32_t)(x)) << DMA_NBYTES_MLOFFNO_NBYTES_SHIFT)) & DMA_NBYTES_MLOFFNO_NBYTES_MASK) +#define DMA_NBYTES_MLOFFNO_DMLOE_MASK (0x40000000U) +#define DMA_NBYTES_MLOFFNO_DMLOE_SHIFT (30U) +/*! DMLOE - Destination Minor Loop Offset enable + * 0b0..The minor loop offset is not applied to the DADDR + * 0b1..The minor loop offset is applied to the DADDR + */ +#define DMA_NBYTES_MLOFFNO_DMLOE(x) (((uint32_t)(((uint32_t)(x)) << DMA_NBYTES_MLOFFNO_DMLOE_SHIFT)) & DMA_NBYTES_MLOFFNO_DMLOE_MASK) +#define DMA_NBYTES_MLOFFNO_SMLOE_MASK (0x80000000U) +#define DMA_NBYTES_MLOFFNO_SMLOE_SHIFT (31U) +/*! SMLOE - Source Minor Loop Offset Enable + * 0b0..The minor loop offset is not applied to the SADDR + * 0b1..The minor loop offset is applied to the SADDR + */ +#define DMA_NBYTES_MLOFFNO_SMLOE(x) (((uint32_t)(((uint32_t)(x)) << DMA_NBYTES_MLOFFNO_SMLOE_SHIFT)) & DMA_NBYTES_MLOFFNO_SMLOE_MASK) +/*! @} */ + +/* The count of DMA_NBYTES_MLOFFNO */ +#define DMA_NBYTES_MLOFFNO_COUNT (16U) + +/*! @name NBYTES_MLOFFYES - TCD Signed Minor Loop Offset (Minor Loop and Offset Enabled) */ +/*! @{ */ +#define DMA_NBYTES_MLOFFYES_NBYTES_MASK (0x3FFU) +#define DMA_NBYTES_MLOFFYES_NBYTES_SHIFT (0U) +#define DMA_NBYTES_MLOFFYES_NBYTES(x) (((uint32_t)(((uint32_t)(x)) << DMA_NBYTES_MLOFFYES_NBYTES_SHIFT)) & DMA_NBYTES_MLOFFYES_NBYTES_MASK) +#define DMA_NBYTES_MLOFFYES_MLOFF_MASK (0x3FFFFC00U) +#define DMA_NBYTES_MLOFFYES_MLOFF_SHIFT (10U) +#define DMA_NBYTES_MLOFFYES_MLOFF(x) (((uint32_t)(((uint32_t)(x)) << DMA_NBYTES_MLOFFYES_MLOFF_SHIFT)) & DMA_NBYTES_MLOFFYES_MLOFF_MASK) +#define DMA_NBYTES_MLOFFYES_DMLOE_MASK (0x40000000U) +#define DMA_NBYTES_MLOFFYES_DMLOE_SHIFT (30U) +/*! DMLOE - Destination Minor Loop Offset enable + * 0b0..The minor loop offset is not applied to the DADDR + * 0b1..The minor loop offset is applied to the DADDR + */ +#define DMA_NBYTES_MLOFFYES_DMLOE(x) (((uint32_t)(((uint32_t)(x)) << DMA_NBYTES_MLOFFYES_DMLOE_SHIFT)) & DMA_NBYTES_MLOFFYES_DMLOE_MASK) +#define DMA_NBYTES_MLOFFYES_SMLOE_MASK (0x80000000U) +#define DMA_NBYTES_MLOFFYES_SMLOE_SHIFT (31U) +/*! SMLOE - Source Minor Loop Offset Enable + * 0b0..The minor loop offset is not applied to the SADDR + * 0b1..The minor loop offset is applied to the SADDR + */ +#define DMA_NBYTES_MLOFFYES_SMLOE(x) (((uint32_t)(((uint32_t)(x)) << DMA_NBYTES_MLOFFYES_SMLOE_SHIFT)) & DMA_NBYTES_MLOFFYES_SMLOE_MASK) +/*! @} */ + +/* The count of DMA_NBYTES_MLOFFYES */ +#define DMA_NBYTES_MLOFFYES_COUNT (16U) + +/*! @name SLAST - TCD Last Source Address Adjustment */ +/*! @{ */ +#define DMA_SLAST_SLAST_MASK (0xFFFFFFFFU) +#define DMA_SLAST_SLAST_SHIFT (0U) +#define DMA_SLAST_SLAST(x) (((uint32_t)(((uint32_t)(x)) << DMA_SLAST_SLAST_SHIFT)) & DMA_SLAST_SLAST_MASK) +/*! @} */ + +/* The count of DMA_SLAST */ +#define DMA_SLAST_COUNT (16U) + +/*! @name DADDR - TCD Destination Address */ +/*! @{ */ +#define DMA_DADDR_DADDR_MASK (0xFFFFFFFFU) +#define DMA_DADDR_DADDR_SHIFT (0U) +#define DMA_DADDR_DADDR(x) (((uint32_t)(((uint32_t)(x)) << DMA_DADDR_DADDR_SHIFT)) & DMA_DADDR_DADDR_MASK) +/*! @} */ + +/* The count of DMA_DADDR */ +#define DMA_DADDR_COUNT (16U) + +/*! @name DOFF - TCD Signed Destination Address Offset */ +/*! @{ */ +#define DMA_DOFF_DOFF_MASK (0xFFFFU) +#define DMA_DOFF_DOFF_SHIFT (0U) +#define DMA_DOFF_DOFF(x) (((uint16_t)(((uint16_t)(x)) << DMA_DOFF_DOFF_SHIFT)) & DMA_DOFF_DOFF_MASK) +/*! @} */ + +/* The count of DMA_DOFF */ +#define DMA_DOFF_COUNT (16U) + +/*! @name CITER_ELINKNO - TCD Current Minor Loop Link, Major Loop Count (Channel Linking Disabled) */ +/*! @{ */ +#define DMA_CITER_ELINKNO_CITER_MASK (0x7FFFU) +#define DMA_CITER_ELINKNO_CITER_SHIFT (0U) +#define DMA_CITER_ELINKNO_CITER(x) (((uint16_t)(((uint16_t)(x)) << DMA_CITER_ELINKNO_CITER_SHIFT)) & DMA_CITER_ELINKNO_CITER_MASK) +#define DMA_CITER_ELINKNO_ELINK_MASK (0x8000U) +#define DMA_CITER_ELINKNO_ELINK_SHIFT (15U) +/*! ELINK - Enable channel-to-channel linking on minor-loop complete + * 0b0..The channel-to-channel linking is disabled + * 0b1..The channel-to-channel linking is enabled + */ +#define DMA_CITER_ELINKNO_ELINK(x) (((uint16_t)(((uint16_t)(x)) << DMA_CITER_ELINKNO_ELINK_SHIFT)) & DMA_CITER_ELINKNO_ELINK_MASK) +/*! @} */ + +/* The count of DMA_CITER_ELINKNO */ +#define DMA_CITER_ELINKNO_COUNT (16U) + +/*! @name CITER_ELINKYES - TCD Current Minor Loop Link, Major Loop Count (Channel Linking Enabled) */ +/*! @{ */ +#define DMA_CITER_ELINKYES_CITER_MASK (0x1FFU) +#define DMA_CITER_ELINKYES_CITER_SHIFT (0U) +#define DMA_CITER_ELINKYES_CITER(x) (((uint16_t)(((uint16_t)(x)) << DMA_CITER_ELINKYES_CITER_SHIFT)) & DMA_CITER_ELINKYES_CITER_MASK) +#define DMA_CITER_ELINKYES_LINKCH_MASK (0x1E00U) +#define DMA_CITER_ELINKYES_LINKCH_SHIFT (9U) +#define DMA_CITER_ELINKYES_LINKCH(x) (((uint16_t)(((uint16_t)(x)) << DMA_CITER_ELINKYES_LINKCH_SHIFT)) & DMA_CITER_ELINKYES_LINKCH_MASK) +#define DMA_CITER_ELINKYES_ELINK_MASK (0x8000U) +#define DMA_CITER_ELINKYES_ELINK_SHIFT (15U) +/*! ELINK - Enable channel-to-channel linking on minor-loop complete + * 0b0..The channel-to-channel linking is disabled + * 0b1..The channel-to-channel linking is enabled + */ +#define DMA_CITER_ELINKYES_ELINK(x) (((uint16_t)(((uint16_t)(x)) << DMA_CITER_ELINKYES_ELINK_SHIFT)) & DMA_CITER_ELINKYES_ELINK_MASK) +/*! @} */ + +/* The count of DMA_CITER_ELINKYES */ +#define DMA_CITER_ELINKYES_COUNT (16U) + +/*! @name DLAST_SGA - TCD Last Destination Address Adjustment/Scatter Gather Address */ +/*! @{ */ +#define DMA_DLAST_SGA_DLASTSGA_MASK (0xFFFFFFFFU) +#define DMA_DLAST_SGA_DLASTSGA_SHIFT (0U) +#define DMA_DLAST_SGA_DLASTSGA(x) (((uint32_t)(((uint32_t)(x)) << DMA_DLAST_SGA_DLASTSGA_SHIFT)) & DMA_DLAST_SGA_DLASTSGA_MASK) +/*! @} */ + +/* The count of DMA_DLAST_SGA */ +#define DMA_DLAST_SGA_COUNT (16U) + +/*! @name CSR - TCD Control and Status */ +/*! @{ */ +#define DMA_CSR_START_MASK (0x1U) +#define DMA_CSR_START_SHIFT (0U) +/*! START - Channel Start + * 0b0..The channel is not explicitly started + * 0b1..The channel is explicitly started via a software initiated service request + */ +#define DMA_CSR_START(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_START_SHIFT)) & DMA_CSR_START_MASK) +#define DMA_CSR_INTMAJOR_MASK (0x2U) +#define DMA_CSR_INTMAJOR_SHIFT (1U) +/*! INTMAJOR - Enable an interrupt when major iteration count completes + * 0b0..The end-of-major loop interrupt is disabled + * 0b1..The end-of-major loop interrupt is enabled + */ +#define DMA_CSR_INTMAJOR(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_INTMAJOR_SHIFT)) & DMA_CSR_INTMAJOR_MASK) +#define DMA_CSR_INTHALF_MASK (0x4U) +#define DMA_CSR_INTHALF_SHIFT (2U) +/*! INTHALF - Enable an interrupt when major counter is half complete. + * 0b0..The half-point interrupt is disabled + * 0b1..The half-point interrupt is enabled + */ +#define DMA_CSR_INTHALF(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_INTHALF_SHIFT)) & DMA_CSR_INTHALF_MASK) +#define DMA_CSR_DREQ_MASK (0x8U) +#define DMA_CSR_DREQ_SHIFT (3U) +/*! DREQ - Disable Request + * 0b0..The channel's ERQ bit is not affected + * 0b1..The channel's ERQ bit is cleared when the major loop is complete + */ +#define DMA_CSR_DREQ(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_DREQ_SHIFT)) & DMA_CSR_DREQ_MASK) +#define DMA_CSR_ESG_MASK (0x10U) +#define DMA_CSR_ESG_SHIFT (4U) +/*! ESG - Enable Scatter/Gather Processing + * 0b0..The current channel's TCD is normal format. + * 0b1..The current channel's TCD specifies a scatter gather format. The DLASTSGA field provides a memory pointer to the next TCD to be loaded into this channel after the major loop completes its execution. + */ +#define DMA_CSR_ESG(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_ESG_SHIFT)) & DMA_CSR_ESG_MASK) +#define DMA_CSR_MAJORELINK_MASK (0x20U) +#define DMA_CSR_MAJORELINK_SHIFT (5U) +/*! MAJORELINK - Enable channel-to-channel linking on major loop complete + * 0b0..The channel-to-channel linking is disabled + * 0b1..The channel-to-channel linking is enabled + */ +#define DMA_CSR_MAJORELINK(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_MAJORELINK_SHIFT)) & DMA_CSR_MAJORELINK_MASK) +#define DMA_CSR_ACTIVE_MASK (0x40U) +#define DMA_CSR_ACTIVE_SHIFT (6U) +#define DMA_CSR_ACTIVE(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_ACTIVE_SHIFT)) & DMA_CSR_ACTIVE_MASK) +#define DMA_CSR_DONE_MASK (0x80U) +#define DMA_CSR_DONE_SHIFT (7U) +#define DMA_CSR_DONE(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_DONE_SHIFT)) & DMA_CSR_DONE_MASK) +#define DMA_CSR_MAJORLINKCH_MASK (0xF00U) +#define DMA_CSR_MAJORLINKCH_SHIFT (8U) +#define DMA_CSR_MAJORLINKCH(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_MAJORLINKCH_SHIFT)) & DMA_CSR_MAJORLINKCH_MASK) +#define DMA_CSR_BWC_MASK (0xC000U) +#define DMA_CSR_BWC_SHIFT (14U) +/*! BWC - Bandwidth Control + * 0b00..No eDMA engine stalls + * 0b01..Reserved + * 0b10..eDMA engine stalls for 4 cycles after each r/w + * 0b11..eDMA engine stalls for 8 cycles after each r/w + */ +#define DMA_CSR_BWC(x) (((uint16_t)(((uint16_t)(x)) << DMA_CSR_BWC_SHIFT)) & DMA_CSR_BWC_MASK) +/*! @} */ + +/* The count of DMA_CSR */ +#define DMA_CSR_COUNT (16U) + +/*! @name BITER_ELINKNO - TCD Beginning Minor Loop Link, Major Loop Count (Channel Linking Disabled) */ +/*! @{ */ +#define DMA_BITER_ELINKNO_BITER_MASK (0x7FFFU) +#define DMA_BITER_ELINKNO_BITER_SHIFT (0U) +#define DMA_BITER_ELINKNO_BITER(x) (((uint16_t)(((uint16_t)(x)) << DMA_BITER_ELINKNO_BITER_SHIFT)) & DMA_BITER_ELINKNO_BITER_MASK) +#define DMA_BITER_ELINKNO_ELINK_MASK (0x8000U) +#define DMA_BITER_ELINKNO_ELINK_SHIFT (15U) +/*! ELINK - Enables channel-to-channel linking on minor loop complete + * 0b0..The channel-to-channel linking is disabled + * 0b1..The channel-to-channel linking is enabled + */ +#define DMA_BITER_ELINKNO_ELINK(x) (((uint16_t)(((uint16_t)(x)) << DMA_BITER_ELINKNO_ELINK_SHIFT)) & DMA_BITER_ELINKNO_ELINK_MASK) +/*! @} */ + +/* The count of DMA_BITER_ELINKNO */ +#define DMA_BITER_ELINKNO_COUNT (16U) + +/*! @name BITER_ELINKYES - TCD Beginning Minor Loop Link, Major Loop Count (Channel Linking Enabled) */ +/*! @{ */ +#define DMA_BITER_ELINKYES_BITER_MASK (0x1FFU) +#define DMA_BITER_ELINKYES_BITER_SHIFT (0U) +#define DMA_BITER_ELINKYES_BITER(x) (((uint16_t)(((uint16_t)(x)) << DMA_BITER_ELINKYES_BITER_SHIFT)) & DMA_BITER_ELINKYES_BITER_MASK) +#define DMA_BITER_ELINKYES_LINKCH_MASK (0x1E00U) +#define DMA_BITER_ELINKYES_LINKCH_SHIFT (9U) +#define DMA_BITER_ELINKYES_LINKCH(x) (((uint16_t)(((uint16_t)(x)) << DMA_BITER_ELINKYES_LINKCH_SHIFT)) & DMA_BITER_ELINKYES_LINKCH_MASK) +#define DMA_BITER_ELINKYES_ELINK_MASK (0x8000U) +#define DMA_BITER_ELINKYES_ELINK_SHIFT (15U) +/*! ELINK - Enables channel-to-channel linking on minor loop complete + * 0b0..The channel-to-channel linking is disabled + * 0b1..The channel-to-channel linking is enabled + */ +#define DMA_BITER_ELINKYES_ELINK(x) (((uint16_t)(((uint16_t)(x)) << DMA_BITER_ELINKYES_ELINK_SHIFT)) & DMA_BITER_ELINKYES_ELINK_MASK) +/*! @} */ + +/* The count of DMA_BITER_ELINKYES */ +#define DMA_BITER_ELINKYES_COUNT (16U) + + +/*! + * @} + */ /* end of group DMA_Register_Masks */ + + +/* DMA - Peripheral instance base addresses */ +/** Peripheral DMA base address */ +#define DMA_BASE (0x40008000u) +/** Peripheral DMA base pointer */ +#define DMA0 ((DMA_Type *)DMA_BASE) +/** Array initializer of DMA peripheral base addresses */ +#define DMA_BASE_ADDRS { DMA_BASE } +/** Array initializer of DMA peripheral base pointers */ +#define DMA_BASE_PTRS { DMA0 } +/** Interrupt vectors for the DMA peripheral type */ +#define DMA_CHN_IRQS { { DMA0_IRQn, DMA1_IRQn, DMA2_IRQn, DMA3_IRQn, DMA4_IRQn, DMA5_IRQn, DMA6_IRQn, DMA7_IRQn, DMA8_IRQn, DMA9_IRQn, DMA10_IRQn, DMA11_IRQn, DMA12_IRQn, DMA13_IRQn, DMA14_IRQn, DMA15_IRQn } } +#define DMA_ERROR_IRQS { DMA_Error_IRQn } + +/*! + * @} + */ /* end of group DMA_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- DMAMUX Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMAMUX_Peripheral_Access_Layer DMAMUX Peripheral Access Layer + * @{ + */ + +/** DMAMUX - Register Layout Typedef */ +typedef struct { + __IO uint8_t CHCFG[16]; /**< Channel Configuration register, array offset: 0x0, array step: 0x1 */ +} DMAMUX_Type; + +/* ---------------------------------------------------------------------------- + -- DMAMUX Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMAMUX_Register_Masks DMAMUX Register Masks + * @{ + */ + +/*! @name CHCFG - Channel Configuration register */ +/*! @{ */ +#define DMAMUX_CHCFG_SOURCE_MASK (0x3FU) +#define DMAMUX_CHCFG_SOURCE_SHIFT (0U) +/*! SOURCE - DMA Channel Source (Slot) + * 0b000000..Disable_Signal + * 0b000010..UART0_Rx_Signal + * 0b000011..UART0_Tx_Signal + * 0b000100..UART1_Rx_Signal + * 0b000101..UART1_Tx_Signal + * 0b000110..UART2_Rx_Signal + * 0b000111..UART2_Tx_Signal + * 0b001000..UART3_Rx_Signal + * 0b001001..UART3_Tx_Signal + * 0b001010..UART4_Signal + * 0b001011..UART5_Signal + * 0b001100..I2S0_Rx_Signal + * 0b001101..I2S0_Tx_Signal + * 0b001110..SPI0_Rx_Signal + * 0b001111..SPI0_Tx_Signal + * 0b010000..SPI1_Signal + * 0b010001..SPI2_Signal + * 0b010010..I2C0_Signal + * 0b010011..I2C1_I2C2_Signal + * 0b010100..FTM0_Channel0_Signal + * 0b010101..FTM0_Channel1_Signal + * 0b010110..FTM0_Channel2_Signal + * 0b010111..FTM0_Channel3_Signal + * 0b011000..FTM0_Channel4_Signal + * 0b011001..FTM0_Channel5_Signal + * 0b011010..FTM0_Channel6_Signal + * 0b011011..FTM0_Channel7_Signal + * 0b011100..FTM1_Channel0_Signal + * 0b011101..FTM1_Channel1_Signal + * 0b011110..FTM2_Channel0_Signal + * 0b011111..FTM2_Channel1_Signal + * 0b100000..FTM3_Channel0_Signal + * 0b100001..FTM3_Channel1_Signal + * 0b100010..FTM3_Channel2_Signal + * 0b100011..FTM3_Channel3_Signal + * 0b100100..FTM3_Channel4_Signal + * 0b100101..FTM3_Channel5_Signal + * 0b100110..FTM3_Channel6_Signal + * 0b100111..FTM3_Channel7_Signal + * 0b101000..ADC0_Signal + * 0b101001..ADC1_Signal + * 0b101010..CMP0_Signal + * 0b101011..CMP1_Signal + * 0b101100..CMP2_Signal + * 0b101101..DAC0_Signal + * 0b101110..DAC1_Signal + * 0b101111..CMT_Signal + * 0b110000..PDB_Signal + * 0b110001..PortA_Signal + * 0b110010..PortB_Signal + * 0b110011..PortC_Signal + * 0b110100..PortD_Signal + * 0b110101..PortE_Signal + * 0b110110..IEEE1588Timer0_Signal + * 0b110111..IEEE1588Timer1_Signal + * 0b111000..IEEE1588Timer2_Signal + * 0b111001..IEEE1588Timer3_Signal + * 0b111010..AlwaysOn58_Signal + * 0b111011..AlwaysOn59_Signal + * 0b111100..AlwaysOn60_Signal + * 0b111101..AlwaysOn61_Signal + * 0b111110..AlwaysOn62_Signal + * 0b111111..AlwaysOn63_Signal + */ +#define DMAMUX_CHCFG_SOURCE(x) (((uint8_t)(((uint8_t)(x)) << DMAMUX_CHCFG_SOURCE_SHIFT)) & DMAMUX_CHCFG_SOURCE_MASK) +#define DMAMUX_CHCFG_TRIG_MASK (0x40U) +#define DMAMUX_CHCFG_TRIG_SHIFT (6U) +/*! TRIG - DMA Channel Trigger Enable + * 0b0..Triggering is disabled. If triggering is disabled and ENBL is set, the DMA Channel will simply route the specified source to the DMA channel. (Normal mode) + * 0b1..Triggering is enabled. If triggering is enabled and ENBL is set, the DMAMUX is in Periodic Trigger mode. + */ +#define DMAMUX_CHCFG_TRIG(x) (((uint8_t)(((uint8_t)(x)) << DMAMUX_CHCFG_TRIG_SHIFT)) & DMAMUX_CHCFG_TRIG_MASK) +#define DMAMUX_CHCFG_ENBL_MASK (0x80U) +#define DMAMUX_CHCFG_ENBL_SHIFT (7U) +/*! ENBL - DMA Channel Enable + * 0b0..DMA channel is disabled. This mode is primarily used during configuration of the DMAMux. The DMA has separate channel enables/disables, which should be used to disable or reconfigure a DMA channel. + * 0b1..DMA channel is enabled + */ +#define DMAMUX_CHCFG_ENBL(x) (((uint8_t)(((uint8_t)(x)) << DMAMUX_CHCFG_ENBL_SHIFT)) & DMAMUX_CHCFG_ENBL_MASK) +/*! @} */ + +/* The count of DMAMUX_CHCFG */ +#define DMAMUX_CHCFG_COUNT (16U) + + +/*! + * @} + */ /* end of group DMAMUX_Register_Masks */ + + +/* DMAMUX - Peripheral instance base addresses */ +/** Peripheral DMAMUX base address */ +#define DMAMUX_BASE (0x40021000u) +/** Peripheral DMAMUX base pointer */ +#define DMAMUX ((DMAMUX_Type *)DMAMUX_BASE) +/** Array initializer of DMAMUX peripheral base addresses */ +#define DMAMUX_BASE_ADDRS { DMAMUX_BASE } +/** Array initializer of DMAMUX peripheral base pointers */ +#define DMAMUX_BASE_PTRS { DMAMUX } + +/*! + * @} + */ /* end of group DMAMUX_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- ENET Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ENET_Peripheral_Access_Layer ENET Peripheral Access Layer + * @{ + */ + +/** ENET - Register Layout Typedef */ +typedef struct { + uint8_t RESERVED_0[4]; + __IO uint32_t EIR; /**< Interrupt Event Register, offset: 0x4 */ + __IO uint32_t EIMR; /**< Interrupt Mask Register, offset: 0x8 */ + uint8_t RESERVED_1[4]; + __IO uint32_t RDAR; /**< Receive Descriptor Active Register, offset: 0x10 */ + __IO uint32_t TDAR; /**< Transmit Descriptor Active Register, offset: 0x14 */ + uint8_t RESERVED_2[12]; + __IO uint32_t ECR; /**< Ethernet Control Register, offset: 0x24 */ + uint8_t RESERVED_3[24]; + __IO uint32_t MMFR; /**< MII Management Frame Register, offset: 0x40 */ + __IO uint32_t MSCR; /**< MII Speed Control Register, offset: 0x44 */ + uint8_t RESERVED_4[28]; + __IO uint32_t MIBC; /**< MIB Control Register, offset: 0x64 */ + uint8_t RESERVED_5[28]; + __IO uint32_t RCR; /**< Receive Control Register, offset: 0x84 */ + uint8_t RESERVED_6[60]; + __IO uint32_t TCR; /**< Transmit Control Register, offset: 0xC4 */ + uint8_t RESERVED_7[28]; + __IO uint32_t PALR; /**< Physical Address Lower Register, offset: 0xE4 */ + __IO uint32_t PAUR; /**< Physical Address Upper Register, offset: 0xE8 */ + __IO uint32_t OPD; /**< Opcode/Pause Duration Register, offset: 0xEC */ + uint8_t RESERVED_8[40]; + __IO uint32_t IAUR; /**< Descriptor Individual Upper Address Register, offset: 0x118 */ + __IO uint32_t IALR; /**< Descriptor Individual Lower Address Register, offset: 0x11C */ + __IO uint32_t GAUR; /**< Descriptor Group Upper Address Register, offset: 0x120 */ + __IO uint32_t GALR; /**< Descriptor Group Lower Address Register, offset: 0x124 */ + uint8_t RESERVED_9[28]; + __IO uint32_t TFWR; /**< Transmit FIFO Watermark Register, offset: 0x144 */ + uint8_t RESERVED_10[56]; + __IO uint32_t RDSR; /**< Receive Descriptor Ring Start Register, offset: 0x180 */ + __IO uint32_t TDSR; /**< Transmit Buffer Descriptor Ring Start Register, offset: 0x184 */ + __IO uint32_t MRBR; /**< Maximum Receive Buffer Size Register, offset: 0x188 */ + uint8_t RESERVED_11[4]; + __IO uint32_t RSFL; /**< Receive FIFO Section Full Threshold, offset: 0x190 */ + __IO uint32_t RSEM; /**< Receive FIFO Section Empty Threshold, offset: 0x194 */ + __IO uint32_t RAEM; /**< Receive FIFO Almost Empty Threshold, offset: 0x198 */ + __IO uint32_t RAFL; /**< Receive FIFO Almost Full Threshold, offset: 0x19C */ + __IO uint32_t TSEM; /**< Transmit FIFO Section Empty Threshold, offset: 0x1A0 */ + __IO uint32_t TAEM; /**< Transmit FIFO Almost Empty Threshold, offset: 0x1A4 */ + __IO uint32_t TAFL; /**< Transmit FIFO Almost Full Threshold, offset: 0x1A8 */ + __IO uint32_t TIPG; /**< Transmit Inter-Packet Gap, offset: 0x1AC */ + __IO uint32_t FTRL; /**< Frame Truncation Length, offset: 0x1B0 */ + uint8_t RESERVED_12[12]; + __IO uint32_t TACC; /**< Transmit Accelerator Function Configuration, offset: 0x1C0 */ + __IO uint32_t RACC; /**< Receive Accelerator Function Configuration, offset: 0x1C4 */ + uint8_t RESERVED_13[60]; + __I uint32_t RMON_T_PACKETS; /**< Tx Packet Count Statistic Register, offset: 0x204 */ + __I uint32_t RMON_T_BC_PKT; /**< Tx Broadcast Packets Statistic Register, offset: 0x208 */ + __I uint32_t RMON_T_MC_PKT; /**< Tx Multicast Packets Statistic Register, offset: 0x20C */ + __I uint32_t RMON_T_CRC_ALIGN; /**< Tx Packets with CRC/Align Error Statistic Register, offset: 0x210 */ + __I uint32_t RMON_T_UNDERSIZE; /**< Tx Packets Less Than Bytes and Good CRC Statistic Register, offset: 0x214 */ + __I uint32_t RMON_T_OVERSIZE; /**< Tx Packets GT MAX_FL bytes and Good CRC Statistic Register, offset: 0x218 */ + __I uint32_t RMON_T_FRAG; /**< Tx Packets Less Than 64 Bytes and Bad CRC Statistic Register, offset: 0x21C */ + __I uint32_t RMON_T_JAB; /**< Tx Packets Greater Than MAX_FL bytes and Bad CRC Statistic Register, offset: 0x220 */ + __I uint32_t RMON_T_COL; /**< Tx Collision Count Statistic Register, offset: 0x224 */ + __I uint32_t RMON_T_P64; /**< Tx 64-Byte Packets Statistic Register, offset: 0x228 */ + __I uint32_t RMON_T_P65TO127; /**< Tx 65- to 127-byte Packets Statistic Register, offset: 0x22C */ + __I uint32_t RMON_T_P128TO255; /**< Tx 128- to 255-byte Packets Statistic Register, offset: 0x230 */ + __I uint32_t RMON_T_P256TO511; /**< Tx 256- to 511-byte Packets Statistic Register, offset: 0x234 */ + __I uint32_t RMON_T_P512TO1023; /**< Tx 512- to 1023-byte Packets Statistic Register, offset: 0x238 */ + __I uint32_t RMON_T_P1024TO2047; /**< Tx 1024- to 2047-byte Packets Statistic Register, offset: 0x23C */ + __I uint32_t RMON_T_P_GTE2048; /**< Tx Packets Greater Than 2048 Bytes Statistic Register, offset: 0x240 */ + __I uint32_t RMON_T_OCTETS; /**< Tx Octets Statistic Register, offset: 0x244 */ + uint8_t RESERVED_14[4]; + __I uint32_t IEEE_T_FRAME_OK; /**< Frames Transmitted OK Statistic Register, offset: 0x24C */ + __I uint32_t IEEE_T_1COL; /**< Frames Transmitted with Single Collision Statistic Register, offset: 0x250 */ + __I uint32_t IEEE_T_MCOL; /**< Frames Transmitted with Multiple Collisions Statistic Register, offset: 0x254 */ + __I uint32_t IEEE_T_DEF; /**< Frames Transmitted after Deferral Delay Statistic Register, offset: 0x258 */ + __I uint32_t IEEE_T_LCOL; /**< Frames Transmitted with Late Collision Statistic Register, offset: 0x25C */ + __I uint32_t IEEE_T_EXCOL; /**< Frames Transmitted with Excessive Collisions Statistic Register, offset: 0x260 */ + __I uint32_t IEEE_T_MACERR; /**< Frames Transmitted with Tx FIFO Underrun Statistic Register, offset: 0x264 */ + __I uint32_t IEEE_T_CSERR; /**< Frames Transmitted with Carrier Sense Error Statistic Register, offset: 0x268 */ + uint8_t RESERVED_15[4]; + __I uint32_t IEEE_T_FDXFC; /**< Flow Control Pause Frames Transmitted Statistic Register, offset: 0x270 */ + __I uint32_t IEEE_T_OCTETS_OK; /**< Octet Count for Frames Transmitted w/o Error Statistic Register, offset: 0x274 */ + uint8_t RESERVED_16[12]; + __I uint32_t RMON_R_PACKETS; /**< Rx Packet Count Statistic Register, offset: 0x284 */ + __I uint32_t RMON_R_BC_PKT; /**< Rx Broadcast Packets Statistic Register, offset: 0x288 */ + __I uint32_t RMON_R_MC_PKT; /**< Rx Multicast Packets Statistic Register, offset: 0x28C */ + __I uint32_t RMON_R_CRC_ALIGN; /**< Rx Packets with CRC/Align Error Statistic Register, offset: 0x290 */ + __I uint32_t RMON_R_UNDERSIZE; /**< Rx Packets with Less Than 64 Bytes and Good CRC Statistic Register, offset: 0x294 */ + __I uint32_t RMON_R_OVERSIZE; /**< Rx Packets Greater Than MAX_FL and Good CRC Statistic Register, offset: 0x298 */ + __I uint32_t RMON_R_FRAG; /**< Rx Packets Less Than 64 Bytes and Bad CRC Statistic Register, offset: 0x29C */ + __I uint32_t RMON_R_JAB; /**< Rx Packets Greater Than MAX_FL Bytes and Bad CRC Statistic Register, offset: 0x2A0 */ + uint8_t RESERVED_17[4]; + __I uint32_t RMON_R_P64; /**< Rx 64-Byte Packets Statistic Register, offset: 0x2A8 */ + __I uint32_t RMON_R_P65TO127; /**< Rx 65- to 127-Byte Packets Statistic Register, offset: 0x2AC */ + __I uint32_t RMON_R_P128TO255; /**< Rx 128- to 255-Byte Packets Statistic Register, offset: 0x2B0 */ + __I uint32_t RMON_R_P256TO511; /**< Rx 256- to 511-Byte Packets Statistic Register, offset: 0x2B4 */ + __I uint32_t RMON_R_P512TO1023; /**< Rx 512- to 1023-Byte Packets Statistic Register, offset: 0x2B8 */ + __I uint32_t RMON_R_P1024TO2047; /**< Rx 1024- to 2047-Byte Packets Statistic Register, offset: 0x2BC */ + __I uint32_t RMON_R_P_GTE2048; /**< Rx Packets Greater than 2048 Bytes Statistic Register, offset: 0x2C0 */ + __I uint32_t RMON_R_OCTETS; /**< Rx Octets Statistic Register, offset: 0x2C4 */ + __I uint32_t IEEE_R_DROP; /**< Frames not Counted Correctly Statistic Register, offset: 0x2C8 */ + __I uint32_t IEEE_R_FRAME_OK; /**< Frames Received OK Statistic Register, offset: 0x2CC */ + __I uint32_t IEEE_R_CRC; /**< Frames Received with CRC Error Statistic Register, offset: 0x2D0 */ + __I uint32_t IEEE_R_ALIGN; /**< Frames Received with Alignment Error Statistic Register, offset: 0x2D4 */ + __I uint32_t IEEE_R_MACERR; /**< Receive FIFO Overflow Count Statistic Register, offset: 0x2D8 */ + __I uint32_t IEEE_R_FDXFC; /**< Flow Control Pause Frames Received Statistic Register, offset: 0x2DC */ + __I uint32_t IEEE_R_OCTETS_OK; /**< Octet Count for Frames Received without Error Statistic Register, offset: 0x2E0 */ + uint8_t RESERVED_18[284]; + __IO uint32_t ATCR; /**< Adjustable Timer Control Register, offset: 0x400 */ + __IO uint32_t ATVR; /**< Timer Value Register, offset: 0x404 */ + __IO uint32_t ATOFF; /**< Timer Offset Register, offset: 0x408 */ + __IO uint32_t ATPER; /**< Timer Period Register, offset: 0x40C */ + __IO uint32_t ATCOR; /**< Timer Correction Register, offset: 0x410 */ + __IO uint32_t ATINC; /**< Time-Stamping Clock Period Register, offset: 0x414 */ + __I uint32_t ATSTMP; /**< Timestamp of Last Transmitted Frame, offset: 0x418 */ + uint8_t RESERVED_19[488]; + __IO uint32_t TGSR; /**< Timer Global Status Register, offset: 0x604 */ + struct { /* offset: 0x608, array step: 0x8 */ + __IO uint32_t TCSR; /**< Timer Control Status Register, array offset: 0x608, array step: 0x8 */ + __IO uint32_t TCCR; /**< Timer Compare Capture Register, array offset: 0x60C, array step: 0x8 */ + } CHANNEL[4]; +} ENET_Type; + +/* ---------------------------------------------------------------------------- + -- ENET Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ENET_Register_Masks ENET Register Masks + * @{ + */ + +/*! @name EIR - Interrupt Event Register */ +/*! @{ */ +#define ENET_EIR_TS_TIMER_MASK (0x8000U) +#define ENET_EIR_TS_TIMER_SHIFT (15U) +#define ENET_EIR_TS_TIMER(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIR_TS_TIMER_SHIFT)) & ENET_EIR_TS_TIMER_MASK) +#define ENET_EIR_TS_AVAIL_MASK (0x10000U) +#define ENET_EIR_TS_AVAIL_SHIFT (16U) +#define ENET_EIR_TS_AVAIL(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIR_TS_AVAIL_SHIFT)) & ENET_EIR_TS_AVAIL_MASK) +#define ENET_EIR_WAKEUP_MASK (0x20000U) +#define ENET_EIR_WAKEUP_SHIFT (17U) +#define ENET_EIR_WAKEUP(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIR_WAKEUP_SHIFT)) & ENET_EIR_WAKEUP_MASK) +#define ENET_EIR_PLR_MASK (0x40000U) +#define ENET_EIR_PLR_SHIFT (18U) +#define ENET_EIR_PLR(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIR_PLR_SHIFT)) & ENET_EIR_PLR_MASK) +#define ENET_EIR_UN_MASK (0x80000U) +#define ENET_EIR_UN_SHIFT (19U) +#define ENET_EIR_UN(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIR_UN_SHIFT)) & ENET_EIR_UN_MASK) +#define ENET_EIR_RL_MASK (0x100000U) +#define ENET_EIR_RL_SHIFT (20U) +#define ENET_EIR_RL(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIR_RL_SHIFT)) & ENET_EIR_RL_MASK) +#define ENET_EIR_LC_MASK (0x200000U) +#define ENET_EIR_LC_SHIFT (21U) +#define ENET_EIR_LC(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIR_LC_SHIFT)) & ENET_EIR_LC_MASK) +#define ENET_EIR_EBERR_MASK (0x400000U) +#define ENET_EIR_EBERR_SHIFT (22U) +#define ENET_EIR_EBERR(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIR_EBERR_SHIFT)) & ENET_EIR_EBERR_MASK) +#define ENET_EIR_MII_MASK (0x800000U) +#define ENET_EIR_MII_SHIFT (23U) +#define ENET_EIR_MII(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIR_MII_SHIFT)) & ENET_EIR_MII_MASK) +#define ENET_EIR_RXB_MASK (0x1000000U) +#define ENET_EIR_RXB_SHIFT (24U) +#define ENET_EIR_RXB(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIR_RXB_SHIFT)) & ENET_EIR_RXB_MASK) +#define ENET_EIR_RXF_MASK (0x2000000U) +#define ENET_EIR_RXF_SHIFT (25U) +#define ENET_EIR_RXF(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIR_RXF_SHIFT)) & ENET_EIR_RXF_MASK) +#define ENET_EIR_TXB_MASK (0x4000000U) +#define ENET_EIR_TXB_SHIFT (26U) +#define ENET_EIR_TXB(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIR_TXB_SHIFT)) & ENET_EIR_TXB_MASK) +#define ENET_EIR_TXF_MASK (0x8000000U) +#define ENET_EIR_TXF_SHIFT (27U) +#define ENET_EIR_TXF(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIR_TXF_SHIFT)) & ENET_EIR_TXF_MASK) +#define ENET_EIR_GRA_MASK (0x10000000U) +#define ENET_EIR_GRA_SHIFT (28U) +#define ENET_EIR_GRA(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIR_GRA_SHIFT)) & ENET_EIR_GRA_MASK) +#define ENET_EIR_BABT_MASK (0x20000000U) +#define ENET_EIR_BABT_SHIFT (29U) +#define ENET_EIR_BABT(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIR_BABT_SHIFT)) & ENET_EIR_BABT_MASK) +#define ENET_EIR_BABR_MASK (0x40000000U) +#define ENET_EIR_BABR_SHIFT (30U) +#define ENET_EIR_BABR(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIR_BABR_SHIFT)) & ENET_EIR_BABR_MASK) +/*! @} */ + +/*! @name EIMR - Interrupt Mask Register */ +/*! @{ */ +#define ENET_EIMR_TS_TIMER_MASK (0x8000U) +#define ENET_EIMR_TS_TIMER_SHIFT (15U) +#define ENET_EIMR_TS_TIMER(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIMR_TS_TIMER_SHIFT)) & ENET_EIMR_TS_TIMER_MASK) +#define ENET_EIMR_TS_AVAIL_MASK (0x10000U) +#define ENET_EIMR_TS_AVAIL_SHIFT (16U) +#define ENET_EIMR_TS_AVAIL(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIMR_TS_AVAIL_SHIFT)) & ENET_EIMR_TS_AVAIL_MASK) +#define ENET_EIMR_WAKEUP_MASK (0x20000U) +#define ENET_EIMR_WAKEUP_SHIFT (17U) +#define ENET_EIMR_WAKEUP(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIMR_WAKEUP_SHIFT)) & ENET_EIMR_WAKEUP_MASK) +#define ENET_EIMR_PLR_MASK (0x40000U) +#define ENET_EIMR_PLR_SHIFT (18U) +#define ENET_EIMR_PLR(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIMR_PLR_SHIFT)) & ENET_EIMR_PLR_MASK) +#define ENET_EIMR_UN_MASK (0x80000U) +#define ENET_EIMR_UN_SHIFT (19U) +#define ENET_EIMR_UN(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIMR_UN_SHIFT)) & ENET_EIMR_UN_MASK) +#define ENET_EIMR_RL_MASK (0x100000U) +#define ENET_EIMR_RL_SHIFT (20U) +#define ENET_EIMR_RL(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIMR_RL_SHIFT)) & ENET_EIMR_RL_MASK) +#define ENET_EIMR_LC_MASK (0x200000U) +#define ENET_EIMR_LC_SHIFT (21U) +#define ENET_EIMR_LC(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIMR_LC_SHIFT)) & ENET_EIMR_LC_MASK) +#define ENET_EIMR_EBERR_MASK (0x400000U) +#define ENET_EIMR_EBERR_SHIFT (22U) +#define ENET_EIMR_EBERR(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIMR_EBERR_SHIFT)) & ENET_EIMR_EBERR_MASK) +#define ENET_EIMR_MII_MASK (0x800000U) +#define ENET_EIMR_MII_SHIFT (23U) +#define ENET_EIMR_MII(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIMR_MII_SHIFT)) & ENET_EIMR_MII_MASK) +#define ENET_EIMR_RXB_MASK (0x1000000U) +#define ENET_EIMR_RXB_SHIFT (24U) +#define ENET_EIMR_RXB(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIMR_RXB_SHIFT)) & ENET_EIMR_RXB_MASK) +#define ENET_EIMR_RXF_MASK (0x2000000U) +#define ENET_EIMR_RXF_SHIFT (25U) +#define ENET_EIMR_RXF(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIMR_RXF_SHIFT)) & ENET_EIMR_RXF_MASK) +#define ENET_EIMR_TXB_MASK (0x4000000U) +#define ENET_EIMR_TXB_SHIFT (26U) +/*! TXB - TXB Interrupt Mask + * 0b0..The corresponding interrupt source is masked. + * 0b1..The corresponding interrupt source is not masked. + */ +#define ENET_EIMR_TXB(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIMR_TXB_SHIFT)) & ENET_EIMR_TXB_MASK) +#define ENET_EIMR_TXF_MASK (0x8000000U) +#define ENET_EIMR_TXF_SHIFT (27U) +/*! TXF - TXF Interrupt Mask + * 0b0..The corresponding interrupt source is masked. + * 0b1..The corresponding interrupt source is not masked. + */ +#define ENET_EIMR_TXF(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIMR_TXF_SHIFT)) & ENET_EIMR_TXF_MASK) +#define ENET_EIMR_GRA_MASK (0x10000000U) +#define ENET_EIMR_GRA_SHIFT (28U) +/*! GRA - GRA Interrupt Mask + * 0b0..The corresponding interrupt source is masked. + * 0b1..The corresponding interrupt source is not masked. + */ +#define ENET_EIMR_GRA(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIMR_GRA_SHIFT)) & ENET_EIMR_GRA_MASK) +#define ENET_EIMR_BABT_MASK (0x20000000U) +#define ENET_EIMR_BABT_SHIFT (29U) +/*! BABT - BABT Interrupt Mask + * 0b0..The corresponding interrupt source is masked. + * 0b1..The corresponding interrupt source is not masked. + */ +#define ENET_EIMR_BABT(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIMR_BABT_SHIFT)) & ENET_EIMR_BABT_MASK) +#define ENET_EIMR_BABR_MASK (0x40000000U) +#define ENET_EIMR_BABR_SHIFT (30U) +/*! BABR - BABR Interrupt Mask + * 0b0..The corresponding interrupt source is masked. + * 0b1..The corresponding interrupt source is not masked. + */ +#define ENET_EIMR_BABR(x) (((uint32_t)(((uint32_t)(x)) << ENET_EIMR_BABR_SHIFT)) & ENET_EIMR_BABR_MASK) +/*! @} */ + +/*! @name RDAR - Receive Descriptor Active Register */ +/*! @{ */ +#define ENET_RDAR_RDAR_MASK (0x1000000U) +#define ENET_RDAR_RDAR_SHIFT (24U) +#define ENET_RDAR_RDAR(x) (((uint32_t)(((uint32_t)(x)) << ENET_RDAR_RDAR_SHIFT)) & ENET_RDAR_RDAR_MASK) +/*! @} */ + +/*! @name TDAR - Transmit Descriptor Active Register */ +/*! @{ */ +#define ENET_TDAR_TDAR_MASK (0x1000000U) +#define ENET_TDAR_TDAR_SHIFT (24U) +#define ENET_TDAR_TDAR(x) (((uint32_t)(((uint32_t)(x)) << ENET_TDAR_TDAR_SHIFT)) & ENET_TDAR_TDAR_MASK) +/*! @} */ + +/*! @name ECR - Ethernet Control Register */ +/*! @{ */ +#define ENET_ECR_RESET_MASK (0x1U) +#define ENET_ECR_RESET_SHIFT (0U) +#define ENET_ECR_RESET(x) (((uint32_t)(((uint32_t)(x)) << ENET_ECR_RESET_SHIFT)) & ENET_ECR_RESET_MASK) +#define ENET_ECR_ETHEREN_MASK (0x2U) +#define ENET_ECR_ETHEREN_SHIFT (1U) +/*! ETHEREN - Ethernet Enable + * 0b0..Reception immediately stops and transmission stops after a bad CRC is appended to any currently transmitted frame. + * 0b1..MAC is enabled, and reception and transmission are possible. + */ +#define ENET_ECR_ETHEREN(x) (((uint32_t)(((uint32_t)(x)) << ENET_ECR_ETHEREN_SHIFT)) & ENET_ECR_ETHEREN_MASK) +#define ENET_ECR_MAGICEN_MASK (0x4U) +#define ENET_ECR_MAGICEN_SHIFT (2U) +/*! MAGICEN - Magic Packet Detection Enable + * 0b0..Magic detection logic disabled. + * 0b1..The MAC core detects magic packets and asserts EIR[WAKEUP] when a frame is detected. + */ +#define ENET_ECR_MAGICEN(x) (((uint32_t)(((uint32_t)(x)) << ENET_ECR_MAGICEN_SHIFT)) & ENET_ECR_MAGICEN_MASK) +#define ENET_ECR_SLEEP_MASK (0x8U) +#define ENET_ECR_SLEEP_SHIFT (3U) +/*! SLEEP - Sleep Mode Enable + * 0b0..Normal operating mode. + * 0b1..Sleep mode. + */ +#define ENET_ECR_SLEEP(x) (((uint32_t)(((uint32_t)(x)) << ENET_ECR_SLEEP_SHIFT)) & ENET_ECR_SLEEP_MASK) +#define ENET_ECR_EN1588_MASK (0x10U) +#define ENET_ECR_EN1588_SHIFT (4U) +/*! EN1588 - EN1588 Enable + * 0b0..Legacy FEC buffer descriptors and functions enabled. + * 0b1..Enhanced frame time-stamping functions enabled. + */ +#define ENET_ECR_EN1588(x) (((uint32_t)(((uint32_t)(x)) << ENET_ECR_EN1588_SHIFT)) & ENET_ECR_EN1588_MASK) +#define ENET_ECR_DBGEN_MASK (0x40U) +#define ENET_ECR_DBGEN_SHIFT (6U) +/*! DBGEN - Debug Enable + * 0b0..MAC continues operation in debug mode. + * 0b1..MAC enters hardware freeze mode when the processor is in debug mode. + */ +#define ENET_ECR_DBGEN(x) (((uint32_t)(((uint32_t)(x)) << ENET_ECR_DBGEN_SHIFT)) & ENET_ECR_DBGEN_MASK) +#define ENET_ECR_STOPEN_MASK (0x80U) +#define ENET_ECR_STOPEN_SHIFT (7U) +#define ENET_ECR_STOPEN(x) (((uint32_t)(((uint32_t)(x)) << ENET_ECR_STOPEN_SHIFT)) & ENET_ECR_STOPEN_MASK) +#define ENET_ECR_DBSWP_MASK (0x100U) +#define ENET_ECR_DBSWP_SHIFT (8U) +/*! DBSWP - Descriptor Byte Swapping Enable + * 0b0..The buffer descriptor bytes are not swapped to support big-endian devices. + * 0b1..The buffer descriptor bytes are swapped to support little-endian devices. + */ +#define ENET_ECR_DBSWP(x) (((uint32_t)(((uint32_t)(x)) << ENET_ECR_DBSWP_SHIFT)) & ENET_ECR_DBSWP_MASK) +/*! @} */ + +/*! @name MMFR - MII Management Frame Register */ +/*! @{ */ +#define ENET_MMFR_DATA_MASK (0xFFFFU) +#define ENET_MMFR_DATA_SHIFT (0U) +#define ENET_MMFR_DATA(x) (((uint32_t)(((uint32_t)(x)) << ENET_MMFR_DATA_SHIFT)) & ENET_MMFR_DATA_MASK) +#define ENET_MMFR_TA_MASK (0x30000U) +#define ENET_MMFR_TA_SHIFT (16U) +#define ENET_MMFR_TA(x) (((uint32_t)(((uint32_t)(x)) << ENET_MMFR_TA_SHIFT)) & ENET_MMFR_TA_MASK) +#define ENET_MMFR_RA_MASK (0x7C0000U) +#define ENET_MMFR_RA_SHIFT (18U) +#define ENET_MMFR_RA(x) (((uint32_t)(((uint32_t)(x)) << ENET_MMFR_RA_SHIFT)) & ENET_MMFR_RA_MASK) +#define ENET_MMFR_PA_MASK (0xF800000U) +#define ENET_MMFR_PA_SHIFT (23U) +#define ENET_MMFR_PA(x) (((uint32_t)(((uint32_t)(x)) << ENET_MMFR_PA_SHIFT)) & ENET_MMFR_PA_MASK) +#define ENET_MMFR_OP_MASK (0x30000000U) +#define ENET_MMFR_OP_SHIFT (28U) +/*! OP - Operation Code + * 0b00..Write frame operation, but not MII compliant. + * 0b01..Write frame operation for a valid MII management frame. + * 0b10..Read frame operation for a valid MII management frame. + * 0b11..Read frame operation, but not MII compliant. + */ +#define ENET_MMFR_OP(x) (((uint32_t)(((uint32_t)(x)) << ENET_MMFR_OP_SHIFT)) & ENET_MMFR_OP_MASK) +#define ENET_MMFR_ST_MASK (0xC0000000U) +#define ENET_MMFR_ST_SHIFT (30U) +#define ENET_MMFR_ST(x) (((uint32_t)(((uint32_t)(x)) << ENET_MMFR_ST_SHIFT)) & ENET_MMFR_ST_MASK) +/*! @} */ + +/*! @name MSCR - MII Speed Control Register */ +/*! @{ */ +#define ENET_MSCR_MII_SPEED_MASK (0x7EU) +#define ENET_MSCR_MII_SPEED_SHIFT (1U) +#define ENET_MSCR_MII_SPEED(x) (((uint32_t)(((uint32_t)(x)) << ENET_MSCR_MII_SPEED_SHIFT)) & ENET_MSCR_MII_SPEED_MASK) +#define ENET_MSCR_DIS_PRE_MASK (0x80U) +#define ENET_MSCR_DIS_PRE_SHIFT (7U) +/*! DIS_PRE - Disable Preamble + * 0b0..Preamble enabled. + * 0b1..Preamble (32 ones) is not prepended to the MII management frame. + */ +#define ENET_MSCR_DIS_PRE(x) (((uint32_t)(((uint32_t)(x)) << ENET_MSCR_DIS_PRE_SHIFT)) & ENET_MSCR_DIS_PRE_MASK) +#define ENET_MSCR_HOLDTIME_MASK (0x700U) +#define ENET_MSCR_HOLDTIME_SHIFT (8U) +/*! HOLDTIME - Hold time On MDIO Output + * 0b000..1 internal module clock cycle + * 0b001..2 internal module clock cycles + * 0b010..3 internal module clock cycles + * 0b111..8 internal module clock cycles + */ +#define ENET_MSCR_HOLDTIME(x) (((uint32_t)(((uint32_t)(x)) << ENET_MSCR_HOLDTIME_SHIFT)) & ENET_MSCR_HOLDTIME_MASK) +/*! @} */ + +/*! @name MIBC - MIB Control Register */ +/*! @{ */ +#define ENET_MIBC_MIB_CLEAR_MASK (0x20000000U) +#define ENET_MIBC_MIB_CLEAR_SHIFT (29U) +#define ENET_MIBC_MIB_CLEAR(x) (((uint32_t)(((uint32_t)(x)) << ENET_MIBC_MIB_CLEAR_SHIFT)) & ENET_MIBC_MIB_CLEAR_MASK) +#define ENET_MIBC_MIB_IDLE_MASK (0x40000000U) +#define ENET_MIBC_MIB_IDLE_SHIFT (30U) +#define ENET_MIBC_MIB_IDLE(x) (((uint32_t)(((uint32_t)(x)) << ENET_MIBC_MIB_IDLE_SHIFT)) & ENET_MIBC_MIB_IDLE_MASK) +#define ENET_MIBC_MIB_DIS_MASK (0x80000000U) +#define ENET_MIBC_MIB_DIS_SHIFT (31U) +#define ENET_MIBC_MIB_DIS(x) (((uint32_t)(((uint32_t)(x)) << ENET_MIBC_MIB_DIS_SHIFT)) & ENET_MIBC_MIB_DIS_MASK) +/*! @} */ + +/*! @name RCR - Receive Control Register */ +/*! @{ */ +#define ENET_RCR_LOOP_MASK (0x1U) +#define ENET_RCR_LOOP_SHIFT (0U) +/*! LOOP - Internal Loopback + * 0b0..Loopback disabled. + * 0b1..Transmitted frames are looped back internal to the device and transmit MII output signals are not asserted. DRT must be cleared. + */ +#define ENET_RCR_LOOP(x) (((uint32_t)(((uint32_t)(x)) << ENET_RCR_LOOP_SHIFT)) & ENET_RCR_LOOP_MASK) +#define ENET_RCR_DRT_MASK (0x2U) +#define ENET_RCR_DRT_SHIFT (1U) +/*! DRT - Disable Receive On Transmit + * 0b0..Receive path operates independently of transmit. Used for full-duplex or to monitor transmit activity in half-duplex mode. + * 0b1..Disable reception of frames while transmitting. Normally used for half-duplex mode. + */ +#define ENET_RCR_DRT(x) (((uint32_t)(((uint32_t)(x)) << ENET_RCR_DRT_SHIFT)) & ENET_RCR_DRT_MASK) +#define ENET_RCR_MII_MODE_MASK (0x4U) +#define ENET_RCR_MII_MODE_SHIFT (2U) +/*! MII_MODE - Media Independent Interface Mode + * 0b0..Reserved. + * 0b1..MII or RMII mode, as indicated by the RMII_MODE field. + */ +#define ENET_RCR_MII_MODE(x) (((uint32_t)(((uint32_t)(x)) << ENET_RCR_MII_MODE_SHIFT)) & ENET_RCR_MII_MODE_MASK) +#define ENET_RCR_PROM_MASK (0x8U) +#define ENET_RCR_PROM_SHIFT (3U) +/*! PROM - Promiscuous Mode + * 0b0..Disabled. + * 0b1..Enabled. + */ +#define ENET_RCR_PROM(x) (((uint32_t)(((uint32_t)(x)) << ENET_RCR_PROM_SHIFT)) & ENET_RCR_PROM_MASK) +#define ENET_RCR_BC_REJ_MASK (0x10U) +#define ENET_RCR_BC_REJ_SHIFT (4U) +#define ENET_RCR_BC_REJ(x) (((uint32_t)(((uint32_t)(x)) << ENET_RCR_BC_REJ_SHIFT)) & ENET_RCR_BC_REJ_MASK) +#define ENET_RCR_FCE_MASK (0x20U) +#define ENET_RCR_FCE_SHIFT (5U) +#define ENET_RCR_FCE(x) (((uint32_t)(((uint32_t)(x)) << ENET_RCR_FCE_SHIFT)) & ENET_RCR_FCE_MASK) +#define ENET_RCR_RMII_MODE_MASK (0x100U) +#define ENET_RCR_RMII_MODE_SHIFT (8U) +/*! RMII_MODE - RMII Mode Enable + * 0b0..MAC configured for MII mode. + * 0b1..MAC configured for RMII operation. + */ +#define ENET_RCR_RMII_MODE(x) (((uint32_t)(((uint32_t)(x)) << ENET_RCR_RMII_MODE_SHIFT)) & ENET_RCR_RMII_MODE_MASK) +#define ENET_RCR_RMII_10T_MASK (0x200U) +#define ENET_RCR_RMII_10T_SHIFT (9U) +/*! RMII_10T + * 0b0..100 Mbps operation. + * 0b1..10 Mbps operation. + */ +#define ENET_RCR_RMII_10T(x) (((uint32_t)(((uint32_t)(x)) << ENET_RCR_RMII_10T_SHIFT)) & ENET_RCR_RMII_10T_MASK) +#define ENET_RCR_PADEN_MASK (0x1000U) +#define ENET_RCR_PADEN_SHIFT (12U) +/*! PADEN - Enable Frame Padding Remove On Receive + * 0b0..No padding is removed on receive by the MAC. + * 0b1..Padding is removed from received frames. + */ +#define ENET_RCR_PADEN(x) (((uint32_t)(((uint32_t)(x)) << ENET_RCR_PADEN_SHIFT)) & ENET_RCR_PADEN_MASK) +#define ENET_RCR_PAUFWD_MASK (0x2000U) +#define ENET_RCR_PAUFWD_SHIFT (13U) +/*! PAUFWD - Terminate/Forward Pause Frames + * 0b0..Pause frames are terminated and discarded in the MAC. + * 0b1..Pause frames are forwarded to the user application. + */ +#define ENET_RCR_PAUFWD(x) (((uint32_t)(((uint32_t)(x)) << ENET_RCR_PAUFWD_SHIFT)) & ENET_RCR_PAUFWD_MASK) +#define ENET_RCR_CRCFWD_MASK (0x4000U) +#define ENET_RCR_CRCFWD_SHIFT (14U) +/*! CRCFWD - Terminate/Forward Received CRC + * 0b0..The CRC field of received frames is transmitted to the user application. + * 0b1..The CRC field is stripped from the frame. + */ +#define ENET_RCR_CRCFWD(x) (((uint32_t)(((uint32_t)(x)) << ENET_RCR_CRCFWD_SHIFT)) & ENET_RCR_CRCFWD_MASK) +#define ENET_RCR_CFEN_MASK (0x8000U) +#define ENET_RCR_CFEN_SHIFT (15U) +/*! CFEN - MAC Control Frame Enable + * 0b0..MAC control frames with any opcode other than 0x0001 (pause frame) are accepted and forwarded to the client interface. + * 0b1..MAC control frames with any opcode other than 0x0001 (pause frame) are silently discarded. + */ +#define ENET_RCR_CFEN(x) (((uint32_t)(((uint32_t)(x)) << ENET_RCR_CFEN_SHIFT)) & ENET_RCR_CFEN_MASK) +#define ENET_RCR_MAX_FL_MASK (0x3FFF0000U) +#define ENET_RCR_MAX_FL_SHIFT (16U) +#define ENET_RCR_MAX_FL(x) (((uint32_t)(((uint32_t)(x)) << ENET_RCR_MAX_FL_SHIFT)) & ENET_RCR_MAX_FL_MASK) +#define ENET_RCR_NLC_MASK (0x40000000U) +#define ENET_RCR_NLC_SHIFT (30U) +/*! NLC - Payload Length Check Disable + * 0b0..The payload length check is disabled. + * 0b1..The core checks the frame's payload length with the frame length/type field. Errors are indicated in the EIR[PLC] field. + */ +#define ENET_RCR_NLC(x) (((uint32_t)(((uint32_t)(x)) << ENET_RCR_NLC_SHIFT)) & ENET_RCR_NLC_MASK) +#define ENET_RCR_GRS_MASK (0x80000000U) +#define ENET_RCR_GRS_SHIFT (31U) +#define ENET_RCR_GRS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RCR_GRS_SHIFT)) & ENET_RCR_GRS_MASK) +/*! @} */ + +/*! @name TCR - Transmit Control Register */ +/*! @{ */ +#define ENET_TCR_GTS_MASK (0x1U) +#define ENET_TCR_GTS_SHIFT (0U) +#define ENET_TCR_GTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_TCR_GTS_SHIFT)) & ENET_TCR_GTS_MASK) +#define ENET_TCR_FDEN_MASK (0x4U) +#define ENET_TCR_FDEN_SHIFT (2U) +#define ENET_TCR_FDEN(x) (((uint32_t)(((uint32_t)(x)) << ENET_TCR_FDEN_SHIFT)) & ENET_TCR_FDEN_MASK) +#define ENET_TCR_TFC_PAUSE_MASK (0x8U) +#define ENET_TCR_TFC_PAUSE_SHIFT (3U) +/*! TFC_PAUSE - Transmit Frame Control Pause + * 0b0..No PAUSE frame transmitted. + * 0b1..The MAC stops transmission of data frames after the current transmission is complete. + */ +#define ENET_TCR_TFC_PAUSE(x) (((uint32_t)(((uint32_t)(x)) << ENET_TCR_TFC_PAUSE_SHIFT)) & ENET_TCR_TFC_PAUSE_MASK) +#define ENET_TCR_RFC_PAUSE_MASK (0x10U) +#define ENET_TCR_RFC_PAUSE_SHIFT (4U) +#define ENET_TCR_RFC_PAUSE(x) (((uint32_t)(((uint32_t)(x)) << ENET_TCR_RFC_PAUSE_SHIFT)) & ENET_TCR_RFC_PAUSE_MASK) +#define ENET_TCR_ADDSEL_MASK (0xE0U) +#define ENET_TCR_ADDSEL_SHIFT (5U) +/*! ADDSEL - Source MAC Address Select On Transmit + * 0b000..Node MAC address programmed on PADDR1/2 registers. + * 0b100..Reserved. + * 0b101..Reserved. + * 0b110..Reserved. + */ +#define ENET_TCR_ADDSEL(x) (((uint32_t)(((uint32_t)(x)) << ENET_TCR_ADDSEL_SHIFT)) & ENET_TCR_ADDSEL_MASK) +#define ENET_TCR_ADDINS_MASK (0x100U) +#define ENET_TCR_ADDINS_SHIFT (8U) +/*! ADDINS - Set MAC Address On Transmit + * 0b0..The source MAC address is not modified by the MAC. + * 0b1..The MAC overwrites the source MAC address with the programmed MAC address according to ADDSEL. + */ +#define ENET_TCR_ADDINS(x) (((uint32_t)(((uint32_t)(x)) << ENET_TCR_ADDINS_SHIFT)) & ENET_TCR_ADDINS_MASK) +#define ENET_TCR_CRCFWD_MASK (0x200U) +#define ENET_TCR_CRCFWD_SHIFT (9U) +/*! CRCFWD - Forward Frame From Application With CRC + * 0b0..TxBD[TC] controls whether the frame has a CRC from the application. + * 0b1..The transmitter does not append any CRC to transmitted frames, as it is expecting a frame with CRC from the application. + */ +#define ENET_TCR_CRCFWD(x) (((uint32_t)(((uint32_t)(x)) << ENET_TCR_CRCFWD_SHIFT)) & ENET_TCR_CRCFWD_MASK) +/*! @} */ + +/*! @name PALR - Physical Address Lower Register */ +/*! @{ */ +#define ENET_PALR_PADDR1_MASK (0xFFFFFFFFU) +#define ENET_PALR_PADDR1_SHIFT (0U) +#define ENET_PALR_PADDR1(x) (((uint32_t)(((uint32_t)(x)) << ENET_PALR_PADDR1_SHIFT)) & ENET_PALR_PADDR1_MASK) +/*! @} */ + +/*! @name PAUR - Physical Address Upper Register */ +/*! @{ */ +#define ENET_PAUR_TYPE_MASK (0xFFFFU) +#define ENET_PAUR_TYPE_SHIFT (0U) +#define ENET_PAUR_TYPE(x) (((uint32_t)(((uint32_t)(x)) << ENET_PAUR_TYPE_SHIFT)) & ENET_PAUR_TYPE_MASK) +#define ENET_PAUR_PADDR2_MASK (0xFFFF0000U) +#define ENET_PAUR_PADDR2_SHIFT (16U) +#define ENET_PAUR_PADDR2(x) (((uint32_t)(((uint32_t)(x)) << ENET_PAUR_PADDR2_SHIFT)) & ENET_PAUR_PADDR2_MASK) +/*! @} */ + +/*! @name OPD - Opcode/Pause Duration Register */ +/*! @{ */ +#define ENET_OPD_PAUSE_DUR_MASK (0xFFFFU) +#define ENET_OPD_PAUSE_DUR_SHIFT (0U) +#define ENET_OPD_PAUSE_DUR(x) (((uint32_t)(((uint32_t)(x)) << ENET_OPD_PAUSE_DUR_SHIFT)) & ENET_OPD_PAUSE_DUR_MASK) +#define ENET_OPD_OPCODE_MASK (0xFFFF0000U) +#define ENET_OPD_OPCODE_SHIFT (16U) +#define ENET_OPD_OPCODE(x) (((uint32_t)(((uint32_t)(x)) << ENET_OPD_OPCODE_SHIFT)) & ENET_OPD_OPCODE_MASK) +/*! @} */ + +/*! @name IAUR - Descriptor Individual Upper Address Register */ +/*! @{ */ +#define ENET_IAUR_IADDR1_MASK (0xFFFFFFFFU) +#define ENET_IAUR_IADDR1_SHIFT (0U) +#define ENET_IAUR_IADDR1(x) (((uint32_t)(((uint32_t)(x)) << ENET_IAUR_IADDR1_SHIFT)) & ENET_IAUR_IADDR1_MASK) +/*! @} */ + +/*! @name IALR - Descriptor Individual Lower Address Register */ +/*! @{ */ +#define ENET_IALR_IADDR2_MASK (0xFFFFFFFFU) +#define ENET_IALR_IADDR2_SHIFT (0U) +#define ENET_IALR_IADDR2(x) (((uint32_t)(((uint32_t)(x)) << ENET_IALR_IADDR2_SHIFT)) & ENET_IALR_IADDR2_MASK) +/*! @} */ + +/*! @name GAUR - Descriptor Group Upper Address Register */ +/*! @{ */ +#define ENET_GAUR_GADDR1_MASK (0xFFFFFFFFU) +#define ENET_GAUR_GADDR1_SHIFT (0U) +#define ENET_GAUR_GADDR1(x) (((uint32_t)(((uint32_t)(x)) << ENET_GAUR_GADDR1_SHIFT)) & ENET_GAUR_GADDR1_MASK) +/*! @} */ + +/*! @name GALR - Descriptor Group Lower Address Register */ +/*! @{ */ +#define ENET_GALR_GADDR2_MASK (0xFFFFFFFFU) +#define ENET_GALR_GADDR2_SHIFT (0U) +#define ENET_GALR_GADDR2(x) (((uint32_t)(((uint32_t)(x)) << ENET_GALR_GADDR2_SHIFT)) & ENET_GALR_GADDR2_MASK) +/*! @} */ + +/*! @name TFWR - Transmit FIFO Watermark Register */ +/*! @{ */ +#define ENET_TFWR_TFWR_MASK (0x3FU) +#define ENET_TFWR_TFWR_SHIFT (0U) +/*! TFWR - Transmit FIFO Write + * 0b000000..64 bytes written. + * 0b000001..64 bytes written. + * 0b000010..128 bytes written. + * 0b000011..192 bytes written. + * 0b111110..3968 bytes written. + * 0b111111..4032 bytes written. + */ +#define ENET_TFWR_TFWR(x) (((uint32_t)(((uint32_t)(x)) << ENET_TFWR_TFWR_SHIFT)) & ENET_TFWR_TFWR_MASK) +#define ENET_TFWR_STRFWD_MASK (0x100U) +#define ENET_TFWR_STRFWD_SHIFT (8U) +/*! STRFWD - Store And Forward Enable + * 0b0..Reset. The transmission start threshold is programmed in TFWR[TFWR]. + * 0b1..Enabled. + */ +#define ENET_TFWR_STRFWD(x) (((uint32_t)(((uint32_t)(x)) << ENET_TFWR_STRFWD_SHIFT)) & ENET_TFWR_STRFWD_MASK) +/*! @} */ + +/*! @name RDSR - Receive Descriptor Ring Start Register */ +/*! @{ */ +#define ENET_RDSR_R_DES_START_MASK (0xFFFFFFF8U) +#define ENET_RDSR_R_DES_START_SHIFT (3U) +#define ENET_RDSR_R_DES_START(x) (((uint32_t)(((uint32_t)(x)) << ENET_RDSR_R_DES_START_SHIFT)) & ENET_RDSR_R_DES_START_MASK) +/*! @} */ + +/*! @name TDSR - Transmit Buffer Descriptor Ring Start Register */ +/*! @{ */ +#define ENET_TDSR_X_DES_START_MASK (0xFFFFFFF8U) +#define ENET_TDSR_X_DES_START_SHIFT (3U) +#define ENET_TDSR_X_DES_START(x) (((uint32_t)(((uint32_t)(x)) << ENET_TDSR_X_DES_START_SHIFT)) & ENET_TDSR_X_DES_START_MASK) +/*! @} */ + +/*! @name MRBR - Maximum Receive Buffer Size Register */ +/*! @{ */ +#define ENET_MRBR_R_BUF_SIZE_MASK (0x3FF0U) +#define ENET_MRBR_R_BUF_SIZE_SHIFT (4U) +#define ENET_MRBR_R_BUF_SIZE(x) (((uint32_t)(((uint32_t)(x)) << ENET_MRBR_R_BUF_SIZE_SHIFT)) & ENET_MRBR_R_BUF_SIZE_MASK) +/*! @} */ + +/*! @name RSFL - Receive FIFO Section Full Threshold */ +/*! @{ */ +#define ENET_RSFL_RX_SECTION_FULL_MASK (0xFFU) +#define ENET_RSFL_RX_SECTION_FULL_SHIFT (0U) +#define ENET_RSFL_RX_SECTION_FULL(x) (((uint32_t)(((uint32_t)(x)) << ENET_RSFL_RX_SECTION_FULL_SHIFT)) & ENET_RSFL_RX_SECTION_FULL_MASK) +/*! @} */ + +/*! @name RSEM - Receive FIFO Section Empty Threshold */ +/*! @{ */ +#define ENET_RSEM_RX_SECTION_EMPTY_MASK (0xFFU) +#define ENET_RSEM_RX_SECTION_EMPTY_SHIFT (0U) +#define ENET_RSEM_RX_SECTION_EMPTY(x) (((uint32_t)(((uint32_t)(x)) << ENET_RSEM_RX_SECTION_EMPTY_SHIFT)) & ENET_RSEM_RX_SECTION_EMPTY_MASK) +#define ENET_RSEM_STAT_SECTION_EMPTY_MASK (0x1F0000U) +#define ENET_RSEM_STAT_SECTION_EMPTY_SHIFT (16U) +#define ENET_RSEM_STAT_SECTION_EMPTY(x) (((uint32_t)(((uint32_t)(x)) << ENET_RSEM_STAT_SECTION_EMPTY_SHIFT)) & ENET_RSEM_STAT_SECTION_EMPTY_MASK) +/*! @} */ + +/*! @name RAEM - Receive FIFO Almost Empty Threshold */ +/*! @{ */ +#define ENET_RAEM_RX_ALMOST_EMPTY_MASK (0xFFU) +#define ENET_RAEM_RX_ALMOST_EMPTY_SHIFT (0U) +#define ENET_RAEM_RX_ALMOST_EMPTY(x) (((uint32_t)(((uint32_t)(x)) << ENET_RAEM_RX_ALMOST_EMPTY_SHIFT)) & ENET_RAEM_RX_ALMOST_EMPTY_MASK) +/*! @} */ + +/*! @name RAFL - Receive FIFO Almost Full Threshold */ +/*! @{ */ +#define ENET_RAFL_RX_ALMOST_FULL_MASK (0xFFU) +#define ENET_RAFL_RX_ALMOST_FULL_SHIFT (0U) +#define ENET_RAFL_RX_ALMOST_FULL(x) (((uint32_t)(((uint32_t)(x)) << ENET_RAFL_RX_ALMOST_FULL_SHIFT)) & ENET_RAFL_RX_ALMOST_FULL_MASK) +/*! @} */ + +/*! @name TSEM - Transmit FIFO Section Empty Threshold */ +/*! @{ */ +#define ENET_TSEM_TX_SECTION_EMPTY_MASK (0xFFU) +#define ENET_TSEM_TX_SECTION_EMPTY_SHIFT (0U) +#define ENET_TSEM_TX_SECTION_EMPTY(x) (((uint32_t)(((uint32_t)(x)) << ENET_TSEM_TX_SECTION_EMPTY_SHIFT)) & ENET_TSEM_TX_SECTION_EMPTY_MASK) +/*! @} */ + +/*! @name TAEM - Transmit FIFO Almost Empty Threshold */ +/*! @{ */ +#define ENET_TAEM_TX_ALMOST_EMPTY_MASK (0xFFU) +#define ENET_TAEM_TX_ALMOST_EMPTY_SHIFT (0U) +#define ENET_TAEM_TX_ALMOST_EMPTY(x) (((uint32_t)(((uint32_t)(x)) << ENET_TAEM_TX_ALMOST_EMPTY_SHIFT)) & ENET_TAEM_TX_ALMOST_EMPTY_MASK) +/*! @} */ + +/*! @name TAFL - Transmit FIFO Almost Full Threshold */ +/*! @{ */ +#define ENET_TAFL_TX_ALMOST_FULL_MASK (0xFFU) +#define ENET_TAFL_TX_ALMOST_FULL_SHIFT (0U) +#define ENET_TAFL_TX_ALMOST_FULL(x) (((uint32_t)(((uint32_t)(x)) << ENET_TAFL_TX_ALMOST_FULL_SHIFT)) & ENET_TAFL_TX_ALMOST_FULL_MASK) +/*! @} */ + +/*! @name TIPG - Transmit Inter-Packet Gap */ +/*! @{ */ +#define ENET_TIPG_IPG_MASK (0x1FU) +#define ENET_TIPG_IPG_SHIFT (0U) +#define ENET_TIPG_IPG(x) (((uint32_t)(((uint32_t)(x)) << ENET_TIPG_IPG_SHIFT)) & ENET_TIPG_IPG_MASK) +/*! @} */ + +/*! @name FTRL - Frame Truncation Length */ +/*! @{ */ +#define ENET_FTRL_TRUNC_FL_MASK (0x3FFFU) +#define ENET_FTRL_TRUNC_FL_SHIFT (0U) +#define ENET_FTRL_TRUNC_FL(x) (((uint32_t)(((uint32_t)(x)) << ENET_FTRL_TRUNC_FL_SHIFT)) & ENET_FTRL_TRUNC_FL_MASK) +/*! @} */ + +/*! @name TACC - Transmit Accelerator Function Configuration */ +/*! @{ */ +#define ENET_TACC_SHIFT16_MASK (0x1U) +#define ENET_TACC_SHIFT16_SHIFT (0U) +/*! SHIFT16 - TX FIFO Shift-16 + * 0b0..Disabled. + * 0b1..Indicates to the transmit data FIFO that the written frames contain two additional octets before the frame data. This means the actual frame begins at bit 16 of the first word written into the FIFO. This function allows putting the frame payload on a 32-bit boundary in memory, as the 14-byte Ethernet header is extended to a 16-byte header. + */ +#define ENET_TACC_SHIFT16(x) (((uint32_t)(((uint32_t)(x)) << ENET_TACC_SHIFT16_SHIFT)) & ENET_TACC_SHIFT16_MASK) +#define ENET_TACC_IPCHK_MASK (0x8U) +#define ENET_TACC_IPCHK_SHIFT (3U) +/*! IPCHK + * 0b0..Checksum is not inserted. + * 0b1..If an IP frame is transmitted, the checksum is inserted automatically. The IP header checksum field must be cleared. If a non-IP frame is transmitted the frame is not modified. + */ +#define ENET_TACC_IPCHK(x) (((uint32_t)(((uint32_t)(x)) << ENET_TACC_IPCHK_SHIFT)) & ENET_TACC_IPCHK_MASK) +#define ENET_TACC_PROCHK_MASK (0x10U) +#define ENET_TACC_PROCHK_SHIFT (4U) +/*! PROCHK + * 0b0..Checksum not inserted. + * 0b1..If an IP frame with a known protocol is transmitted, the checksum is inserted automatically into the frame. The checksum field must be cleared. The other frames are not modified. + */ +#define ENET_TACC_PROCHK(x) (((uint32_t)(((uint32_t)(x)) << ENET_TACC_PROCHK_SHIFT)) & ENET_TACC_PROCHK_MASK) +/*! @} */ + +/*! @name RACC - Receive Accelerator Function Configuration */ +/*! @{ */ +#define ENET_RACC_PADREM_MASK (0x1U) +#define ENET_RACC_PADREM_SHIFT (0U) +/*! PADREM - Enable Padding Removal For Short IP Frames + * 0b0..Padding not removed. + * 0b1..Any bytes following the IP payload section of the frame are removed from the frame. + */ +#define ENET_RACC_PADREM(x) (((uint32_t)(((uint32_t)(x)) << ENET_RACC_PADREM_SHIFT)) & ENET_RACC_PADREM_MASK) +#define ENET_RACC_IPDIS_MASK (0x2U) +#define ENET_RACC_IPDIS_SHIFT (1U) +/*! IPDIS - Enable Discard Of Frames With Wrong IPv4 Header Checksum + * 0b0..Frames with wrong IPv4 header checksum are not discarded. + * 0b1..If an IPv4 frame is received with a mismatching header checksum, the frame is discarded. IPv6 has no header checksum and is not affected by this setting. Discarding is only available when the RX FIFO operates in store and forward mode (RSFL cleared). + */ +#define ENET_RACC_IPDIS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RACC_IPDIS_SHIFT)) & ENET_RACC_IPDIS_MASK) +#define ENET_RACC_PRODIS_MASK (0x4U) +#define ENET_RACC_PRODIS_SHIFT (2U) +/*! PRODIS - Enable Discard Of Frames With Wrong Protocol Checksum + * 0b0..Frames with wrong checksum are not discarded. + * 0b1..If a TCP/IP, UDP/IP, or ICMP/IP frame is received that has a wrong TCP, UDP, or ICMP checksum, the frame is discarded. Discarding is only available when the RX FIFO operates in store and forward mode (RSFL cleared). + */ +#define ENET_RACC_PRODIS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RACC_PRODIS_SHIFT)) & ENET_RACC_PRODIS_MASK) +#define ENET_RACC_LINEDIS_MASK (0x40U) +#define ENET_RACC_LINEDIS_SHIFT (6U) +/*! LINEDIS - Enable Discard Of Frames With MAC Layer Errors + * 0b0..Frames with errors are not discarded. + * 0b1..Any frame received with a CRC, length, or PHY error is automatically discarded and not forwarded to the user application interface. + */ +#define ENET_RACC_LINEDIS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RACC_LINEDIS_SHIFT)) & ENET_RACC_LINEDIS_MASK) +#define ENET_RACC_SHIFT16_MASK (0x80U) +#define ENET_RACC_SHIFT16_SHIFT (7U) +/*! SHIFT16 - RX FIFO Shift-16 + * 0b0..Disabled. + * 0b1..Instructs the MAC to write two additional bytes in front of each frame received into the RX FIFO. + */ +#define ENET_RACC_SHIFT16(x) (((uint32_t)(((uint32_t)(x)) << ENET_RACC_SHIFT16_SHIFT)) & ENET_RACC_SHIFT16_MASK) +/*! @} */ + +/*! @name RMON_T_PACKETS - Tx Packet Count Statistic Register */ +/*! @{ */ +#define ENET_RMON_T_PACKETS_TXPKTS_MASK (0xFFFFU) +#define ENET_RMON_T_PACKETS_TXPKTS_SHIFT (0U) +#define ENET_RMON_T_PACKETS_TXPKTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_T_PACKETS_TXPKTS_SHIFT)) & ENET_RMON_T_PACKETS_TXPKTS_MASK) +/*! @} */ + +/*! @name RMON_T_BC_PKT - Tx Broadcast Packets Statistic Register */ +/*! @{ */ +#define ENET_RMON_T_BC_PKT_TXPKTS_MASK (0xFFFFU) +#define ENET_RMON_T_BC_PKT_TXPKTS_SHIFT (0U) +#define ENET_RMON_T_BC_PKT_TXPKTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_T_BC_PKT_TXPKTS_SHIFT)) & ENET_RMON_T_BC_PKT_TXPKTS_MASK) +/*! @} */ + +/*! @name RMON_T_MC_PKT - Tx Multicast Packets Statistic Register */ +/*! @{ */ +#define ENET_RMON_T_MC_PKT_TXPKTS_MASK (0xFFFFU) +#define ENET_RMON_T_MC_PKT_TXPKTS_SHIFT (0U) +#define ENET_RMON_T_MC_PKT_TXPKTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_T_MC_PKT_TXPKTS_SHIFT)) & ENET_RMON_T_MC_PKT_TXPKTS_MASK) +/*! @} */ + +/*! @name RMON_T_CRC_ALIGN - Tx Packets with CRC/Align Error Statistic Register */ +/*! @{ */ +#define ENET_RMON_T_CRC_ALIGN_TXPKTS_MASK (0xFFFFU) +#define ENET_RMON_T_CRC_ALIGN_TXPKTS_SHIFT (0U) +#define ENET_RMON_T_CRC_ALIGN_TXPKTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_T_CRC_ALIGN_TXPKTS_SHIFT)) & ENET_RMON_T_CRC_ALIGN_TXPKTS_MASK) +/*! @} */ + +/*! @name RMON_T_UNDERSIZE - Tx Packets Less Than Bytes and Good CRC Statistic Register */ +/*! @{ */ +#define ENET_RMON_T_UNDERSIZE_TXPKTS_MASK (0xFFFFU) +#define ENET_RMON_T_UNDERSIZE_TXPKTS_SHIFT (0U) +#define ENET_RMON_T_UNDERSIZE_TXPKTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_T_UNDERSIZE_TXPKTS_SHIFT)) & ENET_RMON_T_UNDERSIZE_TXPKTS_MASK) +/*! @} */ + +/*! @name RMON_T_OVERSIZE - Tx Packets GT MAX_FL bytes and Good CRC Statistic Register */ +/*! @{ */ +#define ENET_RMON_T_OVERSIZE_TXPKTS_MASK (0xFFFFU) +#define ENET_RMON_T_OVERSIZE_TXPKTS_SHIFT (0U) +#define ENET_RMON_T_OVERSIZE_TXPKTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_T_OVERSIZE_TXPKTS_SHIFT)) & ENET_RMON_T_OVERSIZE_TXPKTS_MASK) +/*! @} */ + +/*! @name RMON_T_FRAG - Tx Packets Less Than 64 Bytes and Bad CRC Statistic Register */ +/*! @{ */ +#define ENET_RMON_T_FRAG_TXPKTS_MASK (0xFFFFU) +#define ENET_RMON_T_FRAG_TXPKTS_SHIFT (0U) +#define ENET_RMON_T_FRAG_TXPKTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_T_FRAG_TXPKTS_SHIFT)) & ENET_RMON_T_FRAG_TXPKTS_MASK) +/*! @} */ + +/*! @name RMON_T_JAB - Tx Packets Greater Than MAX_FL bytes and Bad CRC Statistic Register */ +/*! @{ */ +#define ENET_RMON_T_JAB_TXPKTS_MASK (0xFFFFU) +#define ENET_RMON_T_JAB_TXPKTS_SHIFT (0U) +#define ENET_RMON_T_JAB_TXPKTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_T_JAB_TXPKTS_SHIFT)) & ENET_RMON_T_JAB_TXPKTS_MASK) +/*! @} */ + +/*! @name RMON_T_COL - Tx Collision Count Statistic Register */ +/*! @{ */ +#define ENET_RMON_T_COL_TXPKTS_MASK (0xFFFFU) +#define ENET_RMON_T_COL_TXPKTS_SHIFT (0U) +#define ENET_RMON_T_COL_TXPKTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_T_COL_TXPKTS_SHIFT)) & ENET_RMON_T_COL_TXPKTS_MASK) +/*! @} */ + +/*! @name RMON_T_P64 - Tx 64-Byte Packets Statistic Register */ +/*! @{ */ +#define ENET_RMON_T_P64_TXPKTS_MASK (0xFFFFU) +#define ENET_RMON_T_P64_TXPKTS_SHIFT (0U) +#define ENET_RMON_T_P64_TXPKTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_T_P64_TXPKTS_SHIFT)) & ENET_RMON_T_P64_TXPKTS_MASK) +/*! @} */ + +/*! @name RMON_T_P65TO127 - Tx 65- to 127-byte Packets Statistic Register */ +/*! @{ */ +#define ENET_RMON_T_P65TO127_TXPKTS_MASK (0xFFFFU) +#define ENET_RMON_T_P65TO127_TXPKTS_SHIFT (0U) +#define ENET_RMON_T_P65TO127_TXPKTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_T_P65TO127_TXPKTS_SHIFT)) & ENET_RMON_T_P65TO127_TXPKTS_MASK) +/*! @} */ + +/*! @name RMON_T_P128TO255 - Tx 128- to 255-byte Packets Statistic Register */ +/*! @{ */ +#define ENET_RMON_T_P128TO255_TXPKTS_MASK (0xFFFFU) +#define ENET_RMON_T_P128TO255_TXPKTS_SHIFT (0U) +#define ENET_RMON_T_P128TO255_TXPKTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_T_P128TO255_TXPKTS_SHIFT)) & ENET_RMON_T_P128TO255_TXPKTS_MASK) +/*! @} */ + +/*! @name RMON_T_P256TO511 - Tx 256- to 511-byte Packets Statistic Register */ +/*! @{ */ +#define ENET_RMON_T_P256TO511_TXPKTS_MASK (0xFFFFU) +#define ENET_RMON_T_P256TO511_TXPKTS_SHIFT (0U) +#define ENET_RMON_T_P256TO511_TXPKTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_T_P256TO511_TXPKTS_SHIFT)) & ENET_RMON_T_P256TO511_TXPKTS_MASK) +/*! @} */ + +/*! @name RMON_T_P512TO1023 - Tx 512- to 1023-byte Packets Statistic Register */ +/*! @{ */ +#define ENET_RMON_T_P512TO1023_TXPKTS_MASK (0xFFFFU) +#define ENET_RMON_T_P512TO1023_TXPKTS_SHIFT (0U) +#define ENET_RMON_T_P512TO1023_TXPKTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_T_P512TO1023_TXPKTS_SHIFT)) & ENET_RMON_T_P512TO1023_TXPKTS_MASK) +/*! @} */ + +/*! @name RMON_T_P1024TO2047 - Tx 1024- to 2047-byte Packets Statistic Register */ +/*! @{ */ +#define ENET_RMON_T_P1024TO2047_TXPKTS_MASK (0xFFFFU) +#define ENET_RMON_T_P1024TO2047_TXPKTS_SHIFT (0U) +#define ENET_RMON_T_P1024TO2047_TXPKTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_T_P1024TO2047_TXPKTS_SHIFT)) & ENET_RMON_T_P1024TO2047_TXPKTS_MASK) +/*! @} */ + +/*! @name RMON_T_P_GTE2048 - Tx Packets Greater Than 2048 Bytes Statistic Register */ +/*! @{ */ +#define ENET_RMON_T_P_GTE2048_TXPKTS_MASK (0xFFFFU) +#define ENET_RMON_T_P_GTE2048_TXPKTS_SHIFT (0U) +#define ENET_RMON_T_P_GTE2048_TXPKTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_T_P_GTE2048_TXPKTS_SHIFT)) & ENET_RMON_T_P_GTE2048_TXPKTS_MASK) +/*! @} */ + +/*! @name RMON_T_OCTETS - Tx Octets Statistic Register */ +/*! @{ */ +#define ENET_RMON_T_OCTETS_TXOCTS_MASK (0xFFFFFFFFU) +#define ENET_RMON_T_OCTETS_TXOCTS_SHIFT (0U) +#define ENET_RMON_T_OCTETS_TXOCTS(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_T_OCTETS_TXOCTS_SHIFT)) & ENET_RMON_T_OCTETS_TXOCTS_MASK) +/*! @} */ + +/*! @name IEEE_T_FRAME_OK - Frames Transmitted OK Statistic Register */ +/*! @{ */ +#define ENET_IEEE_T_FRAME_OK_COUNT_MASK (0xFFFFU) +#define ENET_IEEE_T_FRAME_OK_COUNT_SHIFT (0U) +#define ENET_IEEE_T_FRAME_OK_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_IEEE_T_FRAME_OK_COUNT_SHIFT)) & ENET_IEEE_T_FRAME_OK_COUNT_MASK) +/*! @} */ + +/*! @name IEEE_T_1COL - Frames Transmitted with Single Collision Statistic Register */ +/*! @{ */ +#define ENET_IEEE_T_1COL_COUNT_MASK (0xFFFFU) +#define ENET_IEEE_T_1COL_COUNT_SHIFT (0U) +#define ENET_IEEE_T_1COL_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_IEEE_T_1COL_COUNT_SHIFT)) & ENET_IEEE_T_1COL_COUNT_MASK) +/*! @} */ + +/*! @name IEEE_T_MCOL - Frames Transmitted with Multiple Collisions Statistic Register */ +/*! @{ */ +#define ENET_IEEE_T_MCOL_COUNT_MASK (0xFFFFU) +#define ENET_IEEE_T_MCOL_COUNT_SHIFT (0U) +#define ENET_IEEE_T_MCOL_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_IEEE_T_MCOL_COUNT_SHIFT)) & ENET_IEEE_T_MCOL_COUNT_MASK) +/*! @} */ + +/*! @name IEEE_T_DEF - Frames Transmitted after Deferral Delay Statistic Register */ +/*! @{ */ +#define ENET_IEEE_T_DEF_COUNT_MASK (0xFFFFU) +#define ENET_IEEE_T_DEF_COUNT_SHIFT (0U) +#define ENET_IEEE_T_DEF_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_IEEE_T_DEF_COUNT_SHIFT)) & ENET_IEEE_T_DEF_COUNT_MASK) +/*! @} */ + +/*! @name IEEE_T_LCOL - Frames Transmitted with Late Collision Statistic Register */ +/*! @{ */ +#define ENET_IEEE_T_LCOL_COUNT_MASK (0xFFFFU) +#define ENET_IEEE_T_LCOL_COUNT_SHIFT (0U) +#define ENET_IEEE_T_LCOL_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_IEEE_T_LCOL_COUNT_SHIFT)) & ENET_IEEE_T_LCOL_COUNT_MASK) +/*! @} */ + +/*! @name IEEE_T_EXCOL - Frames Transmitted with Excessive Collisions Statistic Register */ +/*! @{ */ +#define ENET_IEEE_T_EXCOL_COUNT_MASK (0xFFFFU) +#define ENET_IEEE_T_EXCOL_COUNT_SHIFT (0U) +#define ENET_IEEE_T_EXCOL_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_IEEE_T_EXCOL_COUNT_SHIFT)) & ENET_IEEE_T_EXCOL_COUNT_MASK) +/*! @} */ + +/*! @name IEEE_T_MACERR - Frames Transmitted with Tx FIFO Underrun Statistic Register */ +/*! @{ */ +#define ENET_IEEE_T_MACERR_COUNT_MASK (0xFFFFU) +#define ENET_IEEE_T_MACERR_COUNT_SHIFT (0U) +#define ENET_IEEE_T_MACERR_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_IEEE_T_MACERR_COUNT_SHIFT)) & ENET_IEEE_T_MACERR_COUNT_MASK) +/*! @} */ + +/*! @name IEEE_T_CSERR - Frames Transmitted with Carrier Sense Error Statistic Register */ +/*! @{ */ +#define ENET_IEEE_T_CSERR_COUNT_MASK (0xFFFFU) +#define ENET_IEEE_T_CSERR_COUNT_SHIFT (0U) +#define ENET_IEEE_T_CSERR_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_IEEE_T_CSERR_COUNT_SHIFT)) & ENET_IEEE_T_CSERR_COUNT_MASK) +/*! @} */ + +/*! @name IEEE_T_FDXFC - Flow Control Pause Frames Transmitted Statistic Register */ +/*! @{ */ +#define ENET_IEEE_T_FDXFC_COUNT_MASK (0xFFFFU) +#define ENET_IEEE_T_FDXFC_COUNT_SHIFT (0U) +#define ENET_IEEE_T_FDXFC_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_IEEE_T_FDXFC_COUNT_SHIFT)) & ENET_IEEE_T_FDXFC_COUNT_MASK) +/*! @} */ + +/*! @name IEEE_T_OCTETS_OK - Octet Count for Frames Transmitted w/o Error Statistic Register */ +/*! @{ */ +#define ENET_IEEE_T_OCTETS_OK_COUNT_MASK (0xFFFFFFFFU) +#define ENET_IEEE_T_OCTETS_OK_COUNT_SHIFT (0U) +#define ENET_IEEE_T_OCTETS_OK_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_IEEE_T_OCTETS_OK_COUNT_SHIFT)) & ENET_IEEE_T_OCTETS_OK_COUNT_MASK) +/*! @} */ + +/*! @name RMON_R_PACKETS - Rx Packet Count Statistic Register */ +/*! @{ */ +#define ENET_RMON_R_PACKETS_COUNT_MASK (0xFFFFU) +#define ENET_RMON_R_PACKETS_COUNT_SHIFT (0U) +#define ENET_RMON_R_PACKETS_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_R_PACKETS_COUNT_SHIFT)) & ENET_RMON_R_PACKETS_COUNT_MASK) +/*! @} */ + +/*! @name RMON_R_BC_PKT - Rx Broadcast Packets Statistic Register */ +/*! @{ */ +#define ENET_RMON_R_BC_PKT_COUNT_MASK (0xFFFFU) +#define ENET_RMON_R_BC_PKT_COUNT_SHIFT (0U) +#define ENET_RMON_R_BC_PKT_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_R_BC_PKT_COUNT_SHIFT)) & ENET_RMON_R_BC_PKT_COUNT_MASK) +/*! @} */ + +/*! @name RMON_R_MC_PKT - Rx Multicast Packets Statistic Register */ +/*! @{ */ +#define ENET_RMON_R_MC_PKT_COUNT_MASK (0xFFFFU) +#define ENET_RMON_R_MC_PKT_COUNT_SHIFT (0U) +#define ENET_RMON_R_MC_PKT_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_R_MC_PKT_COUNT_SHIFT)) & ENET_RMON_R_MC_PKT_COUNT_MASK) +/*! @} */ + +/*! @name RMON_R_CRC_ALIGN - Rx Packets with CRC/Align Error Statistic Register */ +/*! @{ */ +#define ENET_RMON_R_CRC_ALIGN_COUNT_MASK (0xFFFFU) +#define ENET_RMON_R_CRC_ALIGN_COUNT_SHIFT (0U) +#define ENET_RMON_R_CRC_ALIGN_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_R_CRC_ALIGN_COUNT_SHIFT)) & ENET_RMON_R_CRC_ALIGN_COUNT_MASK) +/*! @} */ + +/*! @name RMON_R_UNDERSIZE - Rx Packets with Less Than 64 Bytes and Good CRC Statistic Register */ +/*! @{ */ +#define ENET_RMON_R_UNDERSIZE_COUNT_MASK (0xFFFFU) +#define ENET_RMON_R_UNDERSIZE_COUNT_SHIFT (0U) +#define ENET_RMON_R_UNDERSIZE_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_R_UNDERSIZE_COUNT_SHIFT)) & ENET_RMON_R_UNDERSIZE_COUNT_MASK) +/*! @} */ + +/*! @name RMON_R_OVERSIZE - Rx Packets Greater Than MAX_FL and Good CRC Statistic Register */ +/*! @{ */ +#define ENET_RMON_R_OVERSIZE_COUNT_MASK (0xFFFFU) +#define ENET_RMON_R_OVERSIZE_COUNT_SHIFT (0U) +#define ENET_RMON_R_OVERSIZE_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_R_OVERSIZE_COUNT_SHIFT)) & ENET_RMON_R_OVERSIZE_COUNT_MASK) +/*! @} */ + +/*! @name RMON_R_FRAG - Rx Packets Less Than 64 Bytes and Bad CRC Statistic Register */ +/*! @{ */ +#define ENET_RMON_R_FRAG_COUNT_MASK (0xFFFFU) +#define ENET_RMON_R_FRAG_COUNT_SHIFT (0U) +#define ENET_RMON_R_FRAG_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_R_FRAG_COUNT_SHIFT)) & ENET_RMON_R_FRAG_COUNT_MASK) +/*! @} */ + +/*! @name RMON_R_JAB - Rx Packets Greater Than MAX_FL Bytes and Bad CRC Statistic Register */ +/*! @{ */ +#define ENET_RMON_R_JAB_COUNT_MASK (0xFFFFU) +#define ENET_RMON_R_JAB_COUNT_SHIFT (0U) +#define ENET_RMON_R_JAB_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_R_JAB_COUNT_SHIFT)) & ENET_RMON_R_JAB_COUNT_MASK) +/*! @} */ + +/*! @name RMON_R_P64 - Rx 64-Byte Packets Statistic Register */ +/*! @{ */ +#define ENET_RMON_R_P64_COUNT_MASK (0xFFFFU) +#define ENET_RMON_R_P64_COUNT_SHIFT (0U) +#define ENET_RMON_R_P64_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_R_P64_COUNT_SHIFT)) & ENET_RMON_R_P64_COUNT_MASK) +/*! @} */ + +/*! @name RMON_R_P65TO127 - Rx 65- to 127-Byte Packets Statistic Register */ +/*! @{ */ +#define ENET_RMON_R_P65TO127_COUNT_MASK (0xFFFFU) +#define ENET_RMON_R_P65TO127_COUNT_SHIFT (0U) +#define ENET_RMON_R_P65TO127_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_R_P65TO127_COUNT_SHIFT)) & ENET_RMON_R_P65TO127_COUNT_MASK) +/*! @} */ + +/*! @name RMON_R_P128TO255 - Rx 128- to 255-Byte Packets Statistic Register */ +/*! @{ */ +#define ENET_RMON_R_P128TO255_COUNT_MASK (0xFFFFU) +#define ENET_RMON_R_P128TO255_COUNT_SHIFT (0U) +#define ENET_RMON_R_P128TO255_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_R_P128TO255_COUNT_SHIFT)) & ENET_RMON_R_P128TO255_COUNT_MASK) +/*! @} */ + +/*! @name RMON_R_P256TO511 - Rx 256- to 511-Byte Packets Statistic Register */ +/*! @{ */ +#define ENET_RMON_R_P256TO511_COUNT_MASK (0xFFFFU) +#define ENET_RMON_R_P256TO511_COUNT_SHIFT (0U) +#define ENET_RMON_R_P256TO511_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_R_P256TO511_COUNT_SHIFT)) & ENET_RMON_R_P256TO511_COUNT_MASK) +/*! @} */ + +/*! @name RMON_R_P512TO1023 - Rx 512- to 1023-Byte Packets Statistic Register */ +/*! @{ */ +#define ENET_RMON_R_P512TO1023_COUNT_MASK (0xFFFFU) +#define ENET_RMON_R_P512TO1023_COUNT_SHIFT (0U) +#define ENET_RMON_R_P512TO1023_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_R_P512TO1023_COUNT_SHIFT)) & ENET_RMON_R_P512TO1023_COUNT_MASK) +/*! @} */ + +/*! @name RMON_R_P1024TO2047 - Rx 1024- to 2047-Byte Packets Statistic Register */ +/*! @{ */ +#define ENET_RMON_R_P1024TO2047_COUNT_MASK (0xFFFFU) +#define ENET_RMON_R_P1024TO2047_COUNT_SHIFT (0U) +#define ENET_RMON_R_P1024TO2047_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_R_P1024TO2047_COUNT_SHIFT)) & ENET_RMON_R_P1024TO2047_COUNT_MASK) +/*! @} */ + +/*! @name RMON_R_P_GTE2048 - Rx Packets Greater than 2048 Bytes Statistic Register */ +/*! @{ */ +#define ENET_RMON_R_P_GTE2048_COUNT_MASK (0xFFFFU) +#define ENET_RMON_R_P_GTE2048_COUNT_SHIFT (0U) +#define ENET_RMON_R_P_GTE2048_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_R_P_GTE2048_COUNT_SHIFT)) & ENET_RMON_R_P_GTE2048_COUNT_MASK) +/*! @} */ + +/*! @name RMON_R_OCTETS - Rx Octets Statistic Register */ +/*! @{ */ +#define ENET_RMON_R_OCTETS_COUNT_MASK (0xFFFFFFFFU) +#define ENET_RMON_R_OCTETS_COUNT_SHIFT (0U) +#define ENET_RMON_R_OCTETS_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_RMON_R_OCTETS_COUNT_SHIFT)) & ENET_RMON_R_OCTETS_COUNT_MASK) +/*! @} */ + +/*! @name IEEE_R_DROP - Frames not Counted Correctly Statistic Register */ +/*! @{ */ +#define ENET_IEEE_R_DROP_COUNT_MASK (0xFFFFU) +#define ENET_IEEE_R_DROP_COUNT_SHIFT (0U) +#define ENET_IEEE_R_DROP_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_IEEE_R_DROP_COUNT_SHIFT)) & ENET_IEEE_R_DROP_COUNT_MASK) +/*! @} */ + +/*! @name IEEE_R_FRAME_OK - Frames Received OK Statistic Register */ +/*! @{ */ +#define ENET_IEEE_R_FRAME_OK_COUNT_MASK (0xFFFFU) +#define ENET_IEEE_R_FRAME_OK_COUNT_SHIFT (0U) +#define ENET_IEEE_R_FRAME_OK_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_IEEE_R_FRAME_OK_COUNT_SHIFT)) & ENET_IEEE_R_FRAME_OK_COUNT_MASK) +/*! @} */ + +/*! @name IEEE_R_CRC - Frames Received with CRC Error Statistic Register */ +/*! @{ */ +#define ENET_IEEE_R_CRC_COUNT_MASK (0xFFFFU) +#define ENET_IEEE_R_CRC_COUNT_SHIFT (0U) +#define ENET_IEEE_R_CRC_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_IEEE_R_CRC_COUNT_SHIFT)) & ENET_IEEE_R_CRC_COUNT_MASK) +/*! @} */ + +/*! @name IEEE_R_ALIGN - Frames Received with Alignment Error Statistic Register */ +/*! @{ */ +#define ENET_IEEE_R_ALIGN_COUNT_MASK (0xFFFFU) +#define ENET_IEEE_R_ALIGN_COUNT_SHIFT (0U) +#define ENET_IEEE_R_ALIGN_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_IEEE_R_ALIGN_COUNT_SHIFT)) & ENET_IEEE_R_ALIGN_COUNT_MASK) +/*! @} */ + +/*! @name IEEE_R_MACERR - Receive FIFO Overflow Count Statistic Register */ +/*! @{ */ +#define ENET_IEEE_R_MACERR_COUNT_MASK (0xFFFFU) +#define ENET_IEEE_R_MACERR_COUNT_SHIFT (0U) +#define ENET_IEEE_R_MACERR_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_IEEE_R_MACERR_COUNT_SHIFT)) & ENET_IEEE_R_MACERR_COUNT_MASK) +/*! @} */ + +/*! @name IEEE_R_FDXFC - Flow Control Pause Frames Received Statistic Register */ +/*! @{ */ +#define ENET_IEEE_R_FDXFC_COUNT_MASK (0xFFFFU) +#define ENET_IEEE_R_FDXFC_COUNT_SHIFT (0U) +#define ENET_IEEE_R_FDXFC_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_IEEE_R_FDXFC_COUNT_SHIFT)) & ENET_IEEE_R_FDXFC_COUNT_MASK) +/*! @} */ + +/*! @name IEEE_R_OCTETS_OK - Octet Count for Frames Received without Error Statistic Register */ +/*! @{ */ +#define ENET_IEEE_R_OCTETS_OK_COUNT_MASK (0xFFFFFFFFU) +#define ENET_IEEE_R_OCTETS_OK_COUNT_SHIFT (0U) +#define ENET_IEEE_R_OCTETS_OK_COUNT(x) (((uint32_t)(((uint32_t)(x)) << ENET_IEEE_R_OCTETS_OK_COUNT_SHIFT)) & ENET_IEEE_R_OCTETS_OK_COUNT_MASK) +/*! @} */ + +/*! @name ATCR - Adjustable Timer Control Register */ +/*! @{ */ +#define ENET_ATCR_EN_MASK (0x1U) +#define ENET_ATCR_EN_SHIFT (0U) +/*! EN - Enable Timer + * 0b0..The timer stops at the current value. + * 0b1..The timer starts incrementing. + */ +#define ENET_ATCR_EN(x) (((uint32_t)(((uint32_t)(x)) << ENET_ATCR_EN_SHIFT)) & ENET_ATCR_EN_MASK) +#define ENET_ATCR_OFFEN_MASK (0x4U) +#define ENET_ATCR_OFFEN_SHIFT (2U) +/*! OFFEN - Enable One-Shot Offset Event + * 0b0..Disable. + * 0b1..The timer can be reset to zero when the given offset time is reached (offset event). The field is cleared when the offset event is reached, so no further event occurs until the field is set again. The timer offset value must be set before setting this field. + */ +#define ENET_ATCR_OFFEN(x) (((uint32_t)(((uint32_t)(x)) << ENET_ATCR_OFFEN_SHIFT)) & ENET_ATCR_OFFEN_MASK) +#define ENET_ATCR_OFFRST_MASK (0x8U) +#define ENET_ATCR_OFFRST_SHIFT (3U) +/*! OFFRST - Reset Timer On Offset Event + * 0b0..The timer is not affected and no action occurs, besides clearing OFFEN, when the offset is reached. + * 0b1..If OFFEN is set, the timer resets to zero when the offset setting is reached. The offset event does not cause a timer interrupt. + */ +#define ENET_ATCR_OFFRST(x) (((uint32_t)(((uint32_t)(x)) << ENET_ATCR_OFFRST_SHIFT)) & ENET_ATCR_OFFRST_MASK) +#define ENET_ATCR_PEREN_MASK (0x10U) +#define ENET_ATCR_PEREN_SHIFT (4U) +/*! PEREN - Enable Periodical Event + * 0b0..Disable. + * 0b1..A period event interrupt can be generated (EIR[TS_TIMER]) and the event signal output is asserted when the timer wraps around according to the periodic setting ATPER. The timer period value must be set before setting this bit. Not all devices contain the event signal output. See the chip configuration details. + */ +#define ENET_ATCR_PEREN(x) (((uint32_t)(((uint32_t)(x)) << ENET_ATCR_PEREN_SHIFT)) & ENET_ATCR_PEREN_MASK) +#define ENET_ATCR_PINPER_MASK (0x80U) +#define ENET_ATCR_PINPER_SHIFT (7U) +/*! PINPER + * 0b0..Disable. + * 0b1..Enable. + */ +#define ENET_ATCR_PINPER(x) (((uint32_t)(((uint32_t)(x)) << ENET_ATCR_PINPER_SHIFT)) & ENET_ATCR_PINPER_MASK) +#define ENET_ATCR_RESTART_MASK (0x200U) +#define ENET_ATCR_RESTART_SHIFT (9U) +#define ENET_ATCR_RESTART(x) (((uint32_t)(((uint32_t)(x)) << ENET_ATCR_RESTART_SHIFT)) & ENET_ATCR_RESTART_MASK) +#define ENET_ATCR_CAPTURE_MASK (0x800U) +#define ENET_ATCR_CAPTURE_SHIFT (11U) +/*! CAPTURE - Capture Timer Value + * 0b0..No effect. + * 0b1..The current time is captured and can be read from the ATVR register. + */ +#define ENET_ATCR_CAPTURE(x) (((uint32_t)(((uint32_t)(x)) << ENET_ATCR_CAPTURE_SHIFT)) & ENET_ATCR_CAPTURE_MASK) +#define ENET_ATCR_SLAVE_MASK (0x2000U) +#define ENET_ATCR_SLAVE_SHIFT (13U) +/*! SLAVE - Enable Timer Slave Mode + * 0b0..The timer is active and all configuration fields in this register are relevant. + * 0b1..The internal timer is disabled and the externally provided timer value is used. All other fields, except CAPTURE, in this register have no effect. CAPTURE can still be used to capture the current timer value. + */ +#define ENET_ATCR_SLAVE(x) (((uint32_t)(((uint32_t)(x)) << ENET_ATCR_SLAVE_SHIFT)) & ENET_ATCR_SLAVE_MASK) +/*! @} */ + +/*! @name ATVR - Timer Value Register */ +/*! @{ */ +#define ENET_ATVR_ATIME_MASK (0xFFFFFFFFU) +#define ENET_ATVR_ATIME_SHIFT (0U) +#define ENET_ATVR_ATIME(x) (((uint32_t)(((uint32_t)(x)) << ENET_ATVR_ATIME_SHIFT)) & ENET_ATVR_ATIME_MASK) +/*! @} */ + +/*! @name ATOFF - Timer Offset Register */ +/*! @{ */ +#define ENET_ATOFF_OFFSET_MASK (0xFFFFFFFFU) +#define ENET_ATOFF_OFFSET_SHIFT (0U) +#define ENET_ATOFF_OFFSET(x) (((uint32_t)(((uint32_t)(x)) << ENET_ATOFF_OFFSET_SHIFT)) & ENET_ATOFF_OFFSET_MASK) +/*! @} */ + +/*! @name ATPER - Timer Period Register */ +/*! @{ */ +#define ENET_ATPER_PERIOD_MASK (0xFFFFFFFFU) +#define ENET_ATPER_PERIOD_SHIFT (0U) +#define ENET_ATPER_PERIOD(x) (((uint32_t)(((uint32_t)(x)) << ENET_ATPER_PERIOD_SHIFT)) & ENET_ATPER_PERIOD_MASK) +/*! @} */ + +/*! @name ATCOR - Timer Correction Register */ +/*! @{ */ +#define ENET_ATCOR_COR_MASK (0x7FFFFFFFU) +#define ENET_ATCOR_COR_SHIFT (0U) +#define ENET_ATCOR_COR(x) (((uint32_t)(((uint32_t)(x)) << ENET_ATCOR_COR_SHIFT)) & ENET_ATCOR_COR_MASK) +/*! @} */ + +/*! @name ATINC - Time-Stamping Clock Period Register */ +/*! @{ */ +#define ENET_ATINC_INC_MASK (0x7FU) +#define ENET_ATINC_INC_SHIFT (0U) +#define ENET_ATINC_INC(x) (((uint32_t)(((uint32_t)(x)) << ENET_ATINC_INC_SHIFT)) & ENET_ATINC_INC_MASK) +#define ENET_ATINC_INC_CORR_MASK (0x7F00U) +#define ENET_ATINC_INC_CORR_SHIFT (8U) +#define ENET_ATINC_INC_CORR(x) (((uint32_t)(((uint32_t)(x)) << ENET_ATINC_INC_CORR_SHIFT)) & ENET_ATINC_INC_CORR_MASK) +/*! @} */ + +/*! @name ATSTMP - Timestamp of Last Transmitted Frame */ +/*! @{ */ +#define ENET_ATSTMP_TIMESTAMP_MASK (0xFFFFFFFFU) +#define ENET_ATSTMP_TIMESTAMP_SHIFT (0U) +#define ENET_ATSTMP_TIMESTAMP(x) (((uint32_t)(((uint32_t)(x)) << ENET_ATSTMP_TIMESTAMP_SHIFT)) & ENET_ATSTMP_TIMESTAMP_MASK) +/*! @} */ + +/*! @name TGSR - Timer Global Status Register */ +/*! @{ */ +#define ENET_TGSR_TF0_MASK (0x1U) +#define ENET_TGSR_TF0_SHIFT (0U) +/*! TF0 - Copy Of Timer Flag For Channel 0 + * 0b0..Timer Flag for Channel 0 is clear + * 0b1..Timer Flag for Channel 0 is set + */ +#define ENET_TGSR_TF0(x) (((uint32_t)(((uint32_t)(x)) << ENET_TGSR_TF0_SHIFT)) & ENET_TGSR_TF0_MASK) +#define ENET_TGSR_TF1_MASK (0x2U) +#define ENET_TGSR_TF1_SHIFT (1U) +/*! TF1 - Copy Of Timer Flag For Channel 1 + * 0b0..Timer Flag for Channel 1 is clear + * 0b1..Timer Flag for Channel 1 is set + */ +#define ENET_TGSR_TF1(x) (((uint32_t)(((uint32_t)(x)) << ENET_TGSR_TF1_SHIFT)) & ENET_TGSR_TF1_MASK) +#define ENET_TGSR_TF2_MASK (0x4U) +#define ENET_TGSR_TF2_SHIFT (2U) +/*! TF2 - Copy Of Timer Flag For Channel 2 + * 0b0..Timer Flag for Channel 2 is clear + * 0b1..Timer Flag for Channel 2 is set + */ +#define ENET_TGSR_TF2(x) (((uint32_t)(((uint32_t)(x)) << ENET_TGSR_TF2_SHIFT)) & ENET_TGSR_TF2_MASK) +#define ENET_TGSR_TF3_MASK (0x8U) +#define ENET_TGSR_TF3_SHIFT (3U) +/*! TF3 - Copy Of Timer Flag For Channel 3 + * 0b0..Timer Flag for Channel 3 is clear + * 0b1..Timer Flag for Channel 3 is set + */ +#define ENET_TGSR_TF3(x) (((uint32_t)(((uint32_t)(x)) << ENET_TGSR_TF3_SHIFT)) & ENET_TGSR_TF3_MASK) +/*! @} */ + +/*! @name TCSR - Timer Control Status Register */ +/*! @{ */ +#define ENET_TCSR_TDRE_MASK (0x1U) +#define ENET_TCSR_TDRE_SHIFT (0U) +/*! TDRE - Timer DMA Request Enable + * 0b0..DMA request is disabled + * 0b1..DMA request is enabled + */ +#define ENET_TCSR_TDRE(x) (((uint32_t)(((uint32_t)(x)) << ENET_TCSR_TDRE_SHIFT)) & ENET_TCSR_TDRE_MASK) +#define ENET_TCSR_TMODE_MASK (0x3CU) +#define ENET_TCSR_TMODE_SHIFT (2U) +/*! TMODE - Timer Mode + * 0b0000..Timer Channel is disabled. + * 0b0001..Timer Channel is configured for Input Capture on rising edge + * 0b0010..Timer Channel is configured for Input Capture on falling edge + * 0b0011..Timer Channel is configured for Input Capture on both edges + * 0b0100..Timer Channel is configured for Output Compare - software only + * 0b0101..Timer Channel is configured for Output Compare - toggle output on compare + * 0b0110..Timer Channel is configured for Output Compare - clear output on compare + * 0b0111..Timer Channel is configured for Output Compare - set output on compare + * 0b1000..Reserved + * 0b1010..Timer Channel is configured for Output Compare - clear output on compare, set output on overflow + * 0b10x1..Timer Channel is configured for Output Compare - set output on compare, clear output on overflow + * 0b1100..Reserved + * 0b1110..Timer Channel is configured for Output Compare - pulse output low on compare for one 1588 clock cycle + * 0b1111..Timer Channel is configured for Output Compare - pulse output high on compare for one 1588 clock cycle + */ +#define ENET_TCSR_TMODE(x) (((uint32_t)(((uint32_t)(x)) << ENET_TCSR_TMODE_SHIFT)) & ENET_TCSR_TMODE_MASK) +#define ENET_TCSR_TIE_MASK (0x40U) +#define ENET_TCSR_TIE_SHIFT (6U) +/*! TIE - Timer Interrupt Enable + * 0b0..Interrupt is disabled + * 0b1..Interrupt is enabled + */ +#define ENET_TCSR_TIE(x) (((uint32_t)(((uint32_t)(x)) << ENET_TCSR_TIE_SHIFT)) & ENET_TCSR_TIE_MASK) +#define ENET_TCSR_TF_MASK (0x80U) +#define ENET_TCSR_TF_SHIFT (7U) +/*! TF - Timer Flag + * 0b0..Input Capture or Output Compare has not occurred + * 0b1..Input Capture or Output Compare has occurred + */ +#define ENET_TCSR_TF(x) (((uint32_t)(((uint32_t)(x)) << ENET_TCSR_TF_SHIFT)) & ENET_TCSR_TF_MASK) +/*! @} */ + +/* The count of ENET_TCSR */ +#define ENET_TCSR_COUNT (4U) + +/*! @name TCCR - Timer Compare Capture Register */ +/*! @{ */ +#define ENET_TCCR_TCC_MASK (0xFFFFFFFFU) +#define ENET_TCCR_TCC_SHIFT (0U) +#define ENET_TCCR_TCC(x) (((uint32_t)(((uint32_t)(x)) << ENET_TCCR_TCC_SHIFT)) & ENET_TCCR_TCC_MASK) +/*! @} */ + +/* The count of ENET_TCCR */ +#define ENET_TCCR_COUNT (4U) + + +/*! + * @} + */ /* end of group ENET_Register_Masks */ + + +/* ENET - Peripheral instance base addresses */ +/** Peripheral ENET base address */ +#define ENET_BASE (0x400C0000u) +/** Peripheral ENET base pointer */ +#define ENET ((ENET_Type *)ENET_BASE) +/** Array initializer of ENET peripheral base addresses */ +#define ENET_BASE_ADDRS { ENET_BASE } +/** Array initializer of ENET peripheral base pointers */ +#define ENET_BASE_PTRS { ENET } +/** Interrupt vectors for the ENET peripheral type */ +#define ENET_Transmit_IRQS { ENET_Transmit_IRQn } +#define ENET_Receive_IRQS { ENET_Receive_IRQn } +#define ENET_Error_IRQS { ENET_Error_IRQn } +#define ENET_1588_Timer_IRQS { ENET_1588_Timer_IRQn } +/* ENET Buffer Descriptor and Buffer Address Alignment. */ +#define ENET_BUFF_ALIGNMENT (16U) + + +/*! + * @} + */ /* end of group ENET_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- EWM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup EWM_Peripheral_Access_Layer EWM Peripheral Access Layer + * @{ + */ + +/** EWM - Register Layout Typedef */ +typedef struct { + __IO uint8_t CTRL; /**< Control Register, offset: 0x0 */ + __O uint8_t SERV; /**< Service Register, offset: 0x1 */ + __IO uint8_t CMPL; /**< Compare Low Register, offset: 0x2 */ + __IO uint8_t CMPH; /**< Compare High Register, offset: 0x3 */ +} EWM_Type; + +/* ---------------------------------------------------------------------------- + -- EWM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup EWM_Register_Masks EWM Register Masks + * @{ + */ + +/*! @name CTRL - Control Register */ +/*! @{ */ +#define EWM_CTRL_EWMEN_MASK (0x1U) +#define EWM_CTRL_EWMEN_SHIFT (0U) +#define EWM_CTRL_EWMEN(x) (((uint8_t)(((uint8_t)(x)) << EWM_CTRL_EWMEN_SHIFT)) & EWM_CTRL_EWMEN_MASK) +#define EWM_CTRL_ASSIN_MASK (0x2U) +#define EWM_CTRL_ASSIN_SHIFT (1U) +#define EWM_CTRL_ASSIN(x) (((uint8_t)(((uint8_t)(x)) << EWM_CTRL_ASSIN_SHIFT)) & EWM_CTRL_ASSIN_MASK) +#define EWM_CTRL_INEN_MASK (0x4U) +#define EWM_CTRL_INEN_SHIFT (2U) +#define EWM_CTRL_INEN(x) (((uint8_t)(((uint8_t)(x)) << EWM_CTRL_INEN_SHIFT)) & EWM_CTRL_INEN_MASK) +#define EWM_CTRL_INTEN_MASK (0x8U) +#define EWM_CTRL_INTEN_SHIFT (3U) +#define EWM_CTRL_INTEN(x) (((uint8_t)(((uint8_t)(x)) << EWM_CTRL_INTEN_SHIFT)) & EWM_CTRL_INTEN_MASK) +/*! @} */ + +/*! @name SERV - Service Register */ +/*! @{ */ +#define EWM_SERV_SERVICE_MASK (0xFFU) +#define EWM_SERV_SERVICE_SHIFT (0U) +#define EWM_SERV_SERVICE(x) (((uint8_t)(((uint8_t)(x)) << EWM_SERV_SERVICE_SHIFT)) & EWM_SERV_SERVICE_MASK) +/*! @} */ + +/*! @name CMPL - Compare Low Register */ +/*! @{ */ +#define EWM_CMPL_COMPAREL_MASK (0xFFU) +#define EWM_CMPL_COMPAREL_SHIFT (0U) +#define EWM_CMPL_COMPAREL(x) (((uint8_t)(((uint8_t)(x)) << EWM_CMPL_COMPAREL_SHIFT)) & EWM_CMPL_COMPAREL_MASK) +/*! @} */ + +/*! @name CMPH - Compare High Register */ +/*! @{ */ +#define EWM_CMPH_COMPAREH_MASK (0xFFU) +#define EWM_CMPH_COMPAREH_SHIFT (0U) +#define EWM_CMPH_COMPAREH(x) (((uint8_t)(((uint8_t)(x)) << EWM_CMPH_COMPAREH_SHIFT)) & EWM_CMPH_COMPAREH_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group EWM_Register_Masks */ + + +/* EWM - Peripheral instance base addresses */ +/** Peripheral EWM base address */ +#define EWM_BASE (0x40061000u) +/** Peripheral EWM base pointer */ +#define EWM ((EWM_Type *)EWM_BASE) +/** Array initializer of EWM peripheral base addresses */ +#define EWM_BASE_ADDRS { EWM_BASE } +/** Array initializer of EWM peripheral base pointers */ +#define EWM_BASE_PTRS { EWM } +/** Interrupt vectors for the EWM peripheral type */ +#define EWM_IRQS { WDOG_EWM_IRQn } + +/*! + * @} + */ /* end of group EWM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- FB Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FB_Peripheral_Access_Layer FB Peripheral Access Layer + * @{ + */ + +/** FB - Register Layout Typedef */ +typedef struct { + struct { /* offset: 0x0, array step: 0xC */ + __IO uint32_t CSAR; /**< Chip Select Address Register, array offset: 0x0, array step: 0xC */ + __IO uint32_t CSMR; /**< Chip Select Mask Register, array offset: 0x4, array step: 0xC */ + __IO uint32_t CSCR; /**< Chip Select Control Register, array offset: 0x8, array step: 0xC */ + } CS[6]; + uint8_t RESERVED_0[24]; + __IO uint32_t CSPMCR; /**< Chip Select port Multiplexing Control Register, offset: 0x60 */ +} FB_Type; + +/* ---------------------------------------------------------------------------- + -- FB Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FB_Register_Masks FB Register Masks + * @{ + */ + +/*! @name CSAR - Chip Select Address Register */ +/*! @{ */ +#define FB_CSAR_BA_MASK (0xFFFF0000U) +#define FB_CSAR_BA_SHIFT (16U) +#define FB_CSAR_BA(x) (((uint32_t)(((uint32_t)(x)) << FB_CSAR_BA_SHIFT)) & FB_CSAR_BA_MASK) +/*! @} */ + +/* The count of FB_CSAR */ +#define FB_CSAR_COUNT (6U) + +/*! @name CSMR - Chip Select Mask Register */ +/*! @{ */ +#define FB_CSMR_V_MASK (0x1U) +#define FB_CSMR_V_SHIFT (0U) +/*! V - Valid + * 0b0..Chip-select is invalid. + * 0b1..Chip-select is valid. + */ +#define FB_CSMR_V(x) (((uint32_t)(((uint32_t)(x)) << FB_CSMR_V_SHIFT)) & FB_CSMR_V_MASK) +#define FB_CSMR_WP_MASK (0x100U) +#define FB_CSMR_WP_SHIFT (8U) +/*! WP - Write Protect + * 0b0..Write accesses are allowed. + * 0b1..Write accesses are not allowed. Attempting to write to the range of addresses for which the WP bit is set results in a bus error termination of the internal cycle and no external cycle. + */ +#define FB_CSMR_WP(x) (((uint32_t)(((uint32_t)(x)) << FB_CSMR_WP_SHIFT)) & FB_CSMR_WP_MASK) +#define FB_CSMR_BAM_MASK (0xFFFF0000U) +#define FB_CSMR_BAM_SHIFT (16U) +/*! BAM - Base Address Mask + * 0b0000000000000000..The corresponding address bit in CSAR is used in the chip-select decode. + * 0b0000000000000001..The corresponding address bit in CSAR is a don't care in the chip-select decode. + */ +#define FB_CSMR_BAM(x) (((uint32_t)(((uint32_t)(x)) << FB_CSMR_BAM_SHIFT)) & FB_CSMR_BAM_MASK) +/*! @} */ + +/* The count of FB_CSMR */ +#define FB_CSMR_COUNT (6U) + +/*! @name CSCR - Chip Select Control Register */ +/*! @{ */ +#define FB_CSCR_BSTW_MASK (0x8U) +#define FB_CSCR_BSTW_SHIFT (3U) +/*! BSTW - Burst-Write Enable + * 0b0..Disabled. Data exceeding the specified port size is broken into individual, port-sized, non-burst writes. For example, a 32-bit write to an 8-bit port takes four byte writes. + * 0b1..Enabled. Enables burst write of data larger than the specified port size, including 32-bit writes to 8- and 16-bit ports, 16-bit writes to 8-bit ports, and line writes to 8-, 16-, and 32-bit ports. + */ +#define FB_CSCR_BSTW(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_BSTW_SHIFT)) & FB_CSCR_BSTW_MASK) +#define FB_CSCR_BSTR_MASK (0x10U) +#define FB_CSCR_BSTR_SHIFT (4U) +/*! BSTR - Burst-Read Enable + * 0b0..Disabled. Data exceeding the specified port size is broken into individual, port-sized, non-burst reads. For example, a 32-bit read from an 8-bit port is broken into four 8-bit reads. + * 0b1..Enabled. Enables data burst reads larger than the specified port size, including 32-bit reads from 8- and 16-bit ports, 16-bit reads from 8-bit ports, and line reads from 8-, 16-, and 32-bit ports. + */ +#define FB_CSCR_BSTR(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_BSTR_SHIFT)) & FB_CSCR_BSTR_MASK) +#define FB_CSCR_BEM_MASK (0x20U) +#define FB_CSCR_BEM_SHIFT (5U) +/*! BEM - Byte-Enable Mode + * 0b0..FB_BE is asserted for data write only. + * 0b1..FB_BE is asserted for data read and write accesses. + */ +#define FB_CSCR_BEM(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_BEM_SHIFT)) & FB_CSCR_BEM_MASK) +#define FB_CSCR_PS_MASK (0xC0U) +#define FB_CSCR_PS_SHIFT (6U) +/*! PS - Port Size + * 0b00..32-bit port size. Valid data is sampled and driven on FB_D[31:0]. + * 0b01..8-bit port size. Valid data is sampled and driven on FB_D[31:24] when BLS is 0b, or FB_D[7:0] when BLS is 1b. + * 0b1x..16-bit port size. Valid data is sampled and driven on FB_D[31:16] when BLS is 0b, or FB_D[15:0] when BLS is 1b. + */ +#define FB_CSCR_PS(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_PS_SHIFT)) & FB_CSCR_PS_MASK) +#define FB_CSCR_AA_MASK (0x100U) +#define FB_CSCR_AA_SHIFT (8U) +/*! AA - Auto-Acknowledge Enable + * 0b0..Disabled. No internal transfer acknowledge is asserted and the cycle is terminated externally. + * 0b1..Enabled. Internal transfer acknowledge is asserted as specified by WS. + */ +#define FB_CSCR_AA(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_AA_SHIFT)) & FB_CSCR_AA_MASK) +#define FB_CSCR_BLS_MASK (0x200U) +#define FB_CSCR_BLS_SHIFT (9U) +/*! BLS - Byte-Lane Shift + * 0b0..Not shifted. Data is left-aligned on FB_AD. + * 0b1..Shifted. Data is right-aligned on FB_AD. + */ +#define FB_CSCR_BLS(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_BLS_SHIFT)) & FB_CSCR_BLS_MASK) +#define FB_CSCR_WS_MASK (0xFC00U) +#define FB_CSCR_WS_SHIFT (10U) +#define FB_CSCR_WS(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_WS_SHIFT)) & FB_CSCR_WS_MASK) +#define FB_CSCR_WRAH_MASK (0x30000U) +#define FB_CSCR_WRAH_SHIFT (16U) +/*! WRAH - Write Address Hold or Deselect + * 0b00..1 cycle (default for all but FB_CS0 ) + * 0b01..2 cycles + * 0b10..3 cycles + * 0b11..4 cycles (default for FB_CS0 ) + */ +#define FB_CSCR_WRAH(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_WRAH_SHIFT)) & FB_CSCR_WRAH_MASK) +#define FB_CSCR_RDAH_MASK (0xC0000U) +#define FB_CSCR_RDAH_SHIFT (18U) +/*! RDAH - Read Address Hold or Deselect + * 0b00..When AA is 0b, 1 cycle. When AA is 1b, 0 cycles. + * 0b01..When AA is 0b, 2 cycles. When AA is 1b, 1 cycle. + * 0b10..When AA is 0b, 3 cycles. When AA is 1b, 2 cycles. + * 0b11..When AA is 0b, 4 cycles. When AA is 1b, 3 cycles. + */ +#define FB_CSCR_RDAH(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_RDAH_SHIFT)) & FB_CSCR_RDAH_MASK) +#define FB_CSCR_ASET_MASK (0x300000U) +#define FB_CSCR_ASET_SHIFT (20U) +/*! ASET - Address Setup + * 0b00..Assert FB_CSn on the first rising clock edge after the address is asserted (default for all but FB_CS0 ). + * 0b01..Assert FB_CSn on the second rising clock edge after the address is asserted. + * 0b10..Assert FB_CSn on the third rising clock edge after the address is asserted. + * 0b11..Assert FB_CSn on the fourth rising clock edge after the address is asserted (default for FB_CS0 ). + */ +#define FB_CSCR_ASET(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_ASET_SHIFT)) & FB_CSCR_ASET_MASK) +#define FB_CSCR_EXTS_MASK (0x400000U) +#define FB_CSCR_EXTS_SHIFT (22U) +/*! EXTS + * 0b0..Disabled. FB_TS /FB_ALE asserts for one bus clock cycle. + * 0b1..Enabled. FB_TS /FB_ALE remains asserted until the first positive clock edge after FB_CSn asserts. + */ +#define FB_CSCR_EXTS(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_EXTS_SHIFT)) & FB_CSCR_EXTS_MASK) +#define FB_CSCR_SWSEN_MASK (0x800000U) +#define FB_CSCR_SWSEN_SHIFT (23U) +/*! SWSEN - Secondary Wait State Enable + * 0b0..Disabled. A number of wait states (specified by WS) are inserted before an internal transfer acknowledge is generated for all transfers. + * 0b1..Enabled. A number of wait states (specified by SWS) are inserted before an internal transfer acknowledge is generated for burst transfer secondary terminations. + */ +#define FB_CSCR_SWSEN(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_SWSEN_SHIFT)) & FB_CSCR_SWSEN_MASK) +#define FB_CSCR_SWS_MASK (0xFC000000U) +#define FB_CSCR_SWS_SHIFT (26U) +#define FB_CSCR_SWS(x) (((uint32_t)(((uint32_t)(x)) << FB_CSCR_SWS_SHIFT)) & FB_CSCR_SWS_MASK) +/*! @} */ + +/* The count of FB_CSCR */ +#define FB_CSCR_COUNT (6U) + +/*! @name CSPMCR - Chip Select port Multiplexing Control Register */ +/*! @{ */ +#define FB_CSPMCR_GROUP5_MASK (0xF000U) +#define FB_CSPMCR_GROUP5_SHIFT (12U) +/*! GROUP5 - FlexBus Signal Group 5 Multiplex control + * 0b0000..FB_TA + * 0b0001..FB_CS3 . You must also write 1b to CSCR[AA]. + * 0b0010..FB_BE_7_0 . You must also write 1b to CSCR[AA]. + */ +#define FB_CSPMCR_GROUP5(x) (((uint32_t)(((uint32_t)(x)) << FB_CSPMCR_GROUP5_SHIFT)) & FB_CSPMCR_GROUP5_MASK) +#define FB_CSPMCR_GROUP4_MASK (0xF0000U) +#define FB_CSPMCR_GROUP4_SHIFT (16U) +/*! GROUP4 - FlexBus Signal Group 4 Multiplex control + * 0b0000..FB_TBST + * 0b0001..FB_CS2 + * 0b0010..FB_BE_15_8 + */ +#define FB_CSPMCR_GROUP4(x) (((uint32_t)(((uint32_t)(x)) << FB_CSPMCR_GROUP4_SHIFT)) & FB_CSPMCR_GROUP4_MASK) +#define FB_CSPMCR_GROUP3_MASK (0xF00000U) +#define FB_CSPMCR_GROUP3_SHIFT (20U) +/*! GROUP3 - FlexBus Signal Group 3 Multiplex control + * 0b0000..FB_CS5 + * 0b0001..FB_TSIZ1 + * 0b0010..FB_BE_23_16 + */ +#define FB_CSPMCR_GROUP3(x) (((uint32_t)(((uint32_t)(x)) << FB_CSPMCR_GROUP3_SHIFT)) & FB_CSPMCR_GROUP3_MASK) +#define FB_CSPMCR_GROUP2_MASK (0xF000000U) +#define FB_CSPMCR_GROUP2_SHIFT (24U) +/*! GROUP2 - FlexBus Signal Group 2 Multiplex control + * 0b0000..FB_CS4 + * 0b0001..FB_TSIZ0 + * 0b0010..FB_BE_31_24 + */ +#define FB_CSPMCR_GROUP2(x) (((uint32_t)(((uint32_t)(x)) << FB_CSPMCR_GROUP2_SHIFT)) & FB_CSPMCR_GROUP2_MASK) +#define FB_CSPMCR_GROUP1_MASK (0xF0000000U) +#define FB_CSPMCR_GROUP1_SHIFT (28U) +/*! GROUP1 - FlexBus Signal Group 1 Multiplex control + * 0b0000..FB_ALE + * 0b0001..FB_CS1 + * 0b0010..FB_TS + */ +#define FB_CSPMCR_GROUP1(x) (((uint32_t)(((uint32_t)(x)) << FB_CSPMCR_GROUP1_SHIFT)) & FB_CSPMCR_GROUP1_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group FB_Register_Masks */ + + +/* FB - Peripheral instance base addresses */ +/** Peripheral FB base address */ +#define FB_BASE (0x4000C000u) +/** Peripheral FB base pointer */ +#define FB ((FB_Type *)FB_BASE) +/** Array initializer of FB peripheral base addresses */ +#define FB_BASE_ADDRS { FB_BASE } +/** Array initializer of FB peripheral base pointers */ +#define FB_BASE_PTRS { FB } + +/*! + * @} + */ /* end of group FB_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- FMC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FMC_Peripheral_Access_Layer FMC Peripheral Access Layer + * @{ + */ + +/** FMC - Register Layout Typedef */ +typedef struct { + __IO uint32_t PFAPR; /**< Flash Access Protection Register, offset: 0x0 */ + __IO uint32_t PFB0CR; /**< Flash Bank 0 Control Register, offset: 0x4 */ + __IO uint32_t PFB1CR; /**< Flash Bank 1 Control Register, offset: 0x8 */ + uint8_t RESERVED_0[244]; + __IO uint32_t TAGVDW0S[4]; /**< Cache Tag Storage, array offset: 0x100, array step: 0x4 */ + __IO uint32_t TAGVDW1S[4]; /**< Cache Tag Storage, array offset: 0x110, array step: 0x4 */ + __IO uint32_t TAGVDW2S[4]; /**< Cache Tag Storage, array offset: 0x120, array step: 0x4 */ + __IO uint32_t TAGVDW3S[4]; /**< Cache Tag Storage, array offset: 0x130, array step: 0x4 */ + uint8_t RESERVED_1[192]; + struct { /* offset: 0x200, array step: index*0x20, index2*0x8 */ + __IO uint32_t DATA_U; /**< Cache Data Storage (upper word), array offset: 0x200, array step: index*0x20, index2*0x8 */ + __IO uint32_t DATA_L; /**< Cache Data Storage (lower word), array offset: 0x204, array step: index*0x20, index2*0x8 */ + } SET[4][4]; +} FMC_Type; + +/* ---------------------------------------------------------------------------- + -- FMC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FMC_Register_Masks FMC Register Masks + * @{ + */ + +/*! @name PFAPR - Flash Access Protection Register */ +/*! @{ */ +#define FMC_PFAPR_M0AP_MASK (0x3U) +#define FMC_PFAPR_M0AP_SHIFT (0U) +/*! M0AP - Master 0 Access Protection + * 0b00..No access may be performed by this master + * 0b01..Only read accesses may be performed by this master + * 0b10..Only write accesses may be performed by this master + * 0b11..Both read and write accesses may be performed by this master + */ +#define FMC_PFAPR_M0AP(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M0AP_SHIFT)) & FMC_PFAPR_M0AP_MASK) +#define FMC_PFAPR_M1AP_MASK (0xCU) +#define FMC_PFAPR_M1AP_SHIFT (2U) +/*! M1AP - Master 1 Access Protection + * 0b00..No access may be performed by this master + * 0b01..Only read accesses may be performed by this master + * 0b10..Only write accesses may be performed by this master + * 0b11..Both read and write accesses may be performed by this master + */ +#define FMC_PFAPR_M1AP(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M1AP_SHIFT)) & FMC_PFAPR_M1AP_MASK) +#define FMC_PFAPR_M2AP_MASK (0x30U) +#define FMC_PFAPR_M2AP_SHIFT (4U) +/*! M2AP - Master 2 Access Protection + * 0b00..No access may be performed by this master + * 0b01..Only read accesses may be performed by this master + * 0b10..Only write accesses may be performed by this master + * 0b11..Both read and write accesses may be performed by this master + */ +#define FMC_PFAPR_M2AP(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M2AP_SHIFT)) & FMC_PFAPR_M2AP_MASK) +#define FMC_PFAPR_M3AP_MASK (0xC0U) +#define FMC_PFAPR_M3AP_SHIFT (6U) +/*! M3AP - Master 3 Access Protection + * 0b00..No access may be performed by this master + * 0b01..Only read accesses may be performed by this master + * 0b10..Only write accesses may be performed by this master + * 0b11..Both read and write accesses may be performed by this master + */ +#define FMC_PFAPR_M3AP(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M3AP_SHIFT)) & FMC_PFAPR_M3AP_MASK) +#define FMC_PFAPR_M4AP_MASK (0x300U) +#define FMC_PFAPR_M4AP_SHIFT (8U) +/*! M4AP - Master 4 Access Protection + * 0b00..No access may be performed by this master + * 0b01..Only read accesses may be performed by this master + * 0b10..Only write accesses may be performed by this master + * 0b11..Both read and write accesses may be performed by this master + */ +#define FMC_PFAPR_M4AP(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M4AP_SHIFT)) & FMC_PFAPR_M4AP_MASK) +#define FMC_PFAPR_M5AP_MASK (0xC00U) +#define FMC_PFAPR_M5AP_SHIFT (10U) +/*! M5AP - Master 5 Access Protection + * 0b00..No access may be performed by this master + * 0b01..Only read accesses may be performed by this master + * 0b10..Only write accesses may be performed by this master + * 0b11..Both read and write accesses may be performed by this master + */ +#define FMC_PFAPR_M5AP(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M5AP_SHIFT)) & FMC_PFAPR_M5AP_MASK) +#define FMC_PFAPR_M6AP_MASK (0x3000U) +#define FMC_PFAPR_M6AP_SHIFT (12U) +/*! M6AP - Master 6 Access Protection + * 0b00..No access may be performed by this master + * 0b01..Only read accesses may be performed by this master + * 0b10..Only write accesses may be performed by this master + * 0b11..Both read and write accesses may be performed by this master + */ +#define FMC_PFAPR_M6AP(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M6AP_SHIFT)) & FMC_PFAPR_M6AP_MASK) +#define FMC_PFAPR_M7AP_MASK (0xC000U) +#define FMC_PFAPR_M7AP_SHIFT (14U) +/*! M7AP - Master 7 Access Protection + * 0b00..No access may be performed by this master. + * 0b01..Only read accesses may be performed by this master. + * 0b10..Only write accesses may be performed by this master. + * 0b11..Both read and write accesses may be performed by this master. + */ +#define FMC_PFAPR_M7AP(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M7AP_SHIFT)) & FMC_PFAPR_M7AP_MASK) +#define FMC_PFAPR_M0PFD_MASK (0x10000U) +#define FMC_PFAPR_M0PFD_SHIFT (16U) +/*! M0PFD - Master 0 Prefetch Disable + * 0b0..Prefetching for this master is enabled. + * 0b1..Prefetching for this master is disabled. + */ +#define FMC_PFAPR_M0PFD(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M0PFD_SHIFT)) & FMC_PFAPR_M0PFD_MASK) +#define FMC_PFAPR_M1PFD_MASK (0x20000U) +#define FMC_PFAPR_M1PFD_SHIFT (17U) +/*! M1PFD - Master 1 Prefetch Disable + * 0b0..Prefetching for this master is enabled. + * 0b1..Prefetching for this master is disabled. + */ +#define FMC_PFAPR_M1PFD(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M1PFD_SHIFT)) & FMC_PFAPR_M1PFD_MASK) +#define FMC_PFAPR_M2PFD_MASK (0x40000U) +#define FMC_PFAPR_M2PFD_SHIFT (18U) +/*! M2PFD - Master 2 Prefetch Disable + * 0b0..Prefetching for this master is enabled. + * 0b1..Prefetching for this master is disabled. + */ +#define FMC_PFAPR_M2PFD(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M2PFD_SHIFT)) & FMC_PFAPR_M2PFD_MASK) +#define FMC_PFAPR_M3PFD_MASK (0x80000U) +#define FMC_PFAPR_M3PFD_SHIFT (19U) +/*! M3PFD - Master 3 Prefetch Disable + * 0b0..Prefetching for this master is enabled. + * 0b1..Prefetching for this master is disabled. + */ +#define FMC_PFAPR_M3PFD(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M3PFD_SHIFT)) & FMC_PFAPR_M3PFD_MASK) +#define FMC_PFAPR_M4PFD_MASK (0x100000U) +#define FMC_PFAPR_M4PFD_SHIFT (20U) +/*! M4PFD - Master 4 Prefetch Disable + * 0b0..Prefetching for this master is enabled. + * 0b1..Prefetching for this master is disabled. + */ +#define FMC_PFAPR_M4PFD(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M4PFD_SHIFT)) & FMC_PFAPR_M4PFD_MASK) +#define FMC_PFAPR_M5PFD_MASK (0x200000U) +#define FMC_PFAPR_M5PFD_SHIFT (21U) +/*! M5PFD - Master 5 Prefetch Disable + * 0b0..Prefetching for this master is enabled. + * 0b1..Prefetching for this master is disabled. + */ +#define FMC_PFAPR_M5PFD(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M5PFD_SHIFT)) & FMC_PFAPR_M5PFD_MASK) +#define FMC_PFAPR_M6PFD_MASK (0x400000U) +#define FMC_PFAPR_M6PFD_SHIFT (22U) +/*! M6PFD - Master 6 Prefetch Disable + * 0b0..Prefetching for this master is enabled. + * 0b1..Prefetching for this master is disabled. + */ +#define FMC_PFAPR_M6PFD(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M6PFD_SHIFT)) & FMC_PFAPR_M6PFD_MASK) +#define FMC_PFAPR_M7PFD_MASK (0x800000U) +#define FMC_PFAPR_M7PFD_SHIFT (23U) +/*! M7PFD - Master 7 Prefetch Disable + * 0b0..Prefetching for this master is enabled. + * 0b1..Prefetching for this master is disabled. + */ +#define FMC_PFAPR_M7PFD(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFAPR_M7PFD_SHIFT)) & FMC_PFAPR_M7PFD_MASK) +/*! @} */ + +/*! @name PFB0CR - Flash Bank 0 Control Register */ +/*! @{ */ +#define FMC_PFB0CR_B0SEBE_MASK (0x1U) +#define FMC_PFB0CR_B0SEBE_SHIFT (0U) +/*! B0SEBE - Bank 0 Single Entry Buffer Enable + * 0b0..Single entry buffer is disabled. + * 0b1..Single entry buffer is enabled. + */ +#define FMC_PFB0CR_B0SEBE(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_B0SEBE_SHIFT)) & FMC_PFB0CR_B0SEBE_MASK) +#define FMC_PFB0CR_B0IPE_MASK (0x2U) +#define FMC_PFB0CR_B0IPE_SHIFT (1U) +/*! B0IPE - Bank 0 Instruction Prefetch Enable + * 0b0..Do not prefetch in response to instruction fetches. + * 0b1..Enable prefetches in response to instruction fetches. + */ +#define FMC_PFB0CR_B0IPE(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_B0IPE_SHIFT)) & FMC_PFB0CR_B0IPE_MASK) +#define FMC_PFB0CR_B0DPE_MASK (0x4U) +#define FMC_PFB0CR_B0DPE_SHIFT (2U) +/*! B0DPE - Bank 0 Data Prefetch Enable + * 0b0..Do not prefetch in response to data references. + * 0b1..Enable prefetches in response to data references. + */ +#define FMC_PFB0CR_B0DPE(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_B0DPE_SHIFT)) & FMC_PFB0CR_B0DPE_MASK) +#define FMC_PFB0CR_B0ICE_MASK (0x8U) +#define FMC_PFB0CR_B0ICE_SHIFT (3U) +/*! B0ICE - Bank 0 Instruction Cache Enable + * 0b0..Do not cache instruction fetches. + * 0b1..Cache instruction fetches. + */ +#define FMC_PFB0CR_B0ICE(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_B0ICE_SHIFT)) & FMC_PFB0CR_B0ICE_MASK) +#define FMC_PFB0CR_B0DCE_MASK (0x10U) +#define FMC_PFB0CR_B0DCE_SHIFT (4U) +/*! B0DCE - Bank 0 Data Cache Enable + * 0b0..Do not cache data references. + * 0b1..Cache data references. + */ +#define FMC_PFB0CR_B0DCE(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_B0DCE_SHIFT)) & FMC_PFB0CR_B0DCE_MASK) +#define FMC_PFB0CR_CRC_MASK (0xE0U) +#define FMC_PFB0CR_CRC_SHIFT (5U) +/*! CRC - Cache Replacement Control + * 0b000..LRU replacement algorithm per set across all four ways + * 0b001..Reserved + * 0b010..Independent LRU with ways [0-1] for ifetches, [2-3] for data + * 0b011..Independent LRU with ways [0-2] for ifetches, [3] for data + * 0b1xx..Reserved + */ +#define FMC_PFB0CR_CRC(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_CRC_SHIFT)) & FMC_PFB0CR_CRC_MASK) +#define FMC_PFB0CR_B0MW_MASK (0x60000U) +#define FMC_PFB0CR_B0MW_SHIFT (17U) +/*! B0MW - Bank 0 Memory Width + * 0b00..32 bits + * 0b01..64 bits + * 0b10..128 bits + * 0b11..Reserved + */ +#define FMC_PFB0CR_B0MW(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_B0MW_SHIFT)) & FMC_PFB0CR_B0MW_MASK) +#define FMC_PFB0CR_S_B_INV_MASK (0x80000U) +#define FMC_PFB0CR_S_B_INV_SHIFT (19U) +/*! S_B_INV - Invalidate Prefetch Speculation Buffer + * 0b0..Speculation buffer and single entry buffer are not affected. + * 0b1..Invalidate (clear) speculation buffer and single entry buffer. + */ +#define FMC_PFB0CR_S_B_INV(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_S_B_INV_SHIFT)) & FMC_PFB0CR_S_B_INV_MASK) +#define FMC_PFB0CR_CINV_WAY_MASK (0xF00000U) +#define FMC_PFB0CR_CINV_WAY_SHIFT (20U) +/*! CINV_WAY - Cache Invalidate Way x + * 0b0000..No cache way invalidation for the corresponding cache + * 0b0001..Invalidate cache way for the corresponding cache: clear the tag, data, and vld bits of ways selected + */ +#define FMC_PFB0CR_CINV_WAY(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_CINV_WAY_SHIFT)) & FMC_PFB0CR_CINV_WAY_MASK) +#define FMC_PFB0CR_CLCK_WAY_MASK (0xF000000U) +#define FMC_PFB0CR_CLCK_WAY_SHIFT (24U) +/*! CLCK_WAY - Cache Lock Way x + * 0b0000..Cache way is unlocked and may be displaced + * 0b0001..Cache way is locked and its contents are not displaced + */ +#define FMC_PFB0CR_CLCK_WAY(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_CLCK_WAY_SHIFT)) & FMC_PFB0CR_CLCK_WAY_MASK) +#define FMC_PFB0CR_B0RWSC_MASK (0xF0000000U) +#define FMC_PFB0CR_B0RWSC_SHIFT (28U) +#define FMC_PFB0CR_B0RWSC(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB0CR_B0RWSC_SHIFT)) & FMC_PFB0CR_B0RWSC_MASK) +/*! @} */ + +/*! @name PFB1CR - Flash Bank 1 Control Register */ +/*! @{ */ +#define FMC_PFB1CR_B1SEBE_MASK (0x1U) +#define FMC_PFB1CR_B1SEBE_SHIFT (0U) +/*! B1SEBE - Bank 1 Single Entry Buffer Enable + * 0b0..Single entry buffer is disabled. + * 0b1..Single entry buffer is enabled. + */ +#define FMC_PFB1CR_B1SEBE(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB1CR_B1SEBE_SHIFT)) & FMC_PFB1CR_B1SEBE_MASK) +#define FMC_PFB1CR_B1IPE_MASK (0x2U) +#define FMC_PFB1CR_B1IPE_SHIFT (1U) +/*! B1IPE - Bank 1 Instruction Prefetch Enable + * 0b0..Do not prefetch in response to instruction fetches. + * 0b1..Enable prefetches in response to instruction fetches. + */ +#define FMC_PFB1CR_B1IPE(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB1CR_B1IPE_SHIFT)) & FMC_PFB1CR_B1IPE_MASK) +#define FMC_PFB1CR_B1DPE_MASK (0x4U) +#define FMC_PFB1CR_B1DPE_SHIFT (2U) +/*! B1DPE - Bank 1 Data Prefetch Enable + * 0b0..Do not prefetch in response to data references. + * 0b1..Enable prefetches in response to data references. + */ +#define FMC_PFB1CR_B1DPE(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB1CR_B1DPE_SHIFT)) & FMC_PFB1CR_B1DPE_MASK) +#define FMC_PFB1CR_B1ICE_MASK (0x8U) +#define FMC_PFB1CR_B1ICE_SHIFT (3U) +/*! B1ICE - Bank 1 Instruction Cache Enable + * 0b0..Do not cache instruction fetches. + * 0b1..Cache instruction fetches. + */ +#define FMC_PFB1CR_B1ICE(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB1CR_B1ICE_SHIFT)) & FMC_PFB1CR_B1ICE_MASK) +#define FMC_PFB1CR_B1DCE_MASK (0x10U) +#define FMC_PFB1CR_B1DCE_SHIFT (4U) +/*! B1DCE - Bank 1 Data Cache Enable + * 0b0..Do not cache data references. + * 0b1..Cache data references. + */ +#define FMC_PFB1CR_B1DCE(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB1CR_B1DCE_SHIFT)) & FMC_PFB1CR_B1DCE_MASK) +#define FMC_PFB1CR_B1MW_MASK (0x60000U) +#define FMC_PFB1CR_B1MW_SHIFT (17U) +/*! B1MW - Bank 1 Memory Width + * 0b00..32 bits + * 0b01..64 bits + * 0b10..128 bits + * 0b11..Reserved + */ +#define FMC_PFB1CR_B1MW(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB1CR_B1MW_SHIFT)) & FMC_PFB1CR_B1MW_MASK) +#define FMC_PFB1CR_B1RWSC_MASK (0xF0000000U) +#define FMC_PFB1CR_B1RWSC_SHIFT (28U) +#define FMC_PFB1CR_B1RWSC(x) (((uint32_t)(((uint32_t)(x)) << FMC_PFB1CR_B1RWSC_SHIFT)) & FMC_PFB1CR_B1RWSC_MASK) +/*! @} */ + +/*! @name TAGVDW0S - Cache Tag Storage */ +/*! @{ */ +#define FMC_TAGVDW0S_valid_MASK (0x1U) +#define FMC_TAGVDW0S_valid_SHIFT (0U) +#define FMC_TAGVDW0S_valid(x) (((uint32_t)(((uint32_t)(x)) << FMC_TAGVDW0S_valid_SHIFT)) & FMC_TAGVDW0S_valid_MASK) +#define FMC_TAGVDW0S_tag_MASK (0x7FFE0U) +#define FMC_TAGVDW0S_tag_SHIFT (5U) +#define FMC_TAGVDW0S_tag(x) (((uint32_t)(((uint32_t)(x)) << FMC_TAGVDW0S_tag_SHIFT)) & FMC_TAGVDW0S_tag_MASK) +/*! @} */ + +/* The count of FMC_TAGVDW0S */ +#define FMC_TAGVDW0S_COUNT (4U) + +/*! @name TAGVDW1S - Cache Tag Storage */ +/*! @{ */ +#define FMC_TAGVDW1S_valid_MASK (0x1U) +#define FMC_TAGVDW1S_valid_SHIFT (0U) +#define FMC_TAGVDW1S_valid(x) (((uint32_t)(((uint32_t)(x)) << FMC_TAGVDW1S_valid_SHIFT)) & FMC_TAGVDW1S_valid_MASK) +#define FMC_TAGVDW1S_tag_MASK (0x7FFE0U) +#define FMC_TAGVDW1S_tag_SHIFT (5U) +#define FMC_TAGVDW1S_tag(x) (((uint32_t)(((uint32_t)(x)) << FMC_TAGVDW1S_tag_SHIFT)) & FMC_TAGVDW1S_tag_MASK) +/*! @} */ + +/* The count of FMC_TAGVDW1S */ +#define FMC_TAGVDW1S_COUNT (4U) + +/*! @name TAGVDW2S - Cache Tag Storage */ +/*! @{ */ +#define FMC_TAGVDW2S_valid_MASK (0x1U) +#define FMC_TAGVDW2S_valid_SHIFT (0U) +#define FMC_TAGVDW2S_valid(x) (((uint32_t)(((uint32_t)(x)) << FMC_TAGVDW2S_valid_SHIFT)) & FMC_TAGVDW2S_valid_MASK) +#define FMC_TAGVDW2S_tag_MASK (0x7FFE0U) +#define FMC_TAGVDW2S_tag_SHIFT (5U) +#define FMC_TAGVDW2S_tag(x) (((uint32_t)(((uint32_t)(x)) << FMC_TAGVDW2S_tag_SHIFT)) & FMC_TAGVDW2S_tag_MASK) +/*! @} */ + +/* The count of FMC_TAGVDW2S */ +#define FMC_TAGVDW2S_COUNT (4U) + +/*! @name TAGVDW3S - Cache Tag Storage */ +/*! @{ */ +#define FMC_TAGVDW3S_valid_MASK (0x1U) +#define FMC_TAGVDW3S_valid_SHIFT (0U) +#define FMC_TAGVDW3S_valid(x) (((uint32_t)(((uint32_t)(x)) << FMC_TAGVDW3S_valid_SHIFT)) & FMC_TAGVDW3S_valid_MASK) +#define FMC_TAGVDW3S_tag_MASK (0x7FFE0U) +#define FMC_TAGVDW3S_tag_SHIFT (5U) +#define FMC_TAGVDW3S_tag(x) (((uint32_t)(((uint32_t)(x)) << FMC_TAGVDW3S_tag_SHIFT)) & FMC_TAGVDW3S_tag_MASK) +/*! @} */ + +/* The count of FMC_TAGVDW3S */ +#define FMC_TAGVDW3S_COUNT (4U) + +/*! @name DATA_U - Cache Data Storage (upper word) */ +/*! @{ */ +#define FMC_DATA_U_data_MASK (0xFFFFFFFFU) +#define FMC_DATA_U_data_SHIFT (0U) +#define FMC_DATA_U_data(x) (((uint32_t)(((uint32_t)(x)) << FMC_DATA_U_data_SHIFT)) & FMC_DATA_U_data_MASK) +/*! @} */ + +/* The count of FMC_DATA_U */ +#define FMC_DATA_U_COUNT (4U) + +/* The count of FMC_DATA_U */ +#define FMC_DATA_U_COUNT2 (4U) + +/*! @name DATA_L - Cache Data Storage (lower word) */ +/*! @{ */ +#define FMC_DATA_L_data_MASK (0xFFFFFFFFU) +#define FMC_DATA_L_data_SHIFT (0U) +#define FMC_DATA_L_data(x) (((uint32_t)(((uint32_t)(x)) << FMC_DATA_L_data_SHIFT)) & FMC_DATA_L_data_MASK) +/*! @} */ + +/* The count of FMC_DATA_L */ +#define FMC_DATA_L_COUNT (4U) + +/* The count of FMC_DATA_L */ +#define FMC_DATA_L_COUNT2 (4U) + + +/*! + * @} + */ /* end of group FMC_Register_Masks */ + + +/* FMC - Peripheral instance base addresses */ +/** Peripheral FMC base address */ +#define FMC_BASE (0x4001F000u) +/** Peripheral FMC base pointer */ +#define FMC ((FMC_Type *)FMC_BASE) +/** Array initializer of FMC peripheral base addresses */ +#define FMC_BASE_ADDRS { FMC_BASE } +/** Array initializer of FMC peripheral base pointers */ +#define FMC_BASE_PTRS { FMC } + +/*! + * @} + */ /* end of group FMC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- FTFE Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FTFE_Peripheral_Access_Layer FTFE Peripheral Access Layer + * @{ + */ + +/** FTFE - Register Layout Typedef */ +typedef struct { + __IO uint8_t FSTAT; /**< Flash Status Register, offset: 0x0 */ + __IO uint8_t FCNFG; /**< Flash Configuration Register, offset: 0x1 */ + __I uint8_t FSEC; /**< Flash Security Register, offset: 0x2 */ + __I uint8_t FOPT; /**< Flash Option Register, offset: 0x3 */ + __IO uint8_t FCCOB3; /**< Flash Common Command Object Registers, offset: 0x4 */ + __IO uint8_t FCCOB2; /**< Flash Common Command Object Registers, offset: 0x5 */ + __IO uint8_t FCCOB1; /**< Flash Common Command Object Registers, offset: 0x6 */ + __IO uint8_t FCCOB0; /**< Flash Common Command Object Registers, offset: 0x7 */ + __IO uint8_t FCCOB7; /**< Flash Common Command Object Registers, offset: 0x8 */ + __IO uint8_t FCCOB6; /**< Flash Common Command Object Registers, offset: 0x9 */ + __IO uint8_t FCCOB5; /**< Flash Common Command Object Registers, offset: 0xA */ + __IO uint8_t FCCOB4; /**< Flash Common Command Object Registers, offset: 0xB */ + __IO uint8_t FCCOBB; /**< Flash Common Command Object Registers, offset: 0xC */ + __IO uint8_t FCCOBA; /**< Flash Common Command Object Registers, offset: 0xD */ + __IO uint8_t FCCOB9; /**< Flash Common Command Object Registers, offset: 0xE */ + __IO uint8_t FCCOB8; /**< Flash Common Command Object Registers, offset: 0xF */ + __IO uint8_t FPROT3; /**< Program Flash Protection Registers, offset: 0x10 */ + __IO uint8_t FPROT2; /**< Program Flash Protection Registers, offset: 0x11 */ + __IO uint8_t FPROT1; /**< Program Flash Protection Registers, offset: 0x12 */ + __IO uint8_t FPROT0; /**< Program Flash Protection Registers, offset: 0x13 */ + uint8_t RESERVED_0[2]; + __IO uint8_t FEPROT; /**< EEPROM Protection Register, offset: 0x16 */ + __IO uint8_t FDPROT; /**< Data Flash Protection Register, offset: 0x17 */ +} FTFE_Type; + +/* ---------------------------------------------------------------------------- + -- FTFE Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FTFE_Register_Masks FTFE Register Masks + * @{ + */ + +/*! @name FSTAT - Flash Status Register */ +/*! @{ */ +#define FTFE_FSTAT_MGSTAT0_MASK (0x1U) +#define FTFE_FSTAT_MGSTAT0_SHIFT (0U) +#define FTFE_FSTAT_MGSTAT0(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FSTAT_MGSTAT0_SHIFT)) & FTFE_FSTAT_MGSTAT0_MASK) +#define FTFE_FSTAT_FPVIOL_MASK (0x10U) +#define FTFE_FSTAT_FPVIOL_SHIFT (4U) +/*! FPVIOL - Flash Protection Violation Flag + * 0b0..No protection violation detected + * 0b1..Protection violation detected + */ +#define FTFE_FSTAT_FPVIOL(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FSTAT_FPVIOL_SHIFT)) & FTFE_FSTAT_FPVIOL_MASK) +#define FTFE_FSTAT_ACCERR_MASK (0x20U) +#define FTFE_FSTAT_ACCERR_SHIFT (5U) +/*! ACCERR - Flash Access Error Flag + * 0b0..No access error detected + * 0b1..Access error detected + */ +#define FTFE_FSTAT_ACCERR(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FSTAT_ACCERR_SHIFT)) & FTFE_FSTAT_ACCERR_MASK) +#define FTFE_FSTAT_RDCOLERR_MASK (0x40U) +#define FTFE_FSTAT_RDCOLERR_SHIFT (6U) +/*! RDCOLERR - FTFE Read Collision Error Flag + * 0b0..No collision error detected + * 0b1..Collision error detected + */ +#define FTFE_FSTAT_RDCOLERR(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FSTAT_RDCOLERR_SHIFT)) & FTFE_FSTAT_RDCOLERR_MASK) +#define FTFE_FSTAT_CCIF_MASK (0x80U) +#define FTFE_FSTAT_CCIF_SHIFT (7U) +/*! CCIF - Command Complete Interrupt Flag + * 0b0..FTFE command or EEPROM file system operation in progress + * 0b1..FTFE command or EEPROM file system operation has completed + */ +#define FTFE_FSTAT_CCIF(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FSTAT_CCIF_SHIFT)) & FTFE_FSTAT_CCIF_MASK) +/*! @} */ + +/*! @name FCNFG - Flash Configuration Register */ +/*! @{ */ +#define FTFE_FCNFG_EEERDY_MASK (0x1U) +#define FTFE_FCNFG_EEERDY_SHIFT (0U) +/*! EEERDY + * 0b0..For devices with FlexNVM: FlexRAM is not available for EEPROM operation. + * 0b1..For devices with FlexNVM: FlexRAM is available for EEPROM operations where: reads from the FlexRAM return data previously written to the FlexRAM in EEPROM mode and writes launch an EEPROM operation to store the written data in the FlexRAM and EEPROM backup. + */ +#define FTFE_FCNFG_EEERDY(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCNFG_EEERDY_SHIFT)) & FTFE_FCNFG_EEERDY_MASK) +#define FTFE_FCNFG_RAMRDY_MASK (0x2U) +#define FTFE_FCNFG_RAMRDY_SHIFT (1U) +/*! RAMRDY - RAM Ready + * 0b0..For devices with FlexNVM: FlexRAM is not available for traditional RAM access. For devices without FlexNVM: Programming acceleration RAM is not available. + * 0b1..For devices with FlexNVM: FlexRAM is available as traditional RAM only; writes to the FlexRAM do not trigger EEPROM operations. For devices without FlexNVM: Programming acceleration RAM is available. + */ +#define FTFE_FCNFG_RAMRDY(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCNFG_RAMRDY_SHIFT)) & FTFE_FCNFG_RAMRDY_MASK) +#define FTFE_FCNFG_PFLSH_MASK (0x4U) +#define FTFE_FCNFG_PFLSH_SHIFT (2U) +/*! PFLSH - FTFE configuration + * 0b0..For devices with FlexNVM: FTFE configuration supports two program flash blocks and two FlexNVM blocks For devices with program flash only: Reserved + * 0b1..For devices with FlexNVM: Reserved For devices with program flash only: FTFE configuration supports four program flash blocks + */ +#define FTFE_FCNFG_PFLSH(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCNFG_PFLSH_SHIFT)) & FTFE_FCNFG_PFLSH_MASK) +#define FTFE_FCNFG_SWAP_MASK (0x8U) +#define FTFE_FCNFG_SWAP_SHIFT (3U) +/*! SWAP - Swap + * 0b0..For devices with FlexNVM: Program flash 0 block is located at relative address 0x0000 For devices with program flash only: Program flash 0 block is located at relative address 0x0000 + * 0b1..For devices with FlexNVM: Reserved For devices with program flash only: Program flash 1 block is located at relative address 0x0000 + */ +#define FTFE_FCNFG_SWAP(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCNFG_SWAP_SHIFT)) & FTFE_FCNFG_SWAP_MASK) +#define FTFE_FCNFG_ERSSUSP_MASK (0x10U) +#define FTFE_FCNFG_ERSSUSP_SHIFT (4U) +/*! ERSSUSP - Erase Suspend + * 0b0..No suspend requested + * 0b1..Suspend the current Erase Flash Sector command execution. + */ +#define FTFE_FCNFG_ERSSUSP(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCNFG_ERSSUSP_SHIFT)) & FTFE_FCNFG_ERSSUSP_MASK) +#define FTFE_FCNFG_ERSAREQ_MASK (0x20U) +#define FTFE_FCNFG_ERSAREQ_SHIFT (5U) +/*! ERSAREQ - Erase All Request + * 0b0..No request or request complete + * 0b1..Request to: run the Erase All Blocks command, verify the erased state, program the security byte in the Flash Configuration Field to the unsecure state, and release MCU security by setting the FSEC[SEC] field to the unsecure state. + */ +#define FTFE_FCNFG_ERSAREQ(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCNFG_ERSAREQ_SHIFT)) & FTFE_FCNFG_ERSAREQ_MASK) +#define FTFE_FCNFG_RDCOLLIE_MASK (0x40U) +#define FTFE_FCNFG_RDCOLLIE_SHIFT (6U) +/*! RDCOLLIE - Read Collision Error Interrupt Enable + * 0b0..Read collision error interrupt disabled + * 0b1..Read collision error interrupt enabled. An interrupt request is generated whenever an FTFE read collision error is detected (see the description of FSTAT[RDCOLERR]). + */ +#define FTFE_FCNFG_RDCOLLIE(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCNFG_RDCOLLIE_SHIFT)) & FTFE_FCNFG_RDCOLLIE_MASK) +#define FTFE_FCNFG_CCIE_MASK (0x80U) +#define FTFE_FCNFG_CCIE_SHIFT (7U) +/*! CCIE - Command Complete Interrupt Enable + * 0b0..Command complete interrupt disabled + * 0b1..Command complete interrupt enabled. An interrupt request is generated whenever the FSTAT[CCIF] flag is set. + */ +#define FTFE_FCNFG_CCIE(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCNFG_CCIE_SHIFT)) & FTFE_FCNFG_CCIE_MASK) +/*! @} */ + +/*! @name FSEC - Flash Security Register */ +/*! @{ */ +#define FTFE_FSEC_SEC_MASK (0x3U) +#define FTFE_FSEC_SEC_SHIFT (0U) +/*! SEC - Flash Security + * 0b00..MCU security status is secure + * 0b01..MCU security status is secure + * 0b10..MCU security status is unsecure (The standard shipping condition of the FTFE is unsecure.) + * 0b11..MCU security status is secure + */ +#define FTFE_FSEC_SEC(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FSEC_SEC_SHIFT)) & FTFE_FSEC_SEC_MASK) +#define FTFE_FSEC_FSLACC_MASK (0xCU) +#define FTFE_FSEC_FSLACC_SHIFT (2U) +/*! FSLACC - Freescale Failure Analysis Access Code + * 0b00..Freescale factory access granted + * 0b01..Freescale factory access denied + * 0b10..Freescale factory access denied + * 0b11..Freescale factory access granted + */ +#define FTFE_FSEC_FSLACC(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FSEC_FSLACC_SHIFT)) & FTFE_FSEC_FSLACC_MASK) +#define FTFE_FSEC_MEEN_MASK (0x30U) +#define FTFE_FSEC_MEEN_SHIFT (4U) +/*! MEEN - Mass Erase Enable Bits + * 0b00..Mass erase is enabled + * 0b01..Mass erase is enabled + * 0b10..Mass erase is disabled + * 0b11..Mass erase is enabled + */ +#define FTFE_FSEC_MEEN(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FSEC_MEEN_SHIFT)) & FTFE_FSEC_MEEN_MASK) +#define FTFE_FSEC_KEYEN_MASK (0xC0U) +#define FTFE_FSEC_KEYEN_SHIFT (6U) +/*! KEYEN - Backdoor Key Security Enable + * 0b00..Backdoor key access disabled + * 0b01..Backdoor key access disabled (preferred KEYEN state to disable backdoor key access) + * 0b10..Backdoor key access enabled + * 0b11..Backdoor key access disabled + */ +#define FTFE_FSEC_KEYEN(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FSEC_KEYEN_SHIFT)) & FTFE_FSEC_KEYEN_MASK) +/*! @} */ + +/*! @name FOPT - Flash Option Register */ +/*! @{ */ +#define FTFE_FOPT_OPT_MASK (0xFFU) +#define FTFE_FOPT_OPT_SHIFT (0U) +#define FTFE_FOPT_OPT(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FOPT_OPT_SHIFT)) & FTFE_FOPT_OPT_MASK) +/*! @} */ + +/*! @name FCCOB3 - Flash Common Command Object Registers */ +/*! @{ */ +#define FTFE_FCCOB3_CCOBn_MASK (0xFFU) +#define FTFE_FCCOB3_CCOBn_SHIFT (0U) +#define FTFE_FCCOB3_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCCOB3_CCOBn_SHIFT)) & FTFE_FCCOB3_CCOBn_MASK) +/*! @} */ + +/*! @name FCCOB2 - Flash Common Command Object Registers */ +/*! @{ */ +#define FTFE_FCCOB2_CCOBn_MASK (0xFFU) +#define FTFE_FCCOB2_CCOBn_SHIFT (0U) +#define FTFE_FCCOB2_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCCOB2_CCOBn_SHIFT)) & FTFE_FCCOB2_CCOBn_MASK) +/*! @} */ + +/*! @name FCCOB1 - Flash Common Command Object Registers */ +/*! @{ */ +#define FTFE_FCCOB1_CCOBn_MASK (0xFFU) +#define FTFE_FCCOB1_CCOBn_SHIFT (0U) +#define FTFE_FCCOB1_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCCOB1_CCOBn_SHIFT)) & FTFE_FCCOB1_CCOBn_MASK) +/*! @} */ + +/*! @name FCCOB0 - Flash Common Command Object Registers */ +/*! @{ */ +#define FTFE_FCCOB0_CCOBn_MASK (0xFFU) +#define FTFE_FCCOB0_CCOBn_SHIFT (0U) +#define FTFE_FCCOB0_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCCOB0_CCOBn_SHIFT)) & FTFE_FCCOB0_CCOBn_MASK) +/*! @} */ + +/*! @name FCCOB7 - Flash Common Command Object Registers */ +/*! @{ */ +#define FTFE_FCCOB7_CCOBn_MASK (0xFFU) +#define FTFE_FCCOB7_CCOBn_SHIFT (0U) +#define FTFE_FCCOB7_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCCOB7_CCOBn_SHIFT)) & FTFE_FCCOB7_CCOBn_MASK) +/*! @} */ + +/*! @name FCCOB6 - Flash Common Command Object Registers */ +/*! @{ */ +#define FTFE_FCCOB6_CCOBn_MASK (0xFFU) +#define FTFE_FCCOB6_CCOBn_SHIFT (0U) +#define FTFE_FCCOB6_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCCOB6_CCOBn_SHIFT)) & FTFE_FCCOB6_CCOBn_MASK) +/*! @} */ + +/*! @name FCCOB5 - Flash Common Command Object Registers */ +/*! @{ */ +#define FTFE_FCCOB5_CCOBn_MASK (0xFFU) +#define FTFE_FCCOB5_CCOBn_SHIFT (0U) +#define FTFE_FCCOB5_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCCOB5_CCOBn_SHIFT)) & FTFE_FCCOB5_CCOBn_MASK) +/*! @} */ + +/*! @name FCCOB4 - Flash Common Command Object Registers */ +/*! @{ */ +#define FTFE_FCCOB4_CCOBn_MASK (0xFFU) +#define FTFE_FCCOB4_CCOBn_SHIFT (0U) +#define FTFE_FCCOB4_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCCOB4_CCOBn_SHIFT)) & FTFE_FCCOB4_CCOBn_MASK) +/*! @} */ + +/*! @name FCCOBB - Flash Common Command Object Registers */ +/*! @{ */ +#define FTFE_FCCOBB_CCOBn_MASK (0xFFU) +#define FTFE_FCCOBB_CCOBn_SHIFT (0U) +#define FTFE_FCCOBB_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCCOBB_CCOBn_SHIFT)) & FTFE_FCCOBB_CCOBn_MASK) +/*! @} */ + +/*! @name FCCOBA - Flash Common Command Object Registers */ +/*! @{ */ +#define FTFE_FCCOBA_CCOBn_MASK (0xFFU) +#define FTFE_FCCOBA_CCOBn_SHIFT (0U) +#define FTFE_FCCOBA_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCCOBA_CCOBn_SHIFT)) & FTFE_FCCOBA_CCOBn_MASK) +/*! @} */ + +/*! @name FCCOB9 - Flash Common Command Object Registers */ +/*! @{ */ +#define FTFE_FCCOB9_CCOBn_MASK (0xFFU) +#define FTFE_FCCOB9_CCOBn_SHIFT (0U) +#define FTFE_FCCOB9_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCCOB9_CCOBn_SHIFT)) & FTFE_FCCOB9_CCOBn_MASK) +/*! @} */ + +/*! @name FCCOB8 - Flash Common Command Object Registers */ +/*! @{ */ +#define FTFE_FCCOB8_CCOBn_MASK (0xFFU) +#define FTFE_FCCOB8_CCOBn_SHIFT (0U) +#define FTFE_FCCOB8_CCOBn(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FCCOB8_CCOBn_SHIFT)) & FTFE_FCCOB8_CCOBn_MASK) +/*! @} */ + +/*! @name FPROT3 - Program Flash Protection Registers */ +/*! @{ */ +#define FTFE_FPROT3_PROT_MASK (0xFFU) +#define FTFE_FPROT3_PROT_SHIFT (0U) +/*! PROT - Program Flash Region Protect + * 0b00000000..Program flash region is protected. + * 0b00000001..Program flash region is not protected + */ +#define FTFE_FPROT3_PROT(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FPROT3_PROT_SHIFT)) & FTFE_FPROT3_PROT_MASK) +/*! @} */ + +/*! @name FPROT2 - Program Flash Protection Registers */ +/*! @{ */ +#define FTFE_FPROT2_PROT_MASK (0xFFU) +#define FTFE_FPROT2_PROT_SHIFT (0U) +/*! PROT - Program Flash Region Protect + * 0b00000000..Program flash region is protected. + * 0b00000001..Program flash region is not protected + */ +#define FTFE_FPROT2_PROT(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FPROT2_PROT_SHIFT)) & FTFE_FPROT2_PROT_MASK) +/*! @} */ + +/*! @name FPROT1 - Program Flash Protection Registers */ +/*! @{ */ +#define FTFE_FPROT1_PROT_MASK (0xFFU) +#define FTFE_FPROT1_PROT_SHIFT (0U) +/*! PROT - Program Flash Region Protect + * 0b00000000..Program flash region is protected. + * 0b00000001..Program flash region is not protected + */ +#define FTFE_FPROT1_PROT(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FPROT1_PROT_SHIFT)) & FTFE_FPROT1_PROT_MASK) +/*! @} */ + +/*! @name FPROT0 - Program Flash Protection Registers */ +/*! @{ */ +#define FTFE_FPROT0_PROT_MASK (0xFFU) +#define FTFE_FPROT0_PROT_SHIFT (0U) +/*! PROT - Program Flash Region Protect + * 0b00000000..Program flash region is protected. + * 0b00000001..Program flash region is not protected + */ +#define FTFE_FPROT0_PROT(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FPROT0_PROT_SHIFT)) & FTFE_FPROT0_PROT_MASK) +/*! @} */ + +/*! @name FEPROT - EEPROM Protection Register */ +/*! @{ */ +#define FTFE_FEPROT_EPROT_MASK (0xFFU) +#define FTFE_FEPROT_EPROT_SHIFT (0U) +/*! EPROT - EEPROM Region Protect + * 0b00000000..For devices with program flash only: Reserved For devices with FlexNVM: EEPROM region is protected + * 0b00000001..For devices with program flash only: Reserved For devices with FlexNVM: EEPROM region is not protected + */ +#define FTFE_FEPROT_EPROT(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FEPROT_EPROT_SHIFT)) & FTFE_FEPROT_EPROT_MASK) +/*! @} */ + +/*! @name FDPROT - Data Flash Protection Register */ +/*! @{ */ +#define FTFE_FDPROT_DPROT_MASK (0xFFU) +#define FTFE_FDPROT_DPROT_SHIFT (0U) +/*! DPROT - Data Flash Region Protect + * 0b00000000..Data Flash region is protected + * 0b00000001..Data Flash region is not protected + */ +#define FTFE_FDPROT_DPROT(x) (((uint8_t)(((uint8_t)(x)) << FTFE_FDPROT_DPROT_SHIFT)) & FTFE_FDPROT_DPROT_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group FTFE_Register_Masks */ + + +/* FTFE - Peripheral instance base addresses */ +/** Peripheral FTFE base address */ +#define FTFE_BASE (0x40020000u) +/** Peripheral FTFE base pointer */ +#define FTFE ((FTFE_Type *)FTFE_BASE) +/** Array initializer of FTFE peripheral base addresses */ +#define FTFE_BASE_ADDRS { FTFE_BASE } +/** Array initializer of FTFE peripheral base pointers */ +#define FTFE_BASE_PTRS { FTFE } +/** Interrupt vectors for the FTFE peripheral type */ +#define FTFE_COMMAND_COMPLETE_IRQS { FTFE_IRQn } +#define FTFE_READ_COLLISION_IRQS { Read_Collision_IRQn } + +/*! + * @} + */ /* end of group FTFE_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- FTM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FTM_Peripheral_Access_Layer FTM Peripheral Access Layer + * @{ + */ + +/** FTM - Register Layout Typedef */ +typedef struct { + __IO uint32_t SC; /**< Status And Control, offset: 0x0 */ + __IO uint32_t CNT; /**< Counter, offset: 0x4 */ + __IO uint32_t MOD; /**< Modulo, offset: 0x8 */ + struct { /* offset: 0xC, array step: 0x8 */ + __IO uint32_t CnSC; /**< Channel (n) Status And Control, array offset: 0xC, array step: 0x8 */ + __IO uint32_t CnV; /**< Channel (n) Value, array offset: 0x10, array step: 0x8 */ + } CONTROLS[8]; + __IO uint32_t CNTIN; /**< Counter Initial Value, offset: 0x4C */ + __IO uint32_t STATUS; /**< Capture And Compare Status, offset: 0x50 */ + __IO uint32_t MODE; /**< Features Mode Selection, offset: 0x54 */ + __IO uint32_t SYNC; /**< Synchronization, offset: 0x58 */ + __IO uint32_t OUTINIT; /**< Initial State For Channels Output, offset: 0x5C */ + __IO uint32_t OUTMASK; /**< Output Mask, offset: 0x60 */ + __IO uint32_t COMBINE; /**< Function For Linked Channels, offset: 0x64 */ + __IO uint32_t DEADTIME; /**< Deadtime Insertion Control, offset: 0x68 */ + __IO uint32_t EXTTRIG; /**< FTM External Trigger, offset: 0x6C */ + __IO uint32_t POL; /**< Channels Polarity, offset: 0x70 */ + __IO uint32_t FMS; /**< Fault Mode Status, offset: 0x74 */ + __IO uint32_t FILTER; /**< Input Capture Filter Control, offset: 0x78 */ + __IO uint32_t FLTCTRL; /**< Fault Control, offset: 0x7C */ + __IO uint32_t QDCTRL; /**< Quadrature Decoder Control And Status, offset: 0x80 */ + __IO uint32_t CONF; /**< Configuration, offset: 0x84 */ + __IO uint32_t FLTPOL; /**< FTM Fault Input Polarity, offset: 0x88 */ + __IO uint32_t SYNCONF; /**< Synchronization Configuration, offset: 0x8C */ + __IO uint32_t INVCTRL; /**< FTM Inverting Control, offset: 0x90 */ + __IO uint32_t SWOCTRL; /**< FTM Software Output Control, offset: 0x94 */ + __IO uint32_t PWMLOAD; /**< FTM PWM Load, offset: 0x98 */ +} FTM_Type; + +/* ---------------------------------------------------------------------------- + -- FTM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup FTM_Register_Masks FTM Register Masks + * @{ + */ + +/*! @name SC - Status And Control */ +/*! @{ */ +#define FTM_SC_PS_MASK (0x7U) +#define FTM_SC_PS_SHIFT (0U) +/*! PS - Prescale Factor Selection + * 0b000..Divide by 1 + * 0b001..Divide by 2 + * 0b010..Divide by 4 + * 0b011..Divide by 8 + * 0b100..Divide by 16 + * 0b101..Divide by 32 + * 0b110..Divide by 64 + * 0b111..Divide by 128 + */ +#define FTM_SC_PS(x) (((uint32_t)(((uint32_t)(x)) << FTM_SC_PS_SHIFT)) & FTM_SC_PS_MASK) +#define FTM_SC_CLKS_MASK (0x18U) +#define FTM_SC_CLKS_SHIFT (3U) +/*! CLKS - Clock Source Selection + * 0b00..No clock selected. This in effect disables the FTM counter. + * 0b01..System clock + * 0b10..Fixed frequency clock + * 0b11..External clock + */ +#define FTM_SC_CLKS(x) (((uint32_t)(((uint32_t)(x)) << FTM_SC_CLKS_SHIFT)) & FTM_SC_CLKS_MASK) +#define FTM_SC_CPWMS_MASK (0x20U) +#define FTM_SC_CPWMS_SHIFT (5U) +/*! CPWMS - Center-Aligned PWM Select + * 0b0..FTM counter operates in Up Counting mode. + * 0b1..FTM counter operates in Up-Down Counting mode. + */ +#define FTM_SC_CPWMS(x) (((uint32_t)(((uint32_t)(x)) << FTM_SC_CPWMS_SHIFT)) & FTM_SC_CPWMS_MASK) +#define FTM_SC_TOIE_MASK (0x40U) +#define FTM_SC_TOIE_SHIFT (6U) +/*! TOIE - Timer Overflow Interrupt Enable + * 0b0..Disable TOF interrupts. Use software polling. + * 0b1..Enable TOF interrupts. An interrupt is generated when TOF equals one. + */ +#define FTM_SC_TOIE(x) (((uint32_t)(((uint32_t)(x)) << FTM_SC_TOIE_SHIFT)) & FTM_SC_TOIE_MASK) +#define FTM_SC_TOF_MASK (0x80U) +#define FTM_SC_TOF_SHIFT (7U) +/*! TOF - Timer Overflow Flag + * 0b0..FTM counter has not overflowed. + * 0b1..FTM counter has overflowed. + */ +#define FTM_SC_TOF(x) (((uint32_t)(((uint32_t)(x)) << FTM_SC_TOF_SHIFT)) & FTM_SC_TOF_MASK) +/*! @} */ + +/*! @name CNT - Counter */ +/*! @{ */ +#define FTM_CNT_COUNT_MASK (0xFFFFU) +#define FTM_CNT_COUNT_SHIFT (0U) +#define FTM_CNT_COUNT(x) (((uint32_t)(((uint32_t)(x)) << FTM_CNT_COUNT_SHIFT)) & FTM_CNT_COUNT_MASK) +/*! @} */ + +/*! @name MOD - Modulo */ +/*! @{ */ +#define FTM_MOD_MOD_MASK (0xFFFFU) +#define FTM_MOD_MOD_SHIFT (0U) +#define FTM_MOD_MOD(x) (((uint32_t)(((uint32_t)(x)) << FTM_MOD_MOD_SHIFT)) & FTM_MOD_MOD_MASK) +/*! @} */ + +/*! @name CnSC - Channel (n) Status And Control */ +/*! @{ */ +#define FTM_CnSC_DMA_MASK (0x1U) +#define FTM_CnSC_DMA_SHIFT (0U) +/*! DMA - DMA Enable + * 0b0..Disable DMA transfers. + * 0b1..Enable DMA transfers. + */ +#define FTM_CnSC_DMA(x) (((uint32_t)(((uint32_t)(x)) << FTM_CnSC_DMA_SHIFT)) & FTM_CnSC_DMA_MASK) +#define FTM_CnSC_ELSA_MASK (0x4U) +#define FTM_CnSC_ELSA_SHIFT (2U) +#define FTM_CnSC_ELSA(x) (((uint32_t)(((uint32_t)(x)) << FTM_CnSC_ELSA_SHIFT)) & FTM_CnSC_ELSA_MASK) +#define FTM_CnSC_ELSB_MASK (0x8U) +#define FTM_CnSC_ELSB_SHIFT (3U) +#define FTM_CnSC_ELSB(x) (((uint32_t)(((uint32_t)(x)) << FTM_CnSC_ELSB_SHIFT)) & FTM_CnSC_ELSB_MASK) +#define FTM_CnSC_MSA_MASK (0x10U) +#define FTM_CnSC_MSA_SHIFT (4U) +#define FTM_CnSC_MSA(x) (((uint32_t)(((uint32_t)(x)) << FTM_CnSC_MSA_SHIFT)) & FTM_CnSC_MSA_MASK) +#define FTM_CnSC_MSB_MASK (0x20U) +#define FTM_CnSC_MSB_SHIFT (5U) +#define FTM_CnSC_MSB(x) (((uint32_t)(((uint32_t)(x)) << FTM_CnSC_MSB_SHIFT)) & FTM_CnSC_MSB_MASK) +#define FTM_CnSC_CHIE_MASK (0x40U) +#define FTM_CnSC_CHIE_SHIFT (6U) +/*! CHIE - Channel Interrupt Enable + * 0b0..Disable channel interrupts. Use software polling. + * 0b1..Enable channel interrupts. + */ +#define FTM_CnSC_CHIE(x) (((uint32_t)(((uint32_t)(x)) << FTM_CnSC_CHIE_SHIFT)) & FTM_CnSC_CHIE_MASK) +#define FTM_CnSC_CHF_MASK (0x80U) +#define FTM_CnSC_CHF_SHIFT (7U) +/*! CHF - Channel Flag + * 0b0..No channel event has occurred. + * 0b1..A channel event has occurred. + */ +#define FTM_CnSC_CHF(x) (((uint32_t)(((uint32_t)(x)) << FTM_CnSC_CHF_SHIFT)) & FTM_CnSC_CHF_MASK) +/*! @} */ + +/* The count of FTM_CnSC */ +#define FTM_CnSC_COUNT (8U) + +/*! @name CnV - Channel (n) Value */ +/*! @{ */ +#define FTM_CnV_VAL_MASK (0xFFFFU) +#define FTM_CnV_VAL_SHIFT (0U) +#define FTM_CnV_VAL(x) (((uint32_t)(((uint32_t)(x)) << FTM_CnV_VAL_SHIFT)) & FTM_CnV_VAL_MASK) +/*! @} */ + +/* The count of FTM_CnV */ +#define FTM_CnV_COUNT (8U) + +/*! @name CNTIN - Counter Initial Value */ +/*! @{ */ +#define FTM_CNTIN_INIT_MASK (0xFFFFU) +#define FTM_CNTIN_INIT_SHIFT (0U) +#define FTM_CNTIN_INIT(x) (((uint32_t)(((uint32_t)(x)) << FTM_CNTIN_INIT_SHIFT)) & FTM_CNTIN_INIT_MASK) +/*! @} */ + +/*! @name STATUS - Capture And Compare Status */ +/*! @{ */ +#define FTM_STATUS_CH0F_MASK (0x1U) +#define FTM_STATUS_CH0F_SHIFT (0U) +/*! CH0F - Channel 0 Flag + * 0b0..No channel event has occurred. + * 0b1..A channel event has occurred. + */ +#define FTM_STATUS_CH0F(x) (((uint32_t)(((uint32_t)(x)) << FTM_STATUS_CH0F_SHIFT)) & FTM_STATUS_CH0F_MASK) +#define FTM_STATUS_CH1F_MASK (0x2U) +#define FTM_STATUS_CH1F_SHIFT (1U) +/*! CH1F - Channel 1 Flag + * 0b0..No channel event has occurred. + * 0b1..A channel event has occurred. + */ +#define FTM_STATUS_CH1F(x) (((uint32_t)(((uint32_t)(x)) << FTM_STATUS_CH1F_SHIFT)) & FTM_STATUS_CH1F_MASK) +#define FTM_STATUS_CH2F_MASK (0x4U) +#define FTM_STATUS_CH2F_SHIFT (2U) +/*! CH2F - Channel 2 Flag + * 0b0..No channel event has occurred. + * 0b1..A channel event has occurred. + */ +#define FTM_STATUS_CH2F(x) (((uint32_t)(((uint32_t)(x)) << FTM_STATUS_CH2F_SHIFT)) & FTM_STATUS_CH2F_MASK) +#define FTM_STATUS_CH3F_MASK (0x8U) +#define FTM_STATUS_CH3F_SHIFT (3U) +/*! CH3F - Channel 3 Flag + * 0b0..No channel event has occurred. + * 0b1..A channel event has occurred. + */ +#define FTM_STATUS_CH3F(x) (((uint32_t)(((uint32_t)(x)) << FTM_STATUS_CH3F_SHIFT)) & FTM_STATUS_CH3F_MASK) +#define FTM_STATUS_CH4F_MASK (0x10U) +#define FTM_STATUS_CH4F_SHIFT (4U) +/*! CH4F - Channel 4 Flag + * 0b0..No channel event has occurred. + * 0b1..A channel event has occurred. + */ +#define FTM_STATUS_CH4F(x) (((uint32_t)(((uint32_t)(x)) << FTM_STATUS_CH4F_SHIFT)) & FTM_STATUS_CH4F_MASK) +#define FTM_STATUS_CH5F_MASK (0x20U) +#define FTM_STATUS_CH5F_SHIFT (5U) +/*! CH5F - Channel 5 Flag + * 0b0..No channel event has occurred. + * 0b1..A channel event has occurred. + */ +#define FTM_STATUS_CH5F(x) (((uint32_t)(((uint32_t)(x)) << FTM_STATUS_CH5F_SHIFT)) & FTM_STATUS_CH5F_MASK) +#define FTM_STATUS_CH6F_MASK (0x40U) +#define FTM_STATUS_CH6F_SHIFT (6U) +/*! CH6F - Channel 6 Flag + * 0b0..No channel event has occurred. + * 0b1..A channel event has occurred. + */ +#define FTM_STATUS_CH6F(x) (((uint32_t)(((uint32_t)(x)) << FTM_STATUS_CH6F_SHIFT)) & FTM_STATUS_CH6F_MASK) +#define FTM_STATUS_CH7F_MASK (0x80U) +#define FTM_STATUS_CH7F_SHIFT (7U) +/*! CH7F - Channel 7 Flag + * 0b0..No channel event has occurred. + * 0b1..A channel event has occurred. + */ +#define FTM_STATUS_CH7F(x) (((uint32_t)(((uint32_t)(x)) << FTM_STATUS_CH7F_SHIFT)) & FTM_STATUS_CH7F_MASK) +/*! @} */ + +/*! @name MODE - Features Mode Selection */ +/*! @{ */ +#define FTM_MODE_FTMEN_MASK (0x1U) +#define FTM_MODE_FTMEN_SHIFT (0U) +/*! FTMEN - FTM Enable + * 0b0..Only the TPM-compatible registers (first set of registers) can be used without any restriction. Do not use the FTM-specific registers. + * 0b1..All registers including the FTM-specific registers (second set of registers) are available for use with no restrictions. + */ +#define FTM_MODE_FTMEN(x) (((uint32_t)(((uint32_t)(x)) << FTM_MODE_FTMEN_SHIFT)) & FTM_MODE_FTMEN_MASK) +#define FTM_MODE_INIT_MASK (0x2U) +#define FTM_MODE_INIT_SHIFT (1U) +#define FTM_MODE_INIT(x) (((uint32_t)(((uint32_t)(x)) << FTM_MODE_INIT_SHIFT)) & FTM_MODE_INIT_MASK) +#define FTM_MODE_WPDIS_MASK (0x4U) +#define FTM_MODE_WPDIS_SHIFT (2U) +/*! WPDIS - Write Protection Disable + * 0b0..Write protection is enabled. + * 0b1..Write protection is disabled. + */ +#define FTM_MODE_WPDIS(x) (((uint32_t)(((uint32_t)(x)) << FTM_MODE_WPDIS_SHIFT)) & FTM_MODE_WPDIS_MASK) +#define FTM_MODE_PWMSYNC_MASK (0x8U) +#define FTM_MODE_PWMSYNC_SHIFT (3U) +/*! PWMSYNC - PWM Synchronization Mode + * 0b0..No restrictions. Software and hardware triggers can be used by MOD, CnV, OUTMASK, and FTM counter synchronization. + * 0b1..Software trigger can only be used by MOD and CnV synchronization, and hardware triggers can only be used by OUTMASK and FTM counter synchronization. + */ +#define FTM_MODE_PWMSYNC(x) (((uint32_t)(((uint32_t)(x)) << FTM_MODE_PWMSYNC_SHIFT)) & FTM_MODE_PWMSYNC_MASK) +#define FTM_MODE_CAPTEST_MASK (0x10U) +#define FTM_MODE_CAPTEST_SHIFT (4U) +/*! CAPTEST - Capture Test Mode Enable + * 0b0..Capture test mode is disabled. + * 0b1..Capture test mode is enabled. + */ +#define FTM_MODE_CAPTEST(x) (((uint32_t)(((uint32_t)(x)) << FTM_MODE_CAPTEST_SHIFT)) & FTM_MODE_CAPTEST_MASK) +#define FTM_MODE_FAULTM_MASK (0x60U) +#define FTM_MODE_FAULTM_SHIFT (5U) +/*! FAULTM - Fault Control Mode + * 0b00..Fault control is disabled for all channels. + * 0b01..Fault control is enabled for even channels only (channels 0, 2, 4, and 6), and the selected mode is the manual fault clearing. + * 0b10..Fault control is enabled for all channels, and the selected mode is the manual fault clearing. + * 0b11..Fault control is enabled for all channels, and the selected mode is the automatic fault clearing. + */ +#define FTM_MODE_FAULTM(x) (((uint32_t)(((uint32_t)(x)) << FTM_MODE_FAULTM_SHIFT)) & FTM_MODE_FAULTM_MASK) +#define FTM_MODE_FAULTIE_MASK (0x80U) +#define FTM_MODE_FAULTIE_SHIFT (7U) +/*! FAULTIE - Fault Interrupt Enable + * 0b0..Fault control interrupt is disabled. + * 0b1..Fault control interrupt is enabled. + */ +#define FTM_MODE_FAULTIE(x) (((uint32_t)(((uint32_t)(x)) << FTM_MODE_FAULTIE_SHIFT)) & FTM_MODE_FAULTIE_MASK) +/*! @} */ + +/*! @name SYNC - Synchronization */ +/*! @{ */ +#define FTM_SYNC_CNTMIN_MASK (0x1U) +#define FTM_SYNC_CNTMIN_SHIFT (0U) +/*! CNTMIN - Minimum Loading Point Enable + * 0b0..The minimum loading point is disabled. + * 0b1..The minimum loading point is enabled. + */ +#define FTM_SYNC_CNTMIN(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNC_CNTMIN_SHIFT)) & FTM_SYNC_CNTMIN_MASK) +#define FTM_SYNC_CNTMAX_MASK (0x2U) +#define FTM_SYNC_CNTMAX_SHIFT (1U) +/*! CNTMAX - Maximum Loading Point Enable + * 0b0..The maximum loading point is disabled. + * 0b1..The maximum loading point is enabled. + */ +#define FTM_SYNC_CNTMAX(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNC_CNTMAX_SHIFT)) & FTM_SYNC_CNTMAX_MASK) +#define FTM_SYNC_REINIT_MASK (0x4U) +#define FTM_SYNC_REINIT_SHIFT (2U) +/*! REINIT - FTM Counter Reinitialization By Synchronization (FTM counter synchronization) + * 0b0..FTM counter continues to count normally. + * 0b1..FTM counter is updated with its initial value when the selected trigger is detected. + */ +#define FTM_SYNC_REINIT(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNC_REINIT_SHIFT)) & FTM_SYNC_REINIT_MASK) +#define FTM_SYNC_SYNCHOM_MASK (0x8U) +#define FTM_SYNC_SYNCHOM_SHIFT (3U) +/*! SYNCHOM - Output Mask Synchronization + * 0b0..OUTMASK register is updated with the value of its buffer in all rising edges of the system clock. + * 0b1..OUTMASK register is updated with the value of its buffer only by the PWM synchronization. + */ +#define FTM_SYNC_SYNCHOM(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNC_SYNCHOM_SHIFT)) & FTM_SYNC_SYNCHOM_MASK) +#define FTM_SYNC_TRIG0_MASK (0x10U) +#define FTM_SYNC_TRIG0_SHIFT (4U) +/*! TRIG0 - PWM Synchronization Hardware Trigger 0 + * 0b0..Trigger is disabled. + * 0b1..Trigger is enabled. + */ +#define FTM_SYNC_TRIG0(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNC_TRIG0_SHIFT)) & FTM_SYNC_TRIG0_MASK) +#define FTM_SYNC_TRIG1_MASK (0x20U) +#define FTM_SYNC_TRIG1_SHIFT (5U) +/*! TRIG1 - PWM Synchronization Hardware Trigger 1 + * 0b0..Trigger is disabled. + * 0b1..Trigger is enabled. + */ +#define FTM_SYNC_TRIG1(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNC_TRIG1_SHIFT)) & FTM_SYNC_TRIG1_MASK) +#define FTM_SYNC_TRIG2_MASK (0x40U) +#define FTM_SYNC_TRIG2_SHIFT (6U) +/*! TRIG2 - PWM Synchronization Hardware Trigger 2 + * 0b0..Trigger is disabled. + * 0b1..Trigger is enabled. + */ +#define FTM_SYNC_TRIG2(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNC_TRIG2_SHIFT)) & FTM_SYNC_TRIG2_MASK) +#define FTM_SYNC_SWSYNC_MASK (0x80U) +#define FTM_SYNC_SWSYNC_SHIFT (7U) +/*! SWSYNC - PWM Synchronization Software Trigger + * 0b0..Software trigger is not selected. + * 0b1..Software trigger is selected. + */ +#define FTM_SYNC_SWSYNC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNC_SWSYNC_SHIFT)) & FTM_SYNC_SWSYNC_MASK) +/*! @} */ + +/*! @name OUTINIT - Initial State For Channels Output */ +/*! @{ */ +#define FTM_OUTINIT_CH0OI_MASK (0x1U) +#define FTM_OUTINIT_CH0OI_SHIFT (0U) +/*! CH0OI - Channel 0 Output Initialization Value + * 0b0..The initialization value is 0. + * 0b1..The initialization value is 1. + */ +#define FTM_OUTINIT_CH0OI(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTINIT_CH0OI_SHIFT)) & FTM_OUTINIT_CH0OI_MASK) +#define FTM_OUTINIT_CH1OI_MASK (0x2U) +#define FTM_OUTINIT_CH1OI_SHIFT (1U) +/*! CH1OI - Channel 1 Output Initialization Value + * 0b0..The initialization value is 0. + * 0b1..The initialization value is 1. + */ +#define FTM_OUTINIT_CH1OI(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTINIT_CH1OI_SHIFT)) & FTM_OUTINIT_CH1OI_MASK) +#define FTM_OUTINIT_CH2OI_MASK (0x4U) +#define FTM_OUTINIT_CH2OI_SHIFT (2U) +/*! CH2OI - Channel 2 Output Initialization Value + * 0b0..The initialization value is 0. + * 0b1..The initialization value is 1. + */ +#define FTM_OUTINIT_CH2OI(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTINIT_CH2OI_SHIFT)) & FTM_OUTINIT_CH2OI_MASK) +#define FTM_OUTINIT_CH3OI_MASK (0x8U) +#define FTM_OUTINIT_CH3OI_SHIFT (3U) +/*! CH3OI - Channel 3 Output Initialization Value + * 0b0..The initialization value is 0. + * 0b1..The initialization value is 1. + */ +#define FTM_OUTINIT_CH3OI(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTINIT_CH3OI_SHIFT)) & FTM_OUTINIT_CH3OI_MASK) +#define FTM_OUTINIT_CH4OI_MASK (0x10U) +#define FTM_OUTINIT_CH4OI_SHIFT (4U) +/*! CH4OI - Channel 4 Output Initialization Value + * 0b0..The initialization value is 0. + * 0b1..The initialization value is 1. + */ +#define FTM_OUTINIT_CH4OI(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTINIT_CH4OI_SHIFT)) & FTM_OUTINIT_CH4OI_MASK) +#define FTM_OUTINIT_CH5OI_MASK (0x20U) +#define FTM_OUTINIT_CH5OI_SHIFT (5U) +/*! CH5OI - Channel 5 Output Initialization Value + * 0b0..The initialization value is 0. + * 0b1..The initialization value is 1. + */ +#define FTM_OUTINIT_CH5OI(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTINIT_CH5OI_SHIFT)) & FTM_OUTINIT_CH5OI_MASK) +#define FTM_OUTINIT_CH6OI_MASK (0x40U) +#define FTM_OUTINIT_CH6OI_SHIFT (6U) +/*! CH6OI - Channel 6 Output Initialization Value + * 0b0..The initialization value is 0. + * 0b1..The initialization value is 1. + */ +#define FTM_OUTINIT_CH6OI(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTINIT_CH6OI_SHIFT)) & FTM_OUTINIT_CH6OI_MASK) +#define FTM_OUTINIT_CH7OI_MASK (0x80U) +#define FTM_OUTINIT_CH7OI_SHIFT (7U) +/*! CH7OI - Channel 7 Output Initialization Value + * 0b0..The initialization value is 0. + * 0b1..The initialization value is 1. + */ +#define FTM_OUTINIT_CH7OI(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTINIT_CH7OI_SHIFT)) & FTM_OUTINIT_CH7OI_MASK) +/*! @} */ + +/*! @name OUTMASK - Output Mask */ +/*! @{ */ +#define FTM_OUTMASK_CH0OM_MASK (0x1U) +#define FTM_OUTMASK_CH0OM_SHIFT (0U) +/*! CH0OM - Channel 0 Output Mask + * 0b0..Channel output is not masked. It continues to operate normally. + * 0b1..Channel output is masked. It is forced to its inactive state. + */ +#define FTM_OUTMASK_CH0OM(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTMASK_CH0OM_SHIFT)) & FTM_OUTMASK_CH0OM_MASK) +#define FTM_OUTMASK_CH1OM_MASK (0x2U) +#define FTM_OUTMASK_CH1OM_SHIFT (1U) +/*! CH1OM - Channel 1 Output Mask + * 0b0..Channel output is not masked. It continues to operate normally. + * 0b1..Channel output is masked. It is forced to its inactive state. + */ +#define FTM_OUTMASK_CH1OM(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTMASK_CH1OM_SHIFT)) & FTM_OUTMASK_CH1OM_MASK) +#define FTM_OUTMASK_CH2OM_MASK (0x4U) +#define FTM_OUTMASK_CH2OM_SHIFT (2U) +/*! CH2OM - Channel 2 Output Mask + * 0b0..Channel output is not masked. It continues to operate normally. + * 0b1..Channel output is masked. It is forced to its inactive state. + */ +#define FTM_OUTMASK_CH2OM(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTMASK_CH2OM_SHIFT)) & FTM_OUTMASK_CH2OM_MASK) +#define FTM_OUTMASK_CH3OM_MASK (0x8U) +#define FTM_OUTMASK_CH3OM_SHIFT (3U) +/*! CH3OM - Channel 3 Output Mask + * 0b0..Channel output is not masked. It continues to operate normally. + * 0b1..Channel output is masked. It is forced to its inactive state. + */ +#define FTM_OUTMASK_CH3OM(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTMASK_CH3OM_SHIFT)) & FTM_OUTMASK_CH3OM_MASK) +#define FTM_OUTMASK_CH4OM_MASK (0x10U) +#define FTM_OUTMASK_CH4OM_SHIFT (4U) +/*! CH4OM - Channel 4 Output Mask + * 0b0..Channel output is not masked. It continues to operate normally. + * 0b1..Channel output is masked. It is forced to its inactive state. + */ +#define FTM_OUTMASK_CH4OM(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTMASK_CH4OM_SHIFT)) & FTM_OUTMASK_CH4OM_MASK) +#define FTM_OUTMASK_CH5OM_MASK (0x20U) +#define FTM_OUTMASK_CH5OM_SHIFT (5U) +/*! CH5OM - Channel 5 Output Mask + * 0b0..Channel output is not masked. It continues to operate normally. + * 0b1..Channel output is masked. It is forced to its inactive state. + */ +#define FTM_OUTMASK_CH5OM(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTMASK_CH5OM_SHIFT)) & FTM_OUTMASK_CH5OM_MASK) +#define FTM_OUTMASK_CH6OM_MASK (0x40U) +#define FTM_OUTMASK_CH6OM_SHIFT (6U) +/*! CH6OM - Channel 6 Output Mask + * 0b0..Channel output is not masked. It continues to operate normally. + * 0b1..Channel output is masked. It is forced to its inactive state. + */ +#define FTM_OUTMASK_CH6OM(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTMASK_CH6OM_SHIFT)) & FTM_OUTMASK_CH6OM_MASK) +#define FTM_OUTMASK_CH7OM_MASK (0x80U) +#define FTM_OUTMASK_CH7OM_SHIFT (7U) +/*! CH7OM - Channel 7 Output Mask + * 0b0..Channel output is not masked. It continues to operate normally. + * 0b1..Channel output is masked. It is forced to its inactive state. + */ +#define FTM_OUTMASK_CH7OM(x) (((uint32_t)(((uint32_t)(x)) << FTM_OUTMASK_CH7OM_SHIFT)) & FTM_OUTMASK_CH7OM_MASK) +/*! @} */ + +/*! @name COMBINE - Function For Linked Channels */ +/*! @{ */ +#define FTM_COMBINE_COMBINE0_MASK (0x1U) +#define FTM_COMBINE_COMBINE0_SHIFT (0U) +/*! COMBINE0 - Combine Channels For n = 0 + * 0b0..Channels (n) and (n+1) are independent. + * 0b1..Channels (n) and (n+1) are combined. + */ +#define FTM_COMBINE_COMBINE0(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_COMBINE0_SHIFT)) & FTM_COMBINE_COMBINE0_MASK) +#define FTM_COMBINE_COMP0_MASK (0x2U) +#define FTM_COMBINE_COMP0_SHIFT (1U) +/*! COMP0 - Complement Of Channel (n) For n = 0 + * 0b0..The channel (n+1) output is the same as the channel (n) output. + * 0b1..The channel (n+1) output is the complement of the channel (n) output. + */ +#define FTM_COMBINE_COMP0(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_COMP0_SHIFT)) & FTM_COMBINE_COMP0_MASK) +#define FTM_COMBINE_DECAPEN0_MASK (0x4U) +#define FTM_COMBINE_DECAPEN0_SHIFT (2U) +/*! DECAPEN0 - Dual Edge Capture Mode Enable For n = 0 + * 0b0..The Dual Edge Capture mode in this pair of channels is disabled. + * 0b1..The Dual Edge Capture mode in this pair of channels is enabled. + */ +#define FTM_COMBINE_DECAPEN0(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DECAPEN0_SHIFT)) & FTM_COMBINE_DECAPEN0_MASK) +#define FTM_COMBINE_DECAP0_MASK (0x8U) +#define FTM_COMBINE_DECAP0_SHIFT (3U) +/*! DECAP0 - Dual Edge Capture Mode Captures For n = 0 + * 0b0..The dual edge captures are inactive. + * 0b1..The dual edge captures are active. + */ +#define FTM_COMBINE_DECAP0(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DECAP0_SHIFT)) & FTM_COMBINE_DECAP0_MASK) +#define FTM_COMBINE_DTEN0_MASK (0x10U) +#define FTM_COMBINE_DTEN0_SHIFT (4U) +/*! DTEN0 - Deadtime Enable For n = 0 + * 0b0..The deadtime insertion in this pair of channels is disabled. + * 0b1..The deadtime insertion in this pair of channels is enabled. + */ +#define FTM_COMBINE_DTEN0(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DTEN0_SHIFT)) & FTM_COMBINE_DTEN0_MASK) +#define FTM_COMBINE_SYNCEN0_MASK (0x20U) +#define FTM_COMBINE_SYNCEN0_SHIFT (5U) +/*! SYNCEN0 - Synchronization Enable For n = 0 + * 0b0..The PWM synchronization in this pair of channels is disabled. + * 0b1..The PWM synchronization in this pair of channels is enabled. + */ +#define FTM_COMBINE_SYNCEN0(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_SYNCEN0_SHIFT)) & FTM_COMBINE_SYNCEN0_MASK) +#define FTM_COMBINE_FAULTEN0_MASK (0x40U) +#define FTM_COMBINE_FAULTEN0_SHIFT (6U) +/*! FAULTEN0 - Fault Control Enable For n = 0 + * 0b0..The fault control in this pair of channels is disabled. + * 0b1..The fault control in this pair of channels is enabled. + */ +#define FTM_COMBINE_FAULTEN0(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_FAULTEN0_SHIFT)) & FTM_COMBINE_FAULTEN0_MASK) +#define FTM_COMBINE_COMBINE1_MASK (0x100U) +#define FTM_COMBINE_COMBINE1_SHIFT (8U) +/*! COMBINE1 - Combine Channels For n = 2 + * 0b0..Channels (n) and (n+1) are independent. + * 0b1..Channels (n) and (n+1) are combined. + */ +#define FTM_COMBINE_COMBINE1(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_COMBINE1_SHIFT)) & FTM_COMBINE_COMBINE1_MASK) +#define FTM_COMBINE_COMP1_MASK (0x200U) +#define FTM_COMBINE_COMP1_SHIFT (9U) +/*! COMP1 - Complement Of Channel (n) For n = 2 + * 0b0..The channel (n+1) output is the same as the channel (n) output. + * 0b1..The channel (n+1) output is the complement of the channel (n) output. + */ +#define FTM_COMBINE_COMP1(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_COMP1_SHIFT)) & FTM_COMBINE_COMP1_MASK) +#define FTM_COMBINE_DECAPEN1_MASK (0x400U) +#define FTM_COMBINE_DECAPEN1_SHIFT (10U) +/*! DECAPEN1 - Dual Edge Capture Mode Enable For n = 2 + * 0b0..The Dual Edge Capture mode in this pair of channels is disabled. + * 0b1..The Dual Edge Capture mode in this pair of channels is enabled. + */ +#define FTM_COMBINE_DECAPEN1(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DECAPEN1_SHIFT)) & FTM_COMBINE_DECAPEN1_MASK) +#define FTM_COMBINE_DECAP1_MASK (0x800U) +#define FTM_COMBINE_DECAP1_SHIFT (11U) +/*! DECAP1 - Dual Edge Capture Mode Captures For n = 2 + * 0b0..The dual edge captures are inactive. + * 0b1..The dual edge captures are active. + */ +#define FTM_COMBINE_DECAP1(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DECAP1_SHIFT)) & FTM_COMBINE_DECAP1_MASK) +#define FTM_COMBINE_DTEN1_MASK (0x1000U) +#define FTM_COMBINE_DTEN1_SHIFT (12U) +/*! DTEN1 - Deadtime Enable For n = 2 + * 0b0..The deadtime insertion in this pair of channels is disabled. + * 0b1..The deadtime insertion in this pair of channels is enabled. + */ +#define FTM_COMBINE_DTEN1(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DTEN1_SHIFT)) & FTM_COMBINE_DTEN1_MASK) +#define FTM_COMBINE_SYNCEN1_MASK (0x2000U) +#define FTM_COMBINE_SYNCEN1_SHIFT (13U) +/*! SYNCEN1 - Synchronization Enable For n = 2 + * 0b0..The PWM synchronization in this pair of channels is disabled. + * 0b1..The PWM synchronization in this pair of channels is enabled. + */ +#define FTM_COMBINE_SYNCEN1(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_SYNCEN1_SHIFT)) & FTM_COMBINE_SYNCEN1_MASK) +#define FTM_COMBINE_FAULTEN1_MASK (0x4000U) +#define FTM_COMBINE_FAULTEN1_SHIFT (14U) +/*! FAULTEN1 - Fault Control Enable For n = 2 + * 0b0..The fault control in this pair of channels is disabled. + * 0b1..The fault control in this pair of channels is enabled. + */ +#define FTM_COMBINE_FAULTEN1(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_FAULTEN1_SHIFT)) & FTM_COMBINE_FAULTEN1_MASK) +#define FTM_COMBINE_COMBINE2_MASK (0x10000U) +#define FTM_COMBINE_COMBINE2_SHIFT (16U) +/*! COMBINE2 - Combine Channels For n = 4 + * 0b0..Channels (n) and (n+1) are independent. + * 0b1..Channels (n) and (n+1) are combined. + */ +#define FTM_COMBINE_COMBINE2(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_COMBINE2_SHIFT)) & FTM_COMBINE_COMBINE2_MASK) +#define FTM_COMBINE_COMP2_MASK (0x20000U) +#define FTM_COMBINE_COMP2_SHIFT (17U) +/*! COMP2 - Complement Of Channel (n) For n = 4 + * 0b0..The channel (n+1) output is the same as the channel (n) output. + * 0b1..The channel (n+1) output is the complement of the channel (n) output. + */ +#define FTM_COMBINE_COMP2(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_COMP2_SHIFT)) & FTM_COMBINE_COMP2_MASK) +#define FTM_COMBINE_DECAPEN2_MASK (0x40000U) +#define FTM_COMBINE_DECAPEN2_SHIFT (18U) +/*! DECAPEN2 - Dual Edge Capture Mode Enable For n = 4 + * 0b0..The Dual Edge Capture mode in this pair of channels is disabled. + * 0b1..The Dual Edge Capture mode in this pair of channels is enabled. + */ +#define FTM_COMBINE_DECAPEN2(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DECAPEN2_SHIFT)) & FTM_COMBINE_DECAPEN2_MASK) +#define FTM_COMBINE_DECAP2_MASK (0x80000U) +#define FTM_COMBINE_DECAP2_SHIFT (19U) +/*! DECAP2 - Dual Edge Capture Mode Captures For n = 4 + * 0b0..The dual edge captures are inactive. + * 0b1..The dual edge captures are active. + */ +#define FTM_COMBINE_DECAP2(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DECAP2_SHIFT)) & FTM_COMBINE_DECAP2_MASK) +#define FTM_COMBINE_DTEN2_MASK (0x100000U) +#define FTM_COMBINE_DTEN2_SHIFT (20U) +/*! DTEN2 - Deadtime Enable For n = 4 + * 0b0..The deadtime insertion in this pair of channels is disabled. + * 0b1..The deadtime insertion in this pair of channels is enabled. + */ +#define FTM_COMBINE_DTEN2(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DTEN2_SHIFT)) & FTM_COMBINE_DTEN2_MASK) +#define FTM_COMBINE_SYNCEN2_MASK (0x200000U) +#define FTM_COMBINE_SYNCEN2_SHIFT (21U) +/*! SYNCEN2 - Synchronization Enable For n = 4 + * 0b0..The PWM synchronization in this pair of channels is disabled. + * 0b1..The PWM synchronization in this pair of channels is enabled. + */ +#define FTM_COMBINE_SYNCEN2(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_SYNCEN2_SHIFT)) & FTM_COMBINE_SYNCEN2_MASK) +#define FTM_COMBINE_FAULTEN2_MASK (0x400000U) +#define FTM_COMBINE_FAULTEN2_SHIFT (22U) +/*! FAULTEN2 - Fault Control Enable For n = 4 + * 0b0..The fault control in this pair of channels is disabled. + * 0b1..The fault control in this pair of channels is enabled. + */ +#define FTM_COMBINE_FAULTEN2(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_FAULTEN2_SHIFT)) & FTM_COMBINE_FAULTEN2_MASK) +#define FTM_COMBINE_COMBINE3_MASK (0x1000000U) +#define FTM_COMBINE_COMBINE3_SHIFT (24U) +/*! COMBINE3 - Combine Channels For n = 6 + * 0b0..Channels (n) and (n+1) are independent. + * 0b1..Channels (n) and (n+1) are combined. + */ +#define FTM_COMBINE_COMBINE3(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_COMBINE3_SHIFT)) & FTM_COMBINE_COMBINE3_MASK) +#define FTM_COMBINE_COMP3_MASK (0x2000000U) +#define FTM_COMBINE_COMP3_SHIFT (25U) +/*! COMP3 - Complement Of Channel (n) for n = 6 + * 0b0..The channel (n+1) output is the same as the channel (n) output. + * 0b1..The channel (n+1) output is the complement of the channel (n) output. + */ +#define FTM_COMBINE_COMP3(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_COMP3_SHIFT)) & FTM_COMBINE_COMP3_MASK) +#define FTM_COMBINE_DECAPEN3_MASK (0x4000000U) +#define FTM_COMBINE_DECAPEN3_SHIFT (26U) +/*! DECAPEN3 - Dual Edge Capture Mode Enable For n = 6 + * 0b0..The Dual Edge Capture mode in this pair of channels is disabled. + * 0b1..The Dual Edge Capture mode in this pair of channels is enabled. + */ +#define FTM_COMBINE_DECAPEN3(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DECAPEN3_SHIFT)) & FTM_COMBINE_DECAPEN3_MASK) +#define FTM_COMBINE_DECAP3_MASK (0x8000000U) +#define FTM_COMBINE_DECAP3_SHIFT (27U) +/*! DECAP3 - Dual Edge Capture Mode Captures For n = 6 + * 0b0..The dual edge captures are inactive. + * 0b1..The dual edge captures are active. + */ +#define FTM_COMBINE_DECAP3(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DECAP3_SHIFT)) & FTM_COMBINE_DECAP3_MASK) +#define FTM_COMBINE_DTEN3_MASK (0x10000000U) +#define FTM_COMBINE_DTEN3_SHIFT (28U) +/*! DTEN3 - Deadtime Enable For n = 6 + * 0b0..The deadtime insertion in this pair of channels is disabled. + * 0b1..The deadtime insertion in this pair of channels is enabled. + */ +#define FTM_COMBINE_DTEN3(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_DTEN3_SHIFT)) & FTM_COMBINE_DTEN3_MASK) +#define FTM_COMBINE_SYNCEN3_MASK (0x20000000U) +#define FTM_COMBINE_SYNCEN3_SHIFT (29U) +/*! SYNCEN3 - Synchronization Enable For n = 6 + * 0b0..The PWM synchronization in this pair of channels is disabled. + * 0b1..The PWM synchronization in this pair of channels is enabled. + */ +#define FTM_COMBINE_SYNCEN3(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_SYNCEN3_SHIFT)) & FTM_COMBINE_SYNCEN3_MASK) +#define FTM_COMBINE_FAULTEN3_MASK (0x40000000U) +#define FTM_COMBINE_FAULTEN3_SHIFT (30U) +/*! FAULTEN3 - Fault Control Enable For n = 6 + * 0b0..The fault control in this pair of channels is disabled. + * 0b1..The fault control in this pair of channels is enabled. + */ +#define FTM_COMBINE_FAULTEN3(x) (((uint32_t)(((uint32_t)(x)) << FTM_COMBINE_FAULTEN3_SHIFT)) & FTM_COMBINE_FAULTEN3_MASK) +/*! @} */ + +/*! @name DEADTIME - Deadtime Insertion Control */ +/*! @{ */ +#define FTM_DEADTIME_DTVAL_MASK (0x3FU) +#define FTM_DEADTIME_DTVAL_SHIFT (0U) +#define FTM_DEADTIME_DTVAL(x) (((uint32_t)(((uint32_t)(x)) << FTM_DEADTIME_DTVAL_SHIFT)) & FTM_DEADTIME_DTVAL_MASK) +#define FTM_DEADTIME_DTPS_MASK (0xC0U) +#define FTM_DEADTIME_DTPS_SHIFT (6U) +/*! DTPS - Deadtime Prescaler Value + * 0b0x..Divide the system clock by 1. + * 0b10..Divide the system clock by 4. + * 0b11..Divide the system clock by 16. + */ +#define FTM_DEADTIME_DTPS(x) (((uint32_t)(((uint32_t)(x)) << FTM_DEADTIME_DTPS_SHIFT)) & FTM_DEADTIME_DTPS_MASK) +/*! @} */ + +/*! @name EXTTRIG - FTM External Trigger */ +/*! @{ */ +#define FTM_EXTTRIG_CH2TRIG_MASK (0x1U) +#define FTM_EXTTRIG_CH2TRIG_SHIFT (0U) +/*! CH2TRIG - Channel 2 Trigger Enable + * 0b0..The generation of the channel trigger is disabled. + * 0b1..The generation of the channel trigger is enabled. + */ +#define FTM_EXTTRIG_CH2TRIG(x) (((uint32_t)(((uint32_t)(x)) << FTM_EXTTRIG_CH2TRIG_SHIFT)) & FTM_EXTTRIG_CH2TRIG_MASK) +#define FTM_EXTTRIG_CH3TRIG_MASK (0x2U) +#define FTM_EXTTRIG_CH3TRIG_SHIFT (1U) +/*! CH3TRIG - Channel 3 Trigger Enable + * 0b0..The generation of the channel trigger is disabled. + * 0b1..The generation of the channel trigger is enabled. + */ +#define FTM_EXTTRIG_CH3TRIG(x) (((uint32_t)(((uint32_t)(x)) << FTM_EXTTRIG_CH3TRIG_SHIFT)) & FTM_EXTTRIG_CH3TRIG_MASK) +#define FTM_EXTTRIG_CH4TRIG_MASK (0x4U) +#define FTM_EXTTRIG_CH4TRIG_SHIFT (2U) +/*! CH4TRIG - Channel 4 Trigger Enable + * 0b0..The generation of the channel trigger is disabled. + * 0b1..The generation of the channel trigger is enabled. + */ +#define FTM_EXTTRIG_CH4TRIG(x) (((uint32_t)(((uint32_t)(x)) << FTM_EXTTRIG_CH4TRIG_SHIFT)) & FTM_EXTTRIG_CH4TRIG_MASK) +#define FTM_EXTTRIG_CH5TRIG_MASK (0x8U) +#define FTM_EXTTRIG_CH5TRIG_SHIFT (3U) +/*! CH5TRIG - Channel 5 Trigger Enable + * 0b0..The generation of the channel trigger is disabled. + * 0b1..The generation of the channel trigger is enabled. + */ +#define FTM_EXTTRIG_CH5TRIG(x) (((uint32_t)(((uint32_t)(x)) << FTM_EXTTRIG_CH5TRIG_SHIFT)) & FTM_EXTTRIG_CH5TRIG_MASK) +#define FTM_EXTTRIG_CH0TRIG_MASK (0x10U) +#define FTM_EXTTRIG_CH0TRIG_SHIFT (4U) +/*! CH0TRIG - Channel 0 Trigger Enable + * 0b0..The generation of the channel trigger is disabled. + * 0b1..The generation of the channel trigger is enabled. + */ +#define FTM_EXTTRIG_CH0TRIG(x) (((uint32_t)(((uint32_t)(x)) << FTM_EXTTRIG_CH0TRIG_SHIFT)) & FTM_EXTTRIG_CH0TRIG_MASK) +#define FTM_EXTTRIG_CH1TRIG_MASK (0x20U) +#define FTM_EXTTRIG_CH1TRIG_SHIFT (5U) +/*! CH1TRIG - Channel 1 Trigger Enable + * 0b0..The generation of the channel trigger is disabled. + * 0b1..The generation of the channel trigger is enabled. + */ +#define FTM_EXTTRIG_CH1TRIG(x) (((uint32_t)(((uint32_t)(x)) << FTM_EXTTRIG_CH1TRIG_SHIFT)) & FTM_EXTTRIG_CH1TRIG_MASK) +#define FTM_EXTTRIG_INITTRIGEN_MASK (0x40U) +#define FTM_EXTTRIG_INITTRIGEN_SHIFT (6U) +/*! INITTRIGEN - Initialization Trigger Enable + * 0b0..The generation of initialization trigger is disabled. + * 0b1..The generation of initialization trigger is enabled. + */ +#define FTM_EXTTRIG_INITTRIGEN(x) (((uint32_t)(((uint32_t)(x)) << FTM_EXTTRIG_INITTRIGEN_SHIFT)) & FTM_EXTTRIG_INITTRIGEN_MASK) +#define FTM_EXTTRIG_TRIGF_MASK (0x80U) +#define FTM_EXTTRIG_TRIGF_SHIFT (7U) +/*! TRIGF - Channel Trigger Flag + * 0b0..No channel trigger was generated. + * 0b1..A channel trigger was generated. + */ +#define FTM_EXTTRIG_TRIGF(x) (((uint32_t)(((uint32_t)(x)) << FTM_EXTTRIG_TRIGF_SHIFT)) & FTM_EXTTRIG_TRIGF_MASK) +/*! @} */ + +/*! @name POL - Channels Polarity */ +/*! @{ */ +#define FTM_POL_POL0_MASK (0x1U) +#define FTM_POL_POL0_SHIFT (0U) +/*! POL0 - Channel 0 Polarity + * 0b0..The channel polarity is active high. + * 0b1..The channel polarity is active low. + */ +#define FTM_POL_POL0(x) (((uint32_t)(((uint32_t)(x)) << FTM_POL_POL0_SHIFT)) & FTM_POL_POL0_MASK) +#define FTM_POL_POL1_MASK (0x2U) +#define FTM_POL_POL1_SHIFT (1U) +/*! POL1 - Channel 1 Polarity + * 0b0..The channel polarity is active high. + * 0b1..The channel polarity is active low. + */ +#define FTM_POL_POL1(x) (((uint32_t)(((uint32_t)(x)) << FTM_POL_POL1_SHIFT)) & FTM_POL_POL1_MASK) +#define FTM_POL_POL2_MASK (0x4U) +#define FTM_POL_POL2_SHIFT (2U) +/*! POL2 - Channel 2 Polarity + * 0b0..The channel polarity is active high. + * 0b1..The channel polarity is active low. + */ +#define FTM_POL_POL2(x) (((uint32_t)(((uint32_t)(x)) << FTM_POL_POL2_SHIFT)) & FTM_POL_POL2_MASK) +#define FTM_POL_POL3_MASK (0x8U) +#define FTM_POL_POL3_SHIFT (3U) +/*! POL3 - Channel 3 Polarity + * 0b0..The channel polarity is active high. + * 0b1..The channel polarity is active low. + */ +#define FTM_POL_POL3(x) (((uint32_t)(((uint32_t)(x)) << FTM_POL_POL3_SHIFT)) & FTM_POL_POL3_MASK) +#define FTM_POL_POL4_MASK (0x10U) +#define FTM_POL_POL4_SHIFT (4U) +/*! POL4 - Channel 4 Polarity + * 0b0..The channel polarity is active high. + * 0b1..The channel polarity is active low. + */ +#define FTM_POL_POL4(x) (((uint32_t)(((uint32_t)(x)) << FTM_POL_POL4_SHIFT)) & FTM_POL_POL4_MASK) +#define FTM_POL_POL5_MASK (0x20U) +#define FTM_POL_POL5_SHIFT (5U) +/*! POL5 - Channel 5 Polarity + * 0b0..The channel polarity is active high. + * 0b1..The channel polarity is active low. + */ +#define FTM_POL_POL5(x) (((uint32_t)(((uint32_t)(x)) << FTM_POL_POL5_SHIFT)) & FTM_POL_POL5_MASK) +#define FTM_POL_POL6_MASK (0x40U) +#define FTM_POL_POL6_SHIFT (6U) +/*! POL6 - Channel 6 Polarity + * 0b0..The channel polarity is active high. + * 0b1..The channel polarity is active low. + */ +#define FTM_POL_POL6(x) (((uint32_t)(((uint32_t)(x)) << FTM_POL_POL6_SHIFT)) & FTM_POL_POL6_MASK) +#define FTM_POL_POL7_MASK (0x80U) +#define FTM_POL_POL7_SHIFT (7U) +/*! POL7 - Channel 7 Polarity + * 0b0..The channel polarity is active high. + * 0b1..The channel polarity is active low. + */ +#define FTM_POL_POL7(x) (((uint32_t)(((uint32_t)(x)) << FTM_POL_POL7_SHIFT)) & FTM_POL_POL7_MASK) +/*! @} */ + +/*! @name FMS - Fault Mode Status */ +/*! @{ */ +#define FTM_FMS_FAULTF0_MASK (0x1U) +#define FTM_FMS_FAULTF0_SHIFT (0U) +/*! FAULTF0 - Fault Detection Flag 0 + * 0b0..No fault condition was detected at the fault input. + * 0b1..A fault condition was detected at the fault input. + */ +#define FTM_FMS_FAULTF0(x) (((uint32_t)(((uint32_t)(x)) << FTM_FMS_FAULTF0_SHIFT)) & FTM_FMS_FAULTF0_MASK) +#define FTM_FMS_FAULTF1_MASK (0x2U) +#define FTM_FMS_FAULTF1_SHIFT (1U) +/*! FAULTF1 - Fault Detection Flag 1 + * 0b0..No fault condition was detected at the fault input. + * 0b1..A fault condition was detected at the fault input. + */ +#define FTM_FMS_FAULTF1(x) (((uint32_t)(((uint32_t)(x)) << FTM_FMS_FAULTF1_SHIFT)) & FTM_FMS_FAULTF1_MASK) +#define FTM_FMS_FAULTF2_MASK (0x4U) +#define FTM_FMS_FAULTF2_SHIFT (2U) +/*! FAULTF2 - Fault Detection Flag 2 + * 0b0..No fault condition was detected at the fault input. + * 0b1..A fault condition was detected at the fault input. + */ +#define FTM_FMS_FAULTF2(x) (((uint32_t)(((uint32_t)(x)) << FTM_FMS_FAULTF2_SHIFT)) & FTM_FMS_FAULTF2_MASK) +#define FTM_FMS_FAULTF3_MASK (0x8U) +#define FTM_FMS_FAULTF3_SHIFT (3U) +/*! FAULTF3 - Fault Detection Flag 3 + * 0b0..No fault condition was detected at the fault input. + * 0b1..A fault condition was detected at the fault input. + */ +#define FTM_FMS_FAULTF3(x) (((uint32_t)(((uint32_t)(x)) << FTM_FMS_FAULTF3_SHIFT)) & FTM_FMS_FAULTF3_MASK) +#define FTM_FMS_FAULTIN_MASK (0x20U) +#define FTM_FMS_FAULTIN_SHIFT (5U) +/*! FAULTIN - Fault Inputs + * 0b0..The logic OR of the enabled fault inputs is 0. + * 0b1..The logic OR of the enabled fault inputs is 1. + */ +#define FTM_FMS_FAULTIN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FMS_FAULTIN_SHIFT)) & FTM_FMS_FAULTIN_MASK) +#define FTM_FMS_WPEN_MASK (0x40U) +#define FTM_FMS_WPEN_SHIFT (6U) +/*! WPEN - Write Protection Enable + * 0b0..Write protection is disabled. Write protected bits can be written. + * 0b1..Write protection is enabled. Write protected bits cannot be written. + */ +#define FTM_FMS_WPEN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FMS_WPEN_SHIFT)) & FTM_FMS_WPEN_MASK) +#define FTM_FMS_FAULTF_MASK (0x80U) +#define FTM_FMS_FAULTF_SHIFT (7U) +/*! FAULTF - Fault Detection Flag + * 0b0..No fault condition was detected. + * 0b1..A fault condition was detected. + */ +#define FTM_FMS_FAULTF(x) (((uint32_t)(((uint32_t)(x)) << FTM_FMS_FAULTF_SHIFT)) & FTM_FMS_FAULTF_MASK) +/*! @} */ + +/*! @name FILTER - Input Capture Filter Control */ +/*! @{ */ +#define FTM_FILTER_CH0FVAL_MASK (0xFU) +#define FTM_FILTER_CH0FVAL_SHIFT (0U) +#define FTM_FILTER_CH0FVAL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FILTER_CH0FVAL_SHIFT)) & FTM_FILTER_CH0FVAL_MASK) +#define FTM_FILTER_CH1FVAL_MASK (0xF0U) +#define FTM_FILTER_CH1FVAL_SHIFT (4U) +#define FTM_FILTER_CH1FVAL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FILTER_CH1FVAL_SHIFT)) & FTM_FILTER_CH1FVAL_MASK) +#define FTM_FILTER_CH2FVAL_MASK (0xF00U) +#define FTM_FILTER_CH2FVAL_SHIFT (8U) +#define FTM_FILTER_CH2FVAL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FILTER_CH2FVAL_SHIFT)) & FTM_FILTER_CH2FVAL_MASK) +#define FTM_FILTER_CH3FVAL_MASK (0xF000U) +#define FTM_FILTER_CH3FVAL_SHIFT (12U) +#define FTM_FILTER_CH3FVAL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FILTER_CH3FVAL_SHIFT)) & FTM_FILTER_CH3FVAL_MASK) +/*! @} */ + +/*! @name FLTCTRL - Fault Control */ +/*! @{ */ +#define FTM_FLTCTRL_FAULT0EN_MASK (0x1U) +#define FTM_FLTCTRL_FAULT0EN_SHIFT (0U) +/*! FAULT0EN - Fault Input 0 Enable + * 0b0..Fault input is disabled. + * 0b1..Fault input is enabled. + */ +#define FTM_FLTCTRL_FAULT0EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FAULT0EN_SHIFT)) & FTM_FLTCTRL_FAULT0EN_MASK) +#define FTM_FLTCTRL_FAULT1EN_MASK (0x2U) +#define FTM_FLTCTRL_FAULT1EN_SHIFT (1U) +/*! FAULT1EN - Fault Input 1 Enable + * 0b0..Fault input is disabled. + * 0b1..Fault input is enabled. + */ +#define FTM_FLTCTRL_FAULT1EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FAULT1EN_SHIFT)) & FTM_FLTCTRL_FAULT1EN_MASK) +#define FTM_FLTCTRL_FAULT2EN_MASK (0x4U) +#define FTM_FLTCTRL_FAULT2EN_SHIFT (2U) +/*! FAULT2EN - Fault Input 2 Enable + * 0b0..Fault input is disabled. + * 0b1..Fault input is enabled. + */ +#define FTM_FLTCTRL_FAULT2EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FAULT2EN_SHIFT)) & FTM_FLTCTRL_FAULT2EN_MASK) +#define FTM_FLTCTRL_FAULT3EN_MASK (0x8U) +#define FTM_FLTCTRL_FAULT3EN_SHIFT (3U) +/*! FAULT3EN - Fault Input 3 Enable + * 0b0..Fault input is disabled. + * 0b1..Fault input is enabled. + */ +#define FTM_FLTCTRL_FAULT3EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FAULT3EN_SHIFT)) & FTM_FLTCTRL_FAULT3EN_MASK) +#define FTM_FLTCTRL_FFLTR0EN_MASK (0x10U) +#define FTM_FLTCTRL_FFLTR0EN_SHIFT (4U) +/*! FFLTR0EN - Fault Input 0 Filter Enable + * 0b0..Fault input filter is disabled. + * 0b1..Fault input filter is enabled. + */ +#define FTM_FLTCTRL_FFLTR0EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FFLTR0EN_SHIFT)) & FTM_FLTCTRL_FFLTR0EN_MASK) +#define FTM_FLTCTRL_FFLTR1EN_MASK (0x20U) +#define FTM_FLTCTRL_FFLTR1EN_SHIFT (5U) +/*! FFLTR1EN - Fault Input 1 Filter Enable + * 0b0..Fault input filter is disabled. + * 0b1..Fault input filter is enabled. + */ +#define FTM_FLTCTRL_FFLTR1EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FFLTR1EN_SHIFT)) & FTM_FLTCTRL_FFLTR1EN_MASK) +#define FTM_FLTCTRL_FFLTR2EN_MASK (0x40U) +#define FTM_FLTCTRL_FFLTR2EN_SHIFT (6U) +/*! FFLTR2EN - Fault Input 2 Filter Enable + * 0b0..Fault input filter is disabled. + * 0b1..Fault input filter is enabled. + */ +#define FTM_FLTCTRL_FFLTR2EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FFLTR2EN_SHIFT)) & FTM_FLTCTRL_FFLTR2EN_MASK) +#define FTM_FLTCTRL_FFLTR3EN_MASK (0x80U) +#define FTM_FLTCTRL_FFLTR3EN_SHIFT (7U) +/*! FFLTR3EN - Fault Input 3 Filter Enable + * 0b0..Fault input filter is disabled. + * 0b1..Fault input filter is enabled. + */ +#define FTM_FLTCTRL_FFLTR3EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FFLTR3EN_SHIFT)) & FTM_FLTCTRL_FFLTR3EN_MASK) +#define FTM_FLTCTRL_FFVAL_MASK (0xF00U) +#define FTM_FLTCTRL_FFVAL_SHIFT (8U) +#define FTM_FLTCTRL_FFVAL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTCTRL_FFVAL_SHIFT)) & FTM_FLTCTRL_FFVAL_MASK) +/*! @} */ + +/*! @name QDCTRL - Quadrature Decoder Control And Status */ +/*! @{ */ +#define FTM_QDCTRL_QUADEN_MASK (0x1U) +#define FTM_QDCTRL_QUADEN_SHIFT (0U) +/*! QUADEN - Quadrature Decoder Mode Enable + * 0b0..Quadrature Decoder mode is disabled. + * 0b1..Quadrature Decoder mode is enabled. + */ +#define FTM_QDCTRL_QUADEN(x) (((uint32_t)(((uint32_t)(x)) << FTM_QDCTRL_QUADEN_SHIFT)) & FTM_QDCTRL_QUADEN_MASK) +#define FTM_QDCTRL_TOFDIR_MASK (0x2U) +#define FTM_QDCTRL_TOFDIR_SHIFT (1U) +/*! TOFDIR - Timer Overflow Direction In Quadrature Decoder Mode + * 0b0..TOF bit was set on the bottom of counting. There was an FTM counter decrement and FTM counter changes from its minimum value (CNTIN register) to its maximum value (MOD register). + * 0b1..TOF bit was set on the top of counting. There was an FTM counter increment and FTM counter changes from its maximum value (MOD register) to its minimum value (CNTIN register). + */ +#define FTM_QDCTRL_TOFDIR(x) (((uint32_t)(((uint32_t)(x)) << FTM_QDCTRL_TOFDIR_SHIFT)) & FTM_QDCTRL_TOFDIR_MASK) +#define FTM_QDCTRL_QUADIR_MASK (0x4U) +#define FTM_QDCTRL_QUADIR_SHIFT (2U) +/*! QUADIR - FTM Counter Direction In Quadrature Decoder Mode + * 0b0..Counting direction is decreasing (FTM counter decrement). + * 0b1..Counting direction is increasing (FTM counter increment). + */ +#define FTM_QDCTRL_QUADIR(x) (((uint32_t)(((uint32_t)(x)) << FTM_QDCTRL_QUADIR_SHIFT)) & FTM_QDCTRL_QUADIR_MASK) +#define FTM_QDCTRL_QUADMODE_MASK (0x8U) +#define FTM_QDCTRL_QUADMODE_SHIFT (3U) +/*! QUADMODE - Quadrature Decoder Mode + * 0b0..Phase A and phase B encoding mode. + * 0b1..Count and direction encoding mode. + */ +#define FTM_QDCTRL_QUADMODE(x) (((uint32_t)(((uint32_t)(x)) << FTM_QDCTRL_QUADMODE_SHIFT)) & FTM_QDCTRL_QUADMODE_MASK) +#define FTM_QDCTRL_PHBPOL_MASK (0x10U) +#define FTM_QDCTRL_PHBPOL_SHIFT (4U) +/*! PHBPOL - Phase B Input Polarity + * 0b0..Normal polarity. Phase B input signal is not inverted before identifying the rising and falling edges of this signal. + * 0b1..Inverted polarity. Phase B input signal is inverted before identifying the rising and falling edges of this signal. + */ +#define FTM_QDCTRL_PHBPOL(x) (((uint32_t)(((uint32_t)(x)) << FTM_QDCTRL_PHBPOL_SHIFT)) & FTM_QDCTRL_PHBPOL_MASK) +#define FTM_QDCTRL_PHAPOL_MASK (0x20U) +#define FTM_QDCTRL_PHAPOL_SHIFT (5U) +/*! PHAPOL - Phase A Input Polarity + * 0b0..Normal polarity. Phase A input signal is not inverted before identifying the rising and falling edges of this signal. + * 0b1..Inverted polarity. Phase A input signal is inverted before identifying the rising and falling edges of this signal. + */ +#define FTM_QDCTRL_PHAPOL(x) (((uint32_t)(((uint32_t)(x)) << FTM_QDCTRL_PHAPOL_SHIFT)) & FTM_QDCTRL_PHAPOL_MASK) +#define FTM_QDCTRL_PHBFLTREN_MASK (0x40U) +#define FTM_QDCTRL_PHBFLTREN_SHIFT (6U) +/*! PHBFLTREN - Phase B Input Filter Enable + * 0b0..Phase B input filter is disabled. + * 0b1..Phase B input filter is enabled. + */ +#define FTM_QDCTRL_PHBFLTREN(x) (((uint32_t)(((uint32_t)(x)) << FTM_QDCTRL_PHBFLTREN_SHIFT)) & FTM_QDCTRL_PHBFLTREN_MASK) +#define FTM_QDCTRL_PHAFLTREN_MASK (0x80U) +#define FTM_QDCTRL_PHAFLTREN_SHIFT (7U) +/*! PHAFLTREN - Phase A Input Filter Enable + * 0b0..Phase A input filter is disabled. + * 0b1..Phase A input filter is enabled. + */ +#define FTM_QDCTRL_PHAFLTREN(x) (((uint32_t)(((uint32_t)(x)) << FTM_QDCTRL_PHAFLTREN_SHIFT)) & FTM_QDCTRL_PHAFLTREN_MASK) +/*! @} */ + +/*! @name CONF - Configuration */ +/*! @{ */ +#define FTM_CONF_NUMTOF_MASK (0x1FU) +#define FTM_CONF_NUMTOF_SHIFT (0U) +#define FTM_CONF_NUMTOF(x) (((uint32_t)(((uint32_t)(x)) << FTM_CONF_NUMTOF_SHIFT)) & FTM_CONF_NUMTOF_MASK) +#define FTM_CONF_BDMMODE_MASK (0xC0U) +#define FTM_CONF_BDMMODE_SHIFT (6U) +#define FTM_CONF_BDMMODE(x) (((uint32_t)(((uint32_t)(x)) << FTM_CONF_BDMMODE_SHIFT)) & FTM_CONF_BDMMODE_MASK) +#define FTM_CONF_GTBEEN_MASK (0x200U) +#define FTM_CONF_GTBEEN_SHIFT (9U) +/*! GTBEEN - Global Time Base Enable + * 0b0..Use of an external global time base is disabled. + * 0b1..Use of an external global time base is enabled. + */ +#define FTM_CONF_GTBEEN(x) (((uint32_t)(((uint32_t)(x)) << FTM_CONF_GTBEEN_SHIFT)) & FTM_CONF_GTBEEN_MASK) +#define FTM_CONF_GTBEOUT_MASK (0x400U) +#define FTM_CONF_GTBEOUT_SHIFT (10U) +/*! GTBEOUT - Global Time Base Output + * 0b0..A global time base signal generation is disabled. + * 0b1..A global time base signal generation is enabled. + */ +#define FTM_CONF_GTBEOUT(x) (((uint32_t)(((uint32_t)(x)) << FTM_CONF_GTBEOUT_SHIFT)) & FTM_CONF_GTBEOUT_MASK) +/*! @} */ + +/*! @name FLTPOL - FTM Fault Input Polarity */ +/*! @{ */ +#define FTM_FLTPOL_FLT0POL_MASK (0x1U) +#define FTM_FLTPOL_FLT0POL_SHIFT (0U) +/*! FLT0POL - Fault Input 0 Polarity + * 0b0..The fault input polarity is active high. A 1 at the fault input indicates a fault. + * 0b1..The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +#define FTM_FLTPOL_FLT0POL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTPOL_FLT0POL_SHIFT)) & FTM_FLTPOL_FLT0POL_MASK) +#define FTM_FLTPOL_FLT1POL_MASK (0x2U) +#define FTM_FLTPOL_FLT1POL_SHIFT (1U) +/*! FLT1POL - Fault Input 1 Polarity + * 0b0..The fault input polarity is active high. A 1 at the fault input indicates a fault. + * 0b1..The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +#define FTM_FLTPOL_FLT1POL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTPOL_FLT1POL_SHIFT)) & FTM_FLTPOL_FLT1POL_MASK) +#define FTM_FLTPOL_FLT2POL_MASK (0x4U) +#define FTM_FLTPOL_FLT2POL_SHIFT (2U) +/*! FLT2POL - Fault Input 2 Polarity + * 0b0..The fault input polarity is active high. A 1 at the fault input indicates a fault. + * 0b1..The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +#define FTM_FLTPOL_FLT2POL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTPOL_FLT2POL_SHIFT)) & FTM_FLTPOL_FLT2POL_MASK) +#define FTM_FLTPOL_FLT3POL_MASK (0x8U) +#define FTM_FLTPOL_FLT3POL_SHIFT (3U) +/*! FLT3POL - Fault Input 3 Polarity + * 0b0..The fault input polarity is active high. A 1 at the fault input indicates a fault. + * 0b1..The fault input polarity is active low. A 0 at the fault input indicates a fault. + */ +#define FTM_FLTPOL_FLT3POL(x) (((uint32_t)(((uint32_t)(x)) << FTM_FLTPOL_FLT3POL_SHIFT)) & FTM_FLTPOL_FLT3POL_MASK) +/*! @} */ + +/*! @name SYNCONF - Synchronization Configuration */ +/*! @{ */ +#define FTM_SYNCONF_HWTRIGMODE_MASK (0x1U) +#define FTM_SYNCONF_HWTRIGMODE_SHIFT (0U) +/*! HWTRIGMODE - Hardware Trigger Mode + * 0b0..FTM clears the TRIGj bit when the hardware trigger j is detected, where j = 0, 1,2. + * 0b1..FTM does not clear the TRIGj bit when the hardware trigger j is detected, where j = 0, 1,2. + */ +#define FTM_SYNCONF_HWTRIGMODE(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_HWTRIGMODE_SHIFT)) & FTM_SYNCONF_HWTRIGMODE_MASK) +#define FTM_SYNCONF_CNTINC_MASK (0x4U) +#define FTM_SYNCONF_CNTINC_SHIFT (2U) +/*! CNTINC - CNTIN Register Synchronization + * 0b0..CNTIN register is updated with its buffer value at all rising edges of system clock. + * 0b1..CNTIN register is updated with its buffer value by the PWM synchronization. + */ +#define FTM_SYNCONF_CNTINC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_CNTINC_SHIFT)) & FTM_SYNCONF_CNTINC_MASK) +#define FTM_SYNCONF_INVC_MASK (0x10U) +#define FTM_SYNCONF_INVC_SHIFT (4U) +/*! INVC - INVCTRL Register Synchronization + * 0b0..INVCTRL register is updated with its buffer value at all rising edges of system clock. + * 0b1..INVCTRL register is updated with its buffer value by the PWM synchronization. + */ +#define FTM_SYNCONF_INVC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_INVC_SHIFT)) & FTM_SYNCONF_INVC_MASK) +#define FTM_SYNCONF_SWOC_MASK (0x20U) +#define FTM_SYNCONF_SWOC_SHIFT (5U) +/*! SWOC - SWOCTRL Register Synchronization + * 0b0..SWOCTRL register is updated with its buffer value at all rising edges of system clock. + * 0b1..SWOCTRL register is updated with its buffer value by the PWM synchronization. + */ +#define FTM_SYNCONF_SWOC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_SWOC_SHIFT)) & FTM_SYNCONF_SWOC_MASK) +#define FTM_SYNCONF_SYNCMODE_MASK (0x80U) +#define FTM_SYNCONF_SYNCMODE_SHIFT (7U) +/*! SYNCMODE - Synchronization Mode + * 0b0..Legacy PWM synchronization is selected. + * 0b1..Enhanced PWM synchronization is selected. + */ +#define FTM_SYNCONF_SYNCMODE(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_SYNCMODE_SHIFT)) & FTM_SYNCONF_SYNCMODE_MASK) +#define FTM_SYNCONF_SWRSTCNT_MASK (0x100U) +#define FTM_SYNCONF_SWRSTCNT_SHIFT (8U) +/*! SWRSTCNT + * 0b0..The software trigger does not activate the FTM counter synchronization. + * 0b1..The software trigger activates the FTM counter synchronization. + */ +#define FTM_SYNCONF_SWRSTCNT(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_SWRSTCNT_SHIFT)) & FTM_SYNCONF_SWRSTCNT_MASK) +#define FTM_SYNCONF_SWWRBUF_MASK (0x200U) +#define FTM_SYNCONF_SWWRBUF_SHIFT (9U) +/*! SWWRBUF + * 0b0..The software trigger does not activate MOD, CNTIN, and CV registers synchronization. + * 0b1..The software trigger activates MOD, CNTIN, and CV registers synchronization. + */ +#define FTM_SYNCONF_SWWRBUF(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_SWWRBUF_SHIFT)) & FTM_SYNCONF_SWWRBUF_MASK) +#define FTM_SYNCONF_SWOM_MASK (0x400U) +#define FTM_SYNCONF_SWOM_SHIFT (10U) +/*! SWOM + * 0b0..The software trigger does not activate the OUTMASK register synchronization. + * 0b1..The software trigger activates the OUTMASK register synchronization. + */ +#define FTM_SYNCONF_SWOM(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_SWOM_SHIFT)) & FTM_SYNCONF_SWOM_MASK) +#define FTM_SYNCONF_SWINVC_MASK (0x800U) +#define FTM_SYNCONF_SWINVC_SHIFT (11U) +/*! SWINVC + * 0b0..The software trigger does not activate the INVCTRL register synchronization. + * 0b1..The software trigger activates the INVCTRL register synchronization. + */ +#define FTM_SYNCONF_SWINVC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_SWINVC_SHIFT)) & FTM_SYNCONF_SWINVC_MASK) +#define FTM_SYNCONF_SWSOC_MASK (0x1000U) +#define FTM_SYNCONF_SWSOC_SHIFT (12U) +/*! SWSOC + * 0b0..The software trigger does not activate the SWOCTRL register synchronization. + * 0b1..The software trigger activates the SWOCTRL register synchronization. + */ +#define FTM_SYNCONF_SWSOC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_SWSOC_SHIFT)) & FTM_SYNCONF_SWSOC_MASK) +#define FTM_SYNCONF_HWRSTCNT_MASK (0x10000U) +#define FTM_SYNCONF_HWRSTCNT_SHIFT (16U) +/*! HWRSTCNT + * 0b0..A hardware trigger does not activate the FTM counter synchronization. + * 0b1..A hardware trigger activates the FTM counter synchronization. + */ +#define FTM_SYNCONF_HWRSTCNT(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_HWRSTCNT_SHIFT)) & FTM_SYNCONF_HWRSTCNT_MASK) +#define FTM_SYNCONF_HWWRBUF_MASK (0x20000U) +#define FTM_SYNCONF_HWWRBUF_SHIFT (17U) +/*! HWWRBUF + * 0b0..A hardware trigger does not activate MOD, CNTIN, and CV registers synchronization. + * 0b1..A hardware trigger activates MOD, CNTIN, and CV registers synchronization. + */ +#define FTM_SYNCONF_HWWRBUF(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_HWWRBUF_SHIFT)) & FTM_SYNCONF_HWWRBUF_MASK) +#define FTM_SYNCONF_HWOM_MASK (0x40000U) +#define FTM_SYNCONF_HWOM_SHIFT (18U) +/*! HWOM + * 0b0..A hardware trigger does not activate the OUTMASK register synchronization. + * 0b1..A hardware trigger activates the OUTMASK register synchronization. + */ +#define FTM_SYNCONF_HWOM(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_HWOM_SHIFT)) & FTM_SYNCONF_HWOM_MASK) +#define FTM_SYNCONF_HWINVC_MASK (0x80000U) +#define FTM_SYNCONF_HWINVC_SHIFT (19U) +/*! HWINVC + * 0b0..A hardware trigger does not activate the INVCTRL register synchronization. + * 0b1..A hardware trigger activates the INVCTRL register synchronization. + */ +#define FTM_SYNCONF_HWINVC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_HWINVC_SHIFT)) & FTM_SYNCONF_HWINVC_MASK) +#define FTM_SYNCONF_HWSOC_MASK (0x100000U) +#define FTM_SYNCONF_HWSOC_SHIFT (20U) +/*! HWSOC + * 0b0..A hardware trigger does not activate the SWOCTRL register synchronization. + * 0b1..A hardware trigger activates the SWOCTRL register synchronization. + */ +#define FTM_SYNCONF_HWSOC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SYNCONF_HWSOC_SHIFT)) & FTM_SYNCONF_HWSOC_MASK) +/*! @} */ + +/*! @name INVCTRL - FTM Inverting Control */ +/*! @{ */ +#define FTM_INVCTRL_INV0EN_MASK (0x1U) +#define FTM_INVCTRL_INV0EN_SHIFT (0U) +/*! INV0EN - Pair Channels 0 Inverting Enable + * 0b0..Inverting is disabled. + * 0b1..Inverting is enabled. + */ +#define FTM_INVCTRL_INV0EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_INVCTRL_INV0EN_SHIFT)) & FTM_INVCTRL_INV0EN_MASK) +#define FTM_INVCTRL_INV1EN_MASK (0x2U) +#define FTM_INVCTRL_INV1EN_SHIFT (1U) +/*! INV1EN - Pair Channels 1 Inverting Enable + * 0b0..Inverting is disabled. + * 0b1..Inverting is enabled. + */ +#define FTM_INVCTRL_INV1EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_INVCTRL_INV1EN_SHIFT)) & FTM_INVCTRL_INV1EN_MASK) +#define FTM_INVCTRL_INV2EN_MASK (0x4U) +#define FTM_INVCTRL_INV2EN_SHIFT (2U) +/*! INV2EN - Pair Channels 2 Inverting Enable + * 0b0..Inverting is disabled. + * 0b1..Inverting is enabled. + */ +#define FTM_INVCTRL_INV2EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_INVCTRL_INV2EN_SHIFT)) & FTM_INVCTRL_INV2EN_MASK) +#define FTM_INVCTRL_INV3EN_MASK (0x8U) +#define FTM_INVCTRL_INV3EN_SHIFT (3U) +/*! INV3EN - Pair Channels 3 Inverting Enable + * 0b0..Inverting is disabled. + * 0b1..Inverting is enabled. + */ +#define FTM_INVCTRL_INV3EN(x) (((uint32_t)(((uint32_t)(x)) << FTM_INVCTRL_INV3EN_SHIFT)) & FTM_INVCTRL_INV3EN_MASK) +/*! @} */ + +/*! @name SWOCTRL - FTM Software Output Control */ +/*! @{ */ +#define FTM_SWOCTRL_CH0OC_MASK (0x1U) +#define FTM_SWOCTRL_CH0OC_SHIFT (0U) +/*! CH0OC - Channel 0 Software Output Control Enable + * 0b0..The channel output is not affected by software output control. + * 0b1..The channel output is affected by software output control. + */ +#define FTM_SWOCTRL_CH0OC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH0OC_SHIFT)) & FTM_SWOCTRL_CH0OC_MASK) +#define FTM_SWOCTRL_CH1OC_MASK (0x2U) +#define FTM_SWOCTRL_CH1OC_SHIFT (1U) +/*! CH1OC - Channel 1 Software Output Control Enable + * 0b0..The channel output is not affected by software output control. + * 0b1..The channel output is affected by software output control. + */ +#define FTM_SWOCTRL_CH1OC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH1OC_SHIFT)) & FTM_SWOCTRL_CH1OC_MASK) +#define FTM_SWOCTRL_CH2OC_MASK (0x4U) +#define FTM_SWOCTRL_CH2OC_SHIFT (2U) +/*! CH2OC - Channel 2 Software Output Control Enable + * 0b0..The channel output is not affected by software output control. + * 0b1..The channel output is affected by software output control. + */ +#define FTM_SWOCTRL_CH2OC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH2OC_SHIFT)) & FTM_SWOCTRL_CH2OC_MASK) +#define FTM_SWOCTRL_CH3OC_MASK (0x8U) +#define FTM_SWOCTRL_CH3OC_SHIFT (3U) +/*! CH3OC - Channel 3 Software Output Control Enable + * 0b0..The channel output is not affected by software output control. + * 0b1..The channel output is affected by software output control. + */ +#define FTM_SWOCTRL_CH3OC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH3OC_SHIFT)) & FTM_SWOCTRL_CH3OC_MASK) +#define FTM_SWOCTRL_CH4OC_MASK (0x10U) +#define FTM_SWOCTRL_CH4OC_SHIFT (4U) +/*! CH4OC - Channel 4 Software Output Control Enable + * 0b0..The channel output is not affected by software output control. + * 0b1..The channel output is affected by software output control. + */ +#define FTM_SWOCTRL_CH4OC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH4OC_SHIFT)) & FTM_SWOCTRL_CH4OC_MASK) +#define FTM_SWOCTRL_CH5OC_MASK (0x20U) +#define FTM_SWOCTRL_CH5OC_SHIFT (5U) +/*! CH5OC - Channel 5 Software Output Control Enable + * 0b0..The channel output is not affected by software output control. + * 0b1..The channel output is affected by software output control. + */ +#define FTM_SWOCTRL_CH5OC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH5OC_SHIFT)) & FTM_SWOCTRL_CH5OC_MASK) +#define FTM_SWOCTRL_CH6OC_MASK (0x40U) +#define FTM_SWOCTRL_CH6OC_SHIFT (6U) +/*! CH6OC - Channel 6 Software Output Control Enable + * 0b0..The channel output is not affected by software output control. + * 0b1..The channel output is affected by software output control. + */ +#define FTM_SWOCTRL_CH6OC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH6OC_SHIFT)) & FTM_SWOCTRL_CH6OC_MASK) +#define FTM_SWOCTRL_CH7OC_MASK (0x80U) +#define FTM_SWOCTRL_CH7OC_SHIFT (7U) +/*! CH7OC - Channel 7 Software Output Control Enable + * 0b0..The channel output is not affected by software output control. + * 0b1..The channel output is affected by software output control. + */ +#define FTM_SWOCTRL_CH7OC(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH7OC_SHIFT)) & FTM_SWOCTRL_CH7OC_MASK) +#define FTM_SWOCTRL_CH0OCV_MASK (0x100U) +#define FTM_SWOCTRL_CH0OCV_SHIFT (8U) +/*! CH0OCV - Channel 0 Software Output Control Value + * 0b0..The software output control forces 0 to the channel output. + * 0b1..The software output control forces 1 to the channel output. + */ +#define FTM_SWOCTRL_CH0OCV(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH0OCV_SHIFT)) & FTM_SWOCTRL_CH0OCV_MASK) +#define FTM_SWOCTRL_CH1OCV_MASK (0x200U) +#define FTM_SWOCTRL_CH1OCV_SHIFT (9U) +/*! CH1OCV - Channel 1 Software Output Control Value + * 0b0..The software output control forces 0 to the channel output. + * 0b1..The software output control forces 1 to the channel output. + */ +#define FTM_SWOCTRL_CH1OCV(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH1OCV_SHIFT)) & FTM_SWOCTRL_CH1OCV_MASK) +#define FTM_SWOCTRL_CH2OCV_MASK (0x400U) +#define FTM_SWOCTRL_CH2OCV_SHIFT (10U) +/*! CH2OCV - Channel 2 Software Output Control Value + * 0b0..The software output control forces 0 to the channel output. + * 0b1..The software output control forces 1 to the channel output. + */ +#define FTM_SWOCTRL_CH2OCV(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH2OCV_SHIFT)) & FTM_SWOCTRL_CH2OCV_MASK) +#define FTM_SWOCTRL_CH3OCV_MASK (0x800U) +#define FTM_SWOCTRL_CH3OCV_SHIFT (11U) +/*! CH3OCV - Channel 3 Software Output Control Value + * 0b0..The software output control forces 0 to the channel output. + * 0b1..The software output control forces 1 to the channel output. + */ +#define FTM_SWOCTRL_CH3OCV(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH3OCV_SHIFT)) & FTM_SWOCTRL_CH3OCV_MASK) +#define FTM_SWOCTRL_CH4OCV_MASK (0x1000U) +#define FTM_SWOCTRL_CH4OCV_SHIFT (12U) +/*! CH4OCV - Channel 4 Software Output Control Value + * 0b0..The software output control forces 0 to the channel output. + * 0b1..The software output control forces 1 to the channel output. + */ +#define FTM_SWOCTRL_CH4OCV(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH4OCV_SHIFT)) & FTM_SWOCTRL_CH4OCV_MASK) +#define FTM_SWOCTRL_CH5OCV_MASK (0x2000U) +#define FTM_SWOCTRL_CH5OCV_SHIFT (13U) +/*! CH5OCV - Channel 5 Software Output Control Value + * 0b0..The software output control forces 0 to the channel output. + * 0b1..The software output control forces 1 to the channel output. + */ +#define FTM_SWOCTRL_CH5OCV(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH5OCV_SHIFT)) & FTM_SWOCTRL_CH5OCV_MASK) +#define FTM_SWOCTRL_CH6OCV_MASK (0x4000U) +#define FTM_SWOCTRL_CH6OCV_SHIFT (14U) +/*! CH6OCV - Channel 6 Software Output Control Value + * 0b0..The software output control forces 0 to the channel output. + * 0b1..The software output control forces 1 to the channel output. + */ +#define FTM_SWOCTRL_CH6OCV(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH6OCV_SHIFT)) & FTM_SWOCTRL_CH6OCV_MASK) +#define FTM_SWOCTRL_CH7OCV_MASK (0x8000U) +#define FTM_SWOCTRL_CH7OCV_SHIFT (15U) +/*! CH7OCV - Channel 7 Software Output Control Value + * 0b0..The software output control forces 0 to the channel output. + * 0b1..The software output control forces 1 to the channel output. + */ +#define FTM_SWOCTRL_CH7OCV(x) (((uint32_t)(((uint32_t)(x)) << FTM_SWOCTRL_CH7OCV_SHIFT)) & FTM_SWOCTRL_CH7OCV_MASK) +/*! @} */ + +/*! @name PWMLOAD - FTM PWM Load */ +/*! @{ */ +#define FTM_PWMLOAD_CH0SEL_MASK (0x1U) +#define FTM_PWMLOAD_CH0SEL_SHIFT (0U) +/*! CH0SEL - Channel 0 Select + * 0b0..Do not include the channel in the matching process. + * 0b1..Include the channel in the matching process. + */ +#define FTM_PWMLOAD_CH0SEL(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_CH0SEL_SHIFT)) & FTM_PWMLOAD_CH0SEL_MASK) +#define FTM_PWMLOAD_CH1SEL_MASK (0x2U) +#define FTM_PWMLOAD_CH1SEL_SHIFT (1U) +/*! CH1SEL - Channel 1 Select + * 0b0..Do not include the channel in the matching process. + * 0b1..Include the channel in the matching process. + */ +#define FTM_PWMLOAD_CH1SEL(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_CH1SEL_SHIFT)) & FTM_PWMLOAD_CH1SEL_MASK) +#define FTM_PWMLOAD_CH2SEL_MASK (0x4U) +#define FTM_PWMLOAD_CH2SEL_SHIFT (2U) +/*! CH2SEL - Channel 2 Select + * 0b0..Do not include the channel in the matching process. + * 0b1..Include the channel in the matching process. + */ +#define FTM_PWMLOAD_CH2SEL(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_CH2SEL_SHIFT)) & FTM_PWMLOAD_CH2SEL_MASK) +#define FTM_PWMLOAD_CH3SEL_MASK (0x8U) +#define FTM_PWMLOAD_CH3SEL_SHIFT (3U) +/*! CH3SEL - Channel 3 Select + * 0b0..Do not include the channel in the matching process. + * 0b1..Include the channel in the matching process. + */ +#define FTM_PWMLOAD_CH3SEL(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_CH3SEL_SHIFT)) & FTM_PWMLOAD_CH3SEL_MASK) +#define FTM_PWMLOAD_CH4SEL_MASK (0x10U) +#define FTM_PWMLOAD_CH4SEL_SHIFT (4U) +/*! CH4SEL - Channel 4 Select + * 0b0..Do not include the channel in the matching process. + * 0b1..Include the channel in the matching process. + */ +#define FTM_PWMLOAD_CH4SEL(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_CH4SEL_SHIFT)) & FTM_PWMLOAD_CH4SEL_MASK) +#define FTM_PWMLOAD_CH5SEL_MASK (0x20U) +#define FTM_PWMLOAD_CH5SEL_SHIFT (5U) +/*! CH5SEL - Channel 5 Select + * 0b0..Do not include the channel in the matching process. + * 0b1..Include the channel in the matching process. + */ +#define FTM_PWMLOAD_CH5SEL(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_CH5SEL_SHIFT)) & FTM_PWMLOAD_CH5SEL_MASK) +#define FTM_PWMLOAD_CH6SEL_MASK (0x40U) +#define FTM_PWMLOAD_CH6SEL_SHIFT (6U) +/*! CH6SEL - Channel 6 Select + * 0b0..Do not include the channel in the matching process. + * 0b1..Include the channel in the matching process. + */ +#define FTM_PWMLOAD_CH6SEL(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_CH6SEL_SHIFT)) & FTM_PWMLOAD_CH6SEL_MASK) +#define FTM_PWMLOAD_CH7SEL_MASK (0x80U) +#define FTM_PWMLOAD_CH7SEL_SHIFT (7U) +/*! CH7SEL - Channel 7 Select + * 0b0..Do not include the channel in the matching process. + * 0b1..Include the channel in the matching process. + */ +#define FTM_PWMLOAD_CH7SEL(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_CH7SEL_SHIFT)) & FTM_PWMLOAD_CH7SEL_MASK) +#define FTM_PWMLOAD_LDOK_MASK (0x200U) +#define FTM_PWMLOAD_LDOK_SHIFT (9U) +/*! LDOK - Load Enable + * 0b0..Loading updated values is disabled. + * 0b1..Loading updated values is enabled. + */ +#define FTM_PWMLOAD_LDOK(x) (((uint32_t)(((uint32_t)(x)) << FTM_PWMLOAD_LDOK_SHIFT)) & FTM_PWMLOAD_LDOK_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group FTM_Register_Masks */ + + +/* FTM - Peripheral instance base addresses */ +/** Peripheral FTM0 base address */ +#define FTM0_BASE (0x40038000u) +/** Peripheral FTM0 base pointer */ +#define FTM0 ((FTM_Type *)FTM0_BASE) +/** Peripheral FTM1 base address */ +#define FTM1_BASE (0x40039000u) +/** Peripheral FTM1 base pointer */ +#define FTM1 ((FTM_Type *)FTM1_BASE) +/** Peripheral FTM2 base address */ +#define FTM2_BASE (0x4003A000u) +/** Peripheral FTM2 base pointer */ +#define FTM2 ((FTM_Type *)FTM2_BASE) +/** Peripheral FTM3 base address */ +#define FTM3_BASE (0x400B9000u) +/** Peripheral FTM3 base pointer */ +#define FTM3 ((FTM_Type *)FTM3_BASE) +/** Array initializer of FTM peripheral base addresses */ +#define FTM_BASE_ADDRS { FTM0_BASE, FTM1_BASE, FTM2_BASE, FTM3_BASE } +/** Array initializer of FTM peripheral base pointers */ +#define FTM_BASE_PTRS { FTM0, FTM1, FTM2, FTM3 } +/** Interrupt vectors for the FTM peripheral type */ +#define FTM_IRQS { FTM0_IRQn, FTM1_IRQn, FTM2_IRQn, FTM3_IRQn } + +/*! + * @} + */ /* end of group FTM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- GPIO Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GPIO_Peripheral_Access_Layer GPIO Peripheral Access Layer + * @{ + */ + +/** GPIO - Register Layout Typedef */ +typedef struct { + __IO uint32_t PDOR; /**< Port Data Output Register, offset: 0x0 */ + __O uint32_t PSOR; /**< Port Set Output Register, offset: 0x4 */ + __O uint32_t PCOR; /**< Port Clear Output Register, offset: 0x8 */ + __O uint32_t PTOR; /**< Port Toggle Output Register, offset: 0xC */ + __I uint32_t PDIR; /**< Port Data Input Register, offset: 0x10 */ + __IO uint32_t PDDR; /**< Port Data Direction Register, offset: 0x14 */ +} GPIO_Type; + +/* ---------------------------------------------------------------------------- + -- GPIO Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GPIO_Register_Masks GPIO Register Masks + * @{ + */ + +/*! @name PDOR - Port Data Output Register */ +/*! @{ */ +#define GPIO_PDOR_PDO_MASK (0xFFFFFFFFU) +#define GPIO_PDOR_PDO_SHIFT (0U) +/*! PDO - Port Data Output + * 0b00000000000000000000000000000000..Logic level 0 is driven on pin, provided pin is configured for general-purpose output. + * 0b00000000000000000000000000000001..Logic level 1 is driven on pin, provided pin is configured for general-purpose output. + */ +#define GPIO_PDOR_PDO(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PDOR_PDO_SHIFT)) & GPIO_PDOR_PDO_MASK) +/*! @} */ + +/*! @name PSOR - Port Set Output Register */ +/*! @{ */ +#define GPIO_PSOR_PTSO_MASK (0xFFFFFFFFU) +#define GPIO_PSOR_PTSO_SHIFT (0U) +/*! PTSO - Port Set Output + * 0b00000000000000000000000000000000..Corresponding bit in PDORn does not change. + * 0b00000000000000000000000000000001..Corresponding bit in PDORn is set to logic 1. + */ +#define GPIO_PSOR_PTSO(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PSOR_PTSO_SHIFT)) & GPIO_PSOR_PTSO_MASK) +/*! @} */ + +/*! @name PCOR - Port Clear Output Register */ +/*! @{ */ +#define GPIO_PCOR_PTCO_MASK (0xFFFFFFFFU) +#define GPIO_PCOR_PTCO_SHIFT (0U) +/*! PTCO - Port Clear Output + * 0b00000000000000000000000000000000..Corresponding bit in PDORn does not change. + * 0b00000000000000000000000000000001..Corresponding bit in PDORn is cleared to logic 0. + */ +#define GPIO_PCOR_PTCO(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PCOR_PTCO_SHIFT)) & GPIO_PCOR_PTCO_MASK) +/*! @} */ + +/*! @name PTOR - Port Toggle Output Register */ +/*! @{ */ +#define GPIO_PTOR_PTTO_MASK (0xFFFFFFFFU) +#define GPIO_PTOR_PTTO_SHIFT (0U) +/*! PTTO - Port Toggle Output + * 0b00000000000000000000000000000000..Corresponding bit in PDORn does not change. + * 0b00000000000000000000000000000001..Corresponding bit in PDORn is set to the inverse of its existing logic state. + */ +#define GPIO_PTOR_PTTO(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PTOR_PTTO_SHIFT)) & GPIO_PTOR_PTTO_MASK) +/*! @} */ + +/*! @name PDIR - Port Data Input Register */ +/*! @{ */ +#define GPIO_PDIR_PDI_MASK (0xFFFFFFFFU) +#define GPIO_PDIR_PDI_SHIFT (0U) +/*! PDI - Port Data Input + * 0b00000000000000000000000000000000..Pin logic level is logic 0, or is not configured for use by digital function. + * 0b00000000000000000000000000000001..Pin logic level is logic 1. + */ +#define GPIO_PDIR_PDI(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PDIR_PDI_SHIFT)) & GPIO_PDIR_PDI_MASK) +/*! @} */ + +/*! @name PDDR - Port Data Direction Register */ +/*! @{ */ +#define GPIO_PDDR_PDD_MASK (0xFFFFFFFFU) +#define GPIO_PDDR_PDD_SHIFT (0U) +/*! PDD - Port Data Direction + * 0b00000000000000000000000000000000..Pin is configured as general-purpose input, for the GPIO function. + * 0b00000000000000000000000000000001..Pin is configured as general-purpose output, for the GPIO function. + */ +#define GPIO_PDDR_PDD(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PDDR_PDD_SHIFT)) & GPIO_PDDR_PDD_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group GPIO_Register_Masks */ + + +/* GPIO - Peripheral instance base addresses */ +/** Peripheral GPIOA base address */ +#define GPIOA_BASE (0x400FF000u) +/** Peripheral GPIOA base pointer */ +#define GPIOA ((GPIO_Type *)GPIOA_BASE) +/** Peripheral GPIOB base address */ +#define GPIOB_BASE (0x400FF040u) +/** Peripheral GPIOB base pointer */ +#define GPIOB ((GPIO_Type *)GPIOB_BASE) +/** Peripheral GPIOC base address */ +#define GPIOC_BASE (0x400FF080u) +/** Peripheral GPIOC base pointer */ +#define GPIOC ((GPIO_Type *)GPIOC_BASE) +/** Peripheral GPIOD base address */ +#define GPIOD_BASE (0x400FF0C0u) +/** Peripheral GPIOD base pointer */ +#define GPIOD ((GPIO_Type *)GPIOD_BASE) +/** Peripheral GPIOE base address */ +#define GPIOE_BASE (0x400FF100u) +/** Peripheral GPIOE base pointer */ +#define GPIOE ((GPIO_Type *)GPIOE_BASE) +/** Array initializer of GPIO peripheral base addresses */ +#define GPIO_BASE_ADDRS { GPIOA_BASE, GPIOB_BASE, GPIOC_BASE, GPIOD_BASE, GPIOE_BASE } +/** Array initializer of GPIO peripheral base pointers */ +#define GPIO_BASE_PTRS { GPIOA, GPIOB, GPIOC, GPIOD, GPIOE } + +/*! + * @} + */ /* end of group GPIO_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- I2C Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2C_Peripheral_Access_Layer I2C Peripheral Access Layer + * @{ + */ + +/** I2C - Register Layout Typedef */ +typedef struct { + __IO uint8_t A1; /**< I2C Address Register 1, offset: 0x0 */ + __IO uint8_t F; /**< I2C Frequency Divider register, offset: 0x1 */ + __IO uint8_t C1; /**< I2C Control Register 1, offset: 0x2 */ + __IO uint8_t S; /**< I2C Status register, offset: 0x3 */ + __IO uint8_t D; /**< I2C Data I/O register, offset: 0x4 */ + __IO uint8_t C2; /**< I2C Control Register 2, offset: 0x5 */ + __IO uint8_t FLT; /**< I2C Programmable Input Glitch Filter register, offset: 0x6 */ + __IO uint8_t RA; /**< I2C Range Address register, offset: 0x7 */ + __IO uint8_t SMB; /**< I2C SMBus Control and Status register, offset: 0x8 */ + __IO uint8_t A2; /**< I2C Address Register 2, offset: 0x9 */ + __IO uint8_t SLTH; /**< I2C SCL Low Timeout Register High, offset: 0xA */ + __IO uint8_t SLTL; /**< I2C SCL Low Timeout Register Low, offset: 0xB */ +} I2C_Type; + +/* ---------------------------------------------------------------------------- + -- I2C Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2C_Register_Masks I2C Register Masks + * @{ + */ + +/*! @name A1 - I2C Address Register 1 */ +/*! @{ */ +#define I2C_A1_AD_MASK (0xFEU) +#define I2C_A1_AD_SHIFT (1U) +#define I2C_A1_AD(x) (((uint8_t)(((uint8_t)(x)) << I2C_A1_AD_SHIFT)) & I2C_A1_AD_MASK) +/*! @} */ + +/*! @name F - I2C Frequency Divider register */ +/*! @{ */ +#define I2C_F_ICR_MASK (0x3FU) +#define I2C_F_ICR_SHIFT (0U) +#define I2C_F_ICR(x) (((uint8_t)(((uint8_t)(x)) << I2C_F_ICR_SHIFT)) & I2C_F_ICR_MASK) +#define I2C_F_MULT_MASK (0xC0U) +#define I2C_F_MULT_SHIFT (6U) +/*! MULT - Multiplier Factor + * 0b00..mul = 1 + * 0b01..mul = 2 + * 0b10..mul = 4 + * 0b11..Reserved + */ +#define I2C_F_MULT(x) (((uint8_t)(((uint8_t)(x)) << I2C_F_MULT_SHIFT)) & I2C_F_MULT_MASK) +/*! @} */ + +/*! @name C1 - I2C Control Register 1 */ +/*! @{ */ +#define I2C_C1_DMAEN_MASK (0x1U) +#define I2C_C1_DMAEN_SHIFT (0U) +/*! DMAEN - DMA Enable + * 0b0..All DMA signalling disabled. + * 0b1..DMA transfer is enabled. While SMB[FACK] = 0, the following conditions trigger the DMA request: a data byte is received, and either address or data is transmitted. (ACK/NACK is automatic) the first byte received matches the A1 register or is a general call address. If any address matching occurs, S[IAAS] and S[TCF] are set. If the direction of transfer is known from master to slave, then it is not required to check S[SRW]. With this assumption, DMA can also be used in this case. In other cases, if the master reads data from the slave, then it is required to rewrite the C1 register operation. With this assumption, DMA cannot be used. When FACK = 1, an address or a data byte is transmitted. + */ +#define I2C_C1_DMAEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_DMAEN_SHIFT)) & I2C_C1_DMAEN_MASK) +#define I2C_C1_WUEN_MASK (0x2U) +#define I2C_C1_WUEN_SHIFT (1U) +/*! WUEN - Wakeup Enable + * 0b0..Normal operation. No interrupt generated when address matching in low power mode. + * 0b1..Enables the wakeup function in low power mode. + */ +#define I2C_C1_WUEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_WUEN_SHIFT)) & I2C_C1_WUEN_MASK) +#define I2C_C1_RSTA_MASK (0x4U) +#define I2C_C1_RSTA_SHIFT (2U) +#define I2C_C1_RSTA(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_RSTA_SHIFT)) & I2C_C1_RSTA_MASK) +#define I2C_C1_TXAK_MASK (0x8U) +#define I2C_C1_TXAK_SHIFT (3U) +/*! TXAK - Transmit Acknowledge Enable + * 0b0..An acknowledge signal is sent to the bus on the following receiving byte (if FACK is cleared) or the current receiving byte (if FACK is set). + * 0b1..No acknowledge signal is sent to the bus on the following receiving data byte (if FACK is cleared) or the current receiving data byte (if FACK is set). + */ +#define I2C_C1_TXAK(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_TXAK_SHIFT)) & I2C_C1_TXAK_MASK) +#define I2C_C1_TX_MASK (0x10U) +#define I2C_C1_TX_SHIFT (4U) +/*! TX - Transmit Mode Select + * 0b0..Receive + * 0b1..Transmit + */ +#define I2C_C1_TX(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_TX_SHIFT)) & I2C_C1_TX_MASK) +#define I2C_C1_MST_MASK (0x20U) +#define I2C_C1_MST_SHIFT (5U) +/*! MST - Master Mode Select + * 0b0..Slave mode + * 0b1..Master mode + */ +#define I2C_C1_MST(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_MST_SHIFT)) & I2C_C1_MST_MASK) +#define I2C_C1_IICIE_MASK (0x40U) +#define I2C_C1_IICIE_SHIFT (6U) +/*! IICIE - I2C Interrupt Enable + * 0b0..Disabled + * 0b1..Enabled + */ +#define I2C_C1_IICIE(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_IICIE_SHIFT)) & I2C_C1_IICIE_MASK) +#define I2C_C1_IICEN_MASK (0x80U) +#define I2C_C1_IICEN_SHIFT (7U) +/*! IICEN - I2C Enable + * 0b0..Disabled + * 0b1..Enabled + */ +#define I2C_C1_IICEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_C1_IICEN_SHIFT)) & I2C_C1_IICEN_MASK) +/*! @} */ + +/*! @name S - I2C Status register */ +/*! @{ */ +#define I2C_S_RXAK_MASK (0x1U) +#define I2C_S_RXAK_SHIFT (0U) +/*! RXAK - Receive Acknowledge + * 0b0..Acknowledge signal was received after the completion of one byte of data transmission on the bus + * 0b1..No acknowledge signal detected + */ +#define I2C_S_RXAK(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_RXAK_SHIFT)) & I2C_S_RXAK_MASK) +#define I2C_S_IICIF_MASK (0x2U) +#define I2C_S_IICIF_SHIFT (1U) +/*! IICIF - Interrupt Flag + * 0b0..No interrupt pending + * 0b1..Interrupt pending + */ +#define I2C_S_IICIF(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_IICIF_SHIFT)) & I2C_S_IICIF_MASK) +#define I2C_S_SRW_MASK (0x4U) +#define I2C_S_SRW_SHIFT (2U) +/*! SRW - Slave Read/Write + * 0b0..Slave receive, master writing to slave + * 0b1..Slave transmit, master reading from slave + */ +#define I2C_S_SRW(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_SRW_SHIFT)) & I2C_S_SRW_MASK) +#define I2C_S_RAM_MASK (0x8U) +#define I2C_S_RAM_SHIFT (3U) +/*! RAM - Range Address Match + * 0b0..Not addressed + * 0b1..Addressed as a slave + */ +#define I2C_S_RAM(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_RAM_SHIFT)) & I2C_S_RAM_MASK) +#define I2C_S_ARBL_MASK (0x10U) +#define I2C_S_ARBL_SHIFT (4U) +/*! ARBL - Arbitration Lost + * 0b0..Standard bus operation. + * 0b1..Loss of arbitration. + */ +#define I2C_S_ARBL(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_ARBL_SHIFT)) & I2C_S_ARBL_MASK) +#define I2C_S_BUSY_MASK (0x20U) +#define I2C_S_BUSY_SHIFT (5U) +/*! BUSY - Bus Busy + * 0b0..Bus is idle + * 0b1..Bus is busy + */ +#define I2C_S_BUSY(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_BUSY_SHIFT)) & I2C_S_BUSY_MASK) +#define I2C_S_IAAS_MASK (0x40U) +#define I2C_S_IAAS_SHIFT (6U) +/*! IAAS - Addressed As A Slave + * 0b0..Not addressed + * 0b1..Addressed as a slave + */ +#define I2C_S_IAAS(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_IAAS_SHIFT)) & I2C_S_IAAS_MASK) +#define I2C_S_TCF_MASK (0x80U) +#define I2C_S_TCF_SHIFT (7U) +/*! TCF - Transfer Complete Flag + * 0b0..Transfer in progress + * 0b1..Transfer complete + */ +#define I2C_S_TCF(x) (((uint8_t)(((uint8_t)(x)) << I2C_S_TCF_SHIFT)) & I2C_S_TCF_MASK) +/*! @} */ + +/*! @name D - I2C Data I/O register */ +/*! @{ */ +#define I2C_D_DATA_MASK (0xFFU) +#define I2C_D_DATA_SHIFT (0U) +#define I2C_D_DATA(x) (((uint8_t)(((uint8_t)(x)) << I2C_D_DATA_SHIFT)) & I2C_D_DATA_MASK) +/*! @} */ + +/*! @name C2 - I2C Control Register 2 */ +/*! @{ */ +#define I2C_C2_AD_MASK (0x7U) +#define I2C_C2_AD_SHIFT (0U) +#define I2C_C2_AD(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_AD_SHIFT)) & I2C_C2_AD_MASK) +#define I2C_C2_RMEN_MASK (0x8U) +#define I2C_C2_RMEN_SHIFT (3U) +/*! RMEN - Range Address Matching Enable + * 0b0..Range mode disabled. No address matching occurs for an address within the range of values of the A1 and RA registers. + * 0b1..Range mode enabled. Address matching occurs when a slave receives an address within the range of values of the A1 and RA registers. + */ +#define I2C_C2_RMEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_RMEN_SHIFT)) & I2C_C2_RMEN_MASK) +#define I2C_C2_SBRC_MASK (0x10U) +#define I2C_C2_SBRC_SHIFT (4U) +/*! SBRC - Slave Baud Rate Control + * 0b0..The slave baud rate follows the master baud rate and clock stretching may occur + * 0b1..Slave baud rate is independent of the master baud rate + */ +#define I2C_C2_SBRC(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_SBRC_SHIFT)) & I2C_C2_SBRC_MASK) +#define I2C_C2_HDRS_MASK (0x20U) +#define I2C_C2_HDRS_SHIFT (5U) +/*! HDRS - High Drive Select + * 0b0..Normal drive mode + * 0b1..High drive mode + */ +#define I2C_C2_HDRS(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_HDRS_SHIFT)) & I2C_C2_HDRS_MASK) +#define I2C_C2_ADEXT_MASK (0x40U) +#define I2C_C2_ADEXT_SHIFT (6U) +/*! ADEXT - Address Extension + * 0b0..7-bit address scheme + * 0b1..10-bit address scheme + */ +#define I2C_C2_ADEXT(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_ADEXT_SHIFT)) & I2C_C2_ADEXT_MASK) +#define I2C_C2_GCAEN_MASK (0x80U) +#define I2C_C2_GCAEN_SHIFT (7U) +/*! GCAEN - General Call Address Enable + * 0b0..Disabled + * 0b1..Enabled + */ +#define I2C_C2_GCAEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_C2_GCAEN_SHIFT)) & I2C_C2_GCAEN_MASK) +/*! @} */ + +/*! @name FLT - I2C Programmable Input Glitch Filter register */ +/*! @{ */ +#define I2C_FLT_FLT_MASK (0xFU) +#define I2C_FLT_FLT_SHIFT (0U) +/*! FLT - I2C Programmable Filter Factor + * 0b0000..No filter/bypass + */ +#define I2C_FLT_FLT(x) (((uint8_t)(((uint8_t)(x)) << I2C_FLT_FLT_SHIFT)) & I2C_FLT_FLT_MASK) +#define I2C_FLT_STARTF_MASK (0x10U) +#define I2C_FLT_STARTF_SHIFT (4U) +/*! STARTF - I2C Bus Start Detect Flag + * 0b0..No start happens on I2C bus + * 0b1..Start detected on I2C bus + */ +#define I2C_FLT_STARTF(x) (((uint8_t)(((uint8_t)(x)) << I2C_FLT_STARTF_SHIFT)) & I2C_FLT_STARTF_MASK) +#define I2C_FLT_SSIE_MASK (0x20U) +#define I2C_FLT_SSIE_SHIFT (5U) +/*! SSIE - I2C Bus Stop or Start Interrupt Enable + * 0b0..Stop or start detection interrupt is disabled + * 0b1..Stop or start detection interrupt is enabled + */ +#define I2C_FLT_SSIE(x) (((uint8_t)(((uint8_t)(x)) << I2C_FLT_SSIE_SHIFT)) & I2C_FLT_SSIE_MASK) +#define I2C_FLT_STOPF_MASK (0x40U) +#define I2C_FLT_STOPF_SHIFT (6U) +/*! STOPF - I2C Bus Stop Detect Flag + * 0b0..No stop happens on I2C bus + * 0b1..Stop detected on I2C bus + */ +#define I2C_FLT_STOPF(x) (((uint8_t)(((uint8_t)(x)) << I2C_FLT_STOPF_SHIFT)) & I2C_FLT_STOPF_MASK) +#define I2C_FLT_SHEN_MASK (0x80U) +#define I2C_FLT_SHEN_SHIFT (7U) +/*! SHEN - Stop Hold Enable + * 0b0..Stop holdoff is disabled. The MCU's entry to stop mode is not gated. + * 0b1..Stop holdoff is enabled. + */ +#define I2C_FLT_SHEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_FLT_SHEN_SHIFT)) & I2C_FLT_SHEN_MASK) +/*! @} */ + +/*! @name RA - I2C Range Address register */ +/*! @{ */ +#define I2C_RA_RAD_MASK (0xFEU) +#define I2C_RA_RAD_SHIFT (1U) +#define I2C_RA_RAD(x) (((uint8_t)(((uint8_t)(x)) << I2C_RA_RAD_SHIFT)) & I2C_RA_RAD_MASK) +/*! @} */ + +/*! @name SMB - I2C SMBus Control and Status register */ +/*! @{ */ +#define I2C_SMB_SHTF2IE_MASK (0x1U) +#define I2C_SMB_SHTF2IE_SHIFT (0U) +/*! SHTF2IE - SHTF2 Interrupt Enable + * 0b0..SHTF2 interrupt is disabled + * 0b1..SHTF2 interrupt is enabled + */ +#define I2C_SMB_SHTF2IE(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_SHTF2IE_SHIFT)) & I2C_SMB_SHTF2IE_MASK) +#define I2C_SMB_SHTF2_MASK (0x2U) +#define I2C_SMB_SHTF2_SHIFT (1U) +/*! SHTF2 - SCL High Timeout Flag 2 + * 0b0..No SCL high and SDA low timeout occurs + * 0b1..SCL high and SDA low timeout occurs + */ +#define I2C_SMB_SHTF2(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_SHTF2_SHIFT)) & I2C_SMB_SHTF2_MASK) +#define I2C_SMB_SHTF1_MASK (0x4U) +#define I2C_SMB_SHTF1_SHIFT (2U) +/*! SHTF1 - SCL High Timeout Flag 1 + * 0b0..No SCL high and SDA high timeout occurs + * 0b1..SCL high and SDA high timeout occurs + */ +#define I2C_SMB_SHTF1(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_SHTF1_SHIFT)) & I2C_SMB_SHTF1_MASK) +#define I2C_SMB_SLTF_MASK (0x8U) +#define I2C_SMB_SLTF_SHIFT (3U) +/*! SLTF - SCL Low Timeout Flag + * 0b0..No low timeout occurs + * 0b1..Low timeout occurs + */ +#define I2C_SMB_SLTF(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_SLTF_SHIFT)) & I2C_SMB_SLTF_MASK) +#define I2C_SMB_TCKSEL_MASK (0x10U) +#define I2C_SMB_TCKSEL_SHIFT (4U) +/*! TCKSEL - Timeout Counter Clock Select + * 0b0..Timeout counter counts at the frequency of the I2C module clock / 64 + * 0b1..Timeout counter counts at the frequency of the I2C module clock + */ +#define I2C_SMB_TCKSEL(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_TCKSEL_SHIFT)) & I2C_SMB_TCKSEL_MASK) +#define I2C_SMB_SIICAEN_MASK (0x20U) +#define I2C_SMB_SIICAEN_SHIFT (5U) +/*! SIICAEN - Second I2C Address Enable + * 0b0..I2C address register 2 matching is disabled + * 0b1..I2C address register 2 matching is enabled + */ +#define I2C_SMB_SIICAEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_SIICAEN_SHIFT)) & I2C_SMB_SIICAEN_MASK) +#define I2C_SMB_ALERTEN_MASK (0x40U) +#define I2C_SMB_ALERTEN_SHIFT (6U) +/*! ALERTEN - SMBus Alert Response Address Enable + * 0b0..SMBus alert response address matching is disabled + * 0b1..SMBus alert response address matching is enabled + */ +#define I2C_SMB_ALERTEN(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_ALERTEN_SHIFT)) & I2C_SMB_ALERTEN_MASK) +#define I2C_SMB_FACK_MASK (0x80U) +#define I2C_SMB_FACK_SHIFT (7U) +/*! FACK - Fast NACK/ACK Enable + * 0b0..An ACK or NACK is sent on the following receiving data byte + * 0b1..Writing 0 to TXAK after receiving a data byte generates an ACK. Writing 1 to TXAK after receiving a data byte generates a NACK. + */ +#define I2C_SMB_FACK(x) (((uint8_t)(((uint8_t)(x)) << I2C_SMB_FACK_SHIFT)) & I2C_SMB_FACK_MASK) +/*! @} */ + +/*! @name A2 - I2C Address Register 2 */ +/*! @{ */ +#define I2C_A2_SAD_MASK (0xFEU) +#define I2C_A2_SAD_SHIFT (1U) +#define I2C_A2_SAD(x) (((uint8_t)(((uint8_t)(x)) << I2C_A2_SAD_SHIFT)) & I2C_A2_SAD_MASK) +/*! @} */ + +/*! @name SLTH - I2C SCL Low Timeout Register High */ +/*! @{ */ +#define I2C_SLTH_SSLT_MASK (0xFFU) +#define I2C_SLTH_SSLT_SHIFT (0U) +#define I2C_SLTH_SSLT(x) (((uint8_t)(((uint8_t)(x)) << I2C_SLTH_SSLT_SHIFT)) & I2C_SLTH_SSLT_MASK) +/*! @} */ + +/*! @name SLTL - I2C SCL Low Timeout Register Low */ +/*! @{ */ +#define I2C_SLTL_SSLT_MASK (0xFFU) +#define I2C_SLTL_SSLT_SHIFT (0U) +#define I2C_SLTL_SSLT(x) (((uint8_t)(((uint8_t)(x)) << I2C_SLTL_SSLT_SHIFT)) & I2C_SLTL_SSLT_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group I2C_Register_Masks */ + + +/* I2C - Peripheral instance base addresses */ +/** Peripheral I2C0 base address */ +#define I2C0_BASE (0x40066000u) +/** Peripheral I2C0 base pointer */ +#define I2C0 ((I2C_Type *)I2C0_BASE) +/** Peripheral I2C1 base address */ +#define I2C1_BASE (0x40067000u) +/** Peripheral I2C1 base pointer */ +#define I2C1 ((I2C_Type *)I2C1_BASE) +/** Peripheral I2C2 base address */ +#define I2C2_BASE (0x400E6000u) +/** Peripheral I2C2 base pointer */ +#define I2C2 ((I2C_Type *)I2C2_BASE) +/** Array initializer of I2C peripheral base addresses */ +#define I2C_BASE_ADDRS { I2C0_BASE, I2C1_BASE, I2C2_BASE } +/** Array initializer of I2C peripheral base pointers */ +#define I2C_BASE_PTRS { I2C0, I2C1, I2C2 } +/** Interrupt vectors for the I2C peripheral type */ +#define I2C_IRQS { I2C0_IRQn, I2C1_IRQn, I2C2_IRQn } + +/*! + * @} + */ /* end of group I2C_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- I2S Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2S_Peripheral_Access_Layer I2S Peripheral Access Layer + * @{ + */ + +/** I2S - Register Layout Typedef */ +typedef struct { + __IO uint32_t TCSR; /**< SAI Transmit Control Register, offset: 0x0 */ + __IO uint32_t TCR1; /**< SAI Transmit Configuration 1 Register, offset: 0x4 */ + __IO uint32_t TCR2; /**< SAI Transmit Configuration 2 Register, offset: 0x8 */ + __IO uint32_t TCR3; /**< SAI Transmit Configuration 3 Register, offset: 0xC */ + __IO uint32_t TCR4; /**< SAI Transmit Configuration 4 Register, offset: 0x10 */ + __IO uint32_t TCR5; /**< SAI Transmit Configuration 5 Register, offset: 0x14 */ + uint8_t RESERVED_0[8]; + __O uint32_t TDR[2]; /**< SAI Transmit Data Register, array offset: 0x20, array step: 0x4 */ + uint8_t RESERVED_1[24]; + __I uint32_t TFR[2]; /**< SAI Transmit FIFO Register, array offset: 0x40, array step: 0x4 */ + uint8_t RESERVED_2[24]; + __IO uint32_t TMR; /**< SAI Transmit Mask Register, offset: 0x60 */ + uint8_t RESERVED_3[28]; + __IO uint32_t RCSR; /**< SAI Receive Control Register, offset: 0x80 */ + __IO uint32_t RCR1; /**< SAI Receive Configuration 1 Register, offset: 0x84 */ + __IO uint32_t RCR2; /**< SAI Receive Configuration 2 Register, offset: 0x88 */ + __IO uint32_t RCR3; /**< SAI Receive Configuration 3 Register, offset: 0x8C */ + __IO uint32_t RCR4; /**< SAI Receive Configuration 4 Register, offset: 0x90 */ + __IO uint32_t RCR5; /**< SAI Receive Configuration 5 Register, offset: 0x94 */ + uint8_t RESERVED_4[8]; + __I uint32_t RDR[2]; /**< SAI Receive Data Register, array offset: 0xA0, array step: 0x4 */ + uint8_t RESERVED_5[24]; + __I uint32_t RFR[2]; /**< SAI Receive FIFO Register, array offset: 0xC0, array step: 0x4 */ + uint8_t RESERVED_6[24]; + __IO uint32_t RMR; /**< SAI Receive Mask Register, offset: 0xE0 */ + uint8_t RESERVED_7[28]; + __IO uint32_t MCR; /**< SAI MCLK Control Register, offset: 0x100 */ + __IO uint32_t MDR; /**< SAI MCLK Divide Register, offset: 0x104 */ +} I2S_Type; + +/* ---------------------------------------------------------------------------- + -- I2S Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2S_Register_Masks I2S Register Masks + * @{ + */ + +/*! @name TCSR - SAI Transmit Control Register */ +/*! @{ */ +#define I2S_TCSR_FRDE_MASK (0x1U) +#define I2S_TCSR_FRDE_SHIFT (0U) +/*! FRDE - FIFO Request DMA Enable + * 0b0..Disables the DMA request. + * 0b1..Enables the DMA request. + */ +#define I2S_TCSR_FRDE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FRDE_SHIFT)) & I2S_TCSR_FRDE_MASK) +#define I2S_TCSR_FWDE_MASK (0x2U) +#define I2S_TCSR_FWDE_SHIFT (1U) +/*! FWDE - FIFO Warning DMA Enable + * 0b0..Disables the DMA request. + * 0b1..Enables the DMA request. + */ +#define I2S_TCSR_FWDE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FWDE_SHIFT)) & I2S_TCSR_FWDE_MASK) +#define I2S_TCSR_FRIE_MASK (0x100U) +#define I2S_TCSR_FRIE_SHIFT (8U) +/*! FRIE - FIFO Request Interrupt Enable + * 0b0..Disables the interrupt. + * 0b1..Enables the interrupt. + */ +#define I2S_TCSR_FRIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FRIE_SHIFT)) & I2S_TCSR_FRIE_MASK) +#define I2S_TCSR_FWIE_MASK (0x200U) +#define I2S_TCSR_FWIE_SHIFT (9U) +/*! FWIE - FIFO Warning Interrupt Enable + * 0b0..Disables the interrupt. + * 0b1..Enables the interrupt. + */ +#define I2S_TCSR_FWIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FWIE_SHIFT)) & I2S_TCSR_FWIE_MASK) +#define I2S_TCSR_FEIE_MASK (0x400U) +#define I2S_TCSR_FEIE_SHIFT (10U) +/*! FEIE - FIFO Error Interrupt Enable + * 0b0..Disables the interrupt. + * 0b1..Enables the interrupt. + */ +#define I2S_TCSR_FEIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FEIE_SHIFT)) & I2S_TCSR_FEIE_MASK) +#define I2S_TCSR_SEIE_MASK (0x800U) +#define I2S_TCSR_SEIE_SHIFT (11U) +/*! SEIE - Sync Error Interrupt Enable + * 0b0..Disables interrupt. + * 0b1..Enables interrupt. + */ +#define I2S_TCSR_SEIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_SEIE_SHIFT)) & I2S_TCSR_SEIE_MASK) +#define I2S_TCSR_WSIE_MASK (0x1000U) +#define I2S_TCSR_WSIE_SHIFT (12U) +/*! WSIE - Word Start Interrupt Enable + * 0b0..Disables interrupt. + * 0b1..Enables interrupt. + */ +#define I2S_TCSR_WSIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_WSIE_SHIFT)) & I2S_TCSR_WSIE_MASK) +#define I2S_TCSR_FRF_MASK (0x10000U) +#define I2S_TCSR_FRF_SHIFT (16U) +/*! FRF - FIFO Request Flag + * 0b0..Transmit FIFO watermark has not been reached. + * 0b1..Transmit FIFO watermark has been reached. + */ +#define I2S_TCSR_FRF(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FRF_SHIFT)) & I2S_TCSR_FRF_MASK) +#define I2S_TCSR_FWF_MASK (0x20000U) +#define I2S_TCSR_FWF_SHIFT (17U) +/*! FWF - FIFO Warning Flag + * 0b0..No enabled transmit FIFO is empty. + * 0b1..Enabled transmit FIFO is empty. + */ +#define I2S_TCSR_FWF(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FWF_SHIFT)) & I2S_TCSR_FWF_MASK) +#define I2S_TCSR_FEF_MASK (0x40000U) +#define I2S_TCSR_FEF_SHIFT (18U) +/*! FEF - FIFO Error Flag + * 0b0..Transmit underrun not detected. + * 0b1..Transmit underrun detected. + */ +#define I2S_TCSR_FEF(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FEF_SHIFT)) & I2S_TCSR_FEF_MASK) +#define I2S_TCSR_SEF_MASK (0x80000U) +#define I2S_TCSR_SEF_SHIFT (19U) +/*! SEF - Sync Error Flag + * 0b0..Sync error not detected. + * 0b1..Frame sync error detected. + */ +#define I2S_TCSR_SEF(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_SEF_SHIFT)) & I2S_TCSR_SEF_MASK) +#define I2S_TCSR_WSF_MASK (0x100000U) +#define I2S_TCSR_WSF_SHIFT (20U) +/*! WSF - Word Start Flag + * 0b0..Start of word not detected. + * 0b1..Start of word detected. + */ +#define I2S_TCSR_WSF(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_WSF_SHIFT)) & I2S_TCSR_WSF_MASK) +#define I2S_TCSR_SR_MASK (0x1000000U) +#define I2S_TCSR_SR_SHIFT (24U) +/*! SR - Software Reset + * 0b0..No effect. + * 0b1..Software reset. + */ +#define I2S_TCSR_SR(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_SR_SHIFT)) & I2S_TCSR_SR_MASK) +#define I2S_TCSR_FR_MASK (0x2000000U) +#define I2S_TCSR_FR_SHIFT (25U) +/*! FR - FIFO Reset + * 0b0..No effect. + * 0b1..FIFO reset. + */ +#define I2S_TCSR_FR(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_FR_SHIFT)) & I2S_TCSR_FR_MASK) +#define I2S_TCSR_BCE_MASK (0x10000000U) +#define I2S_TCSR_BCE_SHIFT (28U) +/*! BCE - Bit Clock Enable + * 0b0..Transmit bit clock is disabled. + * 0b1..Transmit bit clock is enabled. + */ +#define I2S_TCSR_BCE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_BCE_SHIFT)) & I2S_TCSR_BCE_MASK) +#define I2S_TCSR_DBGE_MASK (0x20000000U) +#define I2S_TCSR_DBGE_SHIFT (29U) +/*! DBGE - Debug Enable + * 0b0..Transmitter is disabled in Debug mode, after completing the current frame. + * 0b1..Transmitter is enabled in Debug mode. + */ +#define I2S_TCSR_DBGE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_DBGE_SHIFT)) & I2S_TCSR_DBGE_MASK) +#define I2S_TCSR_STOPE_MASK (0x40000000U) +#define I2S_TCSR_STOPE_SHIFT (30U) +/*! STOPE - Stop Enable + * 0b0..Transmitter disabled in Stop mode. + * 0b1..Transmitter enabled in Stop mode. + */ +#define I2S_TCSR_STOPE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_STOPE_SHIFT)) & I2S_TCSR_STOPE_MASK) +#define I2S_TCSR_TE_MASK (0x80000000U) +#define I2S_TCSR_TE_SHIFT (31U) +/*! TE - Transmitter Enable + * 0b0..Transmitter is disabled. + * 0b1..Transmitter is enabled, or transmitter has been disabled and has not yet reached end of frame. + */ +#define I2S_TCSR_TE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCSR_TE_SHIFT)) & I2S_TCSR_TE_MASK) +/*! @} */ + +/*! @name TCR1 - SAI Transmit Configuration 1 Register */ +/*! @{ */ +#define I2S_TCR1_TFW_MASK (0x7U) +#define I2S_TCR1_TFW_SHIFT (0U) +#define I2S_TCR1_TFW(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR1_TFW_SHIFT)) & I2S_TCR1_TFW_MASK) +/*! @} */ + +/*! @name TCR2 - SAI Transmit Configuration 2 Register */ +/*! @{ */ +#define I2S_TCR2_DIV_MASK (0xFFU) +#define I2S_TCR2_DIV_SHIFT (0U) +#define I2S_TCR2_DIV(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_DIV_SHIFT)) & I2S_TCR2_DIV_MASK) +#define I2S_TCR2_BCD_MASK (0x1000000U) +#define I2S_TCR2_BCD_SHIFT (24U) +/*! BCD - Bit Clock Direction + * 0b0..Bit clock is generated externally in Slave mode. + * 0b1..Bit clock is generated internally in Master mode. + */ +#define I2S_TCR2_BCD(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_BCD_SHIFT)) & I2S_TCR2_BCD_MASK) +#define I2S_TCR2_BCP_MASK (0x2000000U) +#define I2S_TCR2_BCP_SHIFT (25U) +/*! BCP - Bit Clock Polarity + * 0b0..Bit clock is active high with drive outputs on rising edge and sample inputs on falling edge. + * 0b1..Bit clock is active low with drive outputs on falling edge and sample inputs on rising edge. + */ +#define I2S_TCR2_BCP(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_BCP_SHIFT)) & I2S_TCR2_BCP_MASK) +#define I2S_TCR2_MSEL_MASK (0xC000000U) +#define I2S_TCR2_MSEL_SHIFT (26U) +/*! MSEL - MCLK Select + * 0b00..Bus Clock selected. + * 0b01..Master Clock (MCLK) 1 option selected. + * 0b10..Master Clock (MCLK) 2 option selected. + * 0b11..Master Clock (MCLK) 3 option selected. + */ +#define I2S_TCR2_MSEL(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_MSEL_SHIFT)) & I2S_TCR2_MSEL_MASK) +#define I2S_TCR2_BCI_MASK (0x10000000U) +#define I2S_TCR2_BCI_SHIFT (28U) +/*! BCI - Bit Clock Input + * 0b0..No effect. + * 0b1..Internal logic is clocked as if bit clock was externally generated. + */ +#define I2S_TCR2_BCI(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_BCI_SHIFT)) & I2S_TCR2_BCI_MASK) +#define I2S_TCR2_BCS_MASK (0x20000000U) +#define I2S_TCR2_BCS_SHIFT (29U) +/*! BCS - Bit Clock Swap + * 0b0..Use the normal bit clock source. + * 0b1..Swap the bit clock source. + */ +#define I2S_TCR2_BCS(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_BCS_SHIFT)) & I2S_TCR2_BCS_MASK) +#define I2S_TCR2_SYNC_MASK (0xC0000000U) +#define I2S_TCR2_SYNC_SHIFT (30U) +/*! SYNC - Synchronous Mode + * 0b00..Asynchronous mode. + * 0b01..Synchronous with receiver. + * 0b10..Synchronous with another SAI transmitter. + * 0b11..Synchronous with another SAI receiver. + */ +#define I2S_TCR2_SYNC(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR2_SYNC_SHIFT)) & I2S_TCR2_SYNC_MASK) +/*! @} */ + +/*! @name TCR3 - SAI Transmit Configuration 3 Register */ +/*! @{ */ +#define I2S_TCR3_WDFL_MASK (0x1FU) +#define I2S_TCR3_WDFL_SHIFT (0U) +#define I2S_TCR3_WDFL(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR3_WDFL_SHIFT)) & I2S_TCR3_WDFL_MASK) +#define I2S_TCR3_TCE_MASK (0x30000U) +#define I2S_TCR3_TCE_SHIFT (16U) +/*! TCE - Transmit Channel Enable + * 0b00..Transmit data channel N is disabled. + * 0b01..Transmit data channel N is enabled. + */ +#define I2S_TCR3_TCE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR3_TCE_SHIFT)) & I2S_TCR3_TCE_MASK) +/*! @} */ + +/*! @name TCR4 - SAI Transmit Configuration 4 Register */ +/*! @{ */ +#define I2S_TCR4_FSD_MASK (0x1U) +#define I2S_TCR4_FSD_SHIFT (0U) +/*! FSD - Frame Sync Direction + * 0b0..Frame sync is generated externally in Slave mode. + * 0b1..Frame sync is generated internally in Master mode. + */ +#define I2S_TCR4_FSD(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_FSD_SHIFT)) & I2S_TCR4_FSD_MASK) +#define I2S_TCR4_FSP_MASK (0x2U) +#define I2S_TCR4_FSP_SHIFT (1U) +/*! FSP - Frame Sync Polarity + * 0b0..Frame sync is active high. + * 0b1..Frame sync is active low. + */ +#define I2S_TCR4_FSP(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_FSP_SHIFT)) & I2S_TCR4_FSP_MASK) +#define I2S_TCR4_FSE_MASK (0x8U) +#define I2S_TCR4_FSE_SHIFT (3U) +/*! FSE - Frame Sync Early + * 0b0..Frame sync asserts with the first bit of the frame. + * 0b1..Frame sync asserts one bit before the first bit of the frame. + */ +#define I2S_TCR4_FSE(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_FSE_SHIFT)) & I2S_TCR4_FSE_MASK) +#define I2S_TCR4_MF_MASK (0x10U) +#define I2S_TCR4_MF_SHIFT (4U) +/*! MF - MSB First + * 0b0..LSB is transmitted first. + * 0b1..MSB is transmitted first. + */ +#define I2S_TCR4_MF(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_MF_SHIFT)) & I2S_TCR4_MF_MASK) +#define I2S_TCR4_SYWD_MASK (0x1F00U) +#define I2S_TCR4_SYWD_SHIFT (8U) +#define I2S_TCR4_SYWD(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_SYWD_SHIFT)) & I2S_TCR4_SYWD_MASK) +#define I2S_TCR4_FRSZ_MASK (0x1F0000U) +#define I2S_TCR4_FRSZ_SHIFT (16U) +#define I2S_TCR4_FRSZ(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR4_FRSZ_SHIFT)) & I2S_TCR4_FRSZ_MASK) +/*! @} */ + +/*! @name TCR5 - SAI Transmit Configuration 5 Register */ +/*! @{ */ +#define I2S_TCR5_FBT_MASK (0x1F00U) +#define I2S_TCR5_FBT_SHIFT (8U) +#define I2S_TCR5_FBT(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR5_FBT_SHIFT)) & I2S_TCR5_FBT_MASK) +#define I2S_TCR5_W0W_MASK (0x1F0000U) +#define I2S_TCR5_W0W_SHIFT (16U) +#define I2S_TCR5_W0W(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR5_W0W_SHIFT)) & I2S_TCR5_W0W_MASK) +#define I2S_TCR5_WNW_MASK (0x1F000000U) +#define I2S_TCR5_WNW_SHIFT (24U) +#define I2S_TCR5_WNW(x) (((uint32_t)(((uint32_t)(x)) << I2S_TCR5_WNW_SHIFT)) & I2S_TCR5_WNW_MASK) +/*! @} */ + +/*! @name TDR - SAI Transmit Data Register */ +/*! @{ */ +#define I2S_TDR_TDR_MASK (0xFFFFFFFFU) +#define I2S_TDR_TDR_SHIFT (0U) +#define I2S_TDR_TDR(x) (((uint32_t)(((uint32_t)(x)) << I2S_TDR_TDR_SHIFT)) & I2S_TDR_TDR_MASK) +/*! @} */ + +/* The count of I2S_TDR */ +#define I2S_TDR_COUNT (2U) + +/*! @name TFR - SAI Transmit FIFO Register */ +/*! @{ */ +#define I2S_TFR_RFP_MASK (0xFU) +#define I2S_TFR_RFP_SHIFT (0U) +#define I2S_TFR_RFP(x) (((uint32_t)(((uint32_t)(x)) << I2S_TFR_RFP_SHIFT)) & I2S_TFR_RFP_MASK) +#define I2S_TFR_WFP_MASK (0xF0000U) +#define I2S_TFR_WFP_SHIFT (16U) +#define I2S_TFR_WFP(x) (((uint32_t)(((uint32_t)(x)) << I2S_TFR_WFP_SHIFT)) & I2S_TFR_WFP_MASK) +/*! @} */ + +/* The count of I2S_TFR */ +#define I2S_TFR_COUNT (2U) + +/*! @name TMR - SAI Transmit Mask Register */ +/*! @{ */ +#define I2S_TMR_TWM_MASK (0xFFFFFFFFU) +#define I2S_TMR_TWM_SHIFT (0U) +/*! TWM - Transmit Word Mask + * 0b00000000000000000000000000000000..Word N is enabled. + * 0b00000000000000000000000000000001..Word N is masked. The transmit data pins are tri-stated when masked. + */ +#define I2S_TMR_TWM(x) (((uint32_t)(((uint32_t)(x)) << I2S_TMR_TWM_SHIFT)) & I2S_TMR_TWM_MASK) +/*! @} */ + +/*! @name RCSR - SAI Receive Control Register */ +/*! @{ */ +#define I2S_RCSR_FRDE_MASK (0x1U) +#define I2S_RCSR_FRDE_SHIFT (0U) +/*! FRDE - FIFO Request DMA Enable + * 0b0..Disables the DMA request. + * 0b1..Enables the DMA request. + */ +#define I2S_RCSR_FRDE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FRDE_SHIFT)) & I2S_RCSR_FRDE_MASK) +#define I2S_RCSR_FWDE_MASK (0x2U) +#define I2S_RCSR_FWDE_SHIFT (1U) +/*! FWDE - FIFO Warning DMA Enable + * 0b0..Disables the DMA request. + * 0b1..Enables the DMA request. + */ +#define I2S_RCSR_FWDE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FWDE_SHIFT)) & I2S_RCSR_FWDE_MASK) +#define I2S_RCSR_FRIE_MASK (0x100U) +#define I2S_RCSR_FRIE_SHIFT (8U) +/*! FRIE - FIFO Request Interrupt Enable + * 0b0..Disables the interrupt. + * 0b1..Enables the interrupt. + */ +#define I2S_RCSR_FRIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FRIE_SHIFT)) & I2S_RCSR_FRIE_MASK) +#define I2S_RCSR_FWIE_MASK (0x200U) +#define I2S_RCSR_FWIE_SHIFT (9U) +/*! FWIE - FIFO Warning Interrupt Enable + * 0b0..Disables the interrupt. + * 0b1..Enables the interrupt. + */ +#define I2S_RCSR_FWIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FWIE_SHIFT)) & I2S_RCSR_FWIE_MASK) +#define I2S_RCSR_FEIE_MASK (0x400U) +#define I2S_RCSR_FEIE_SHIFT (10U) +/*! FEIE - FIFO Error Interrupt Enable + * 0b0..Disables the interrupt. + * 0b1..Enables the interrupt. + */ +#define I2S_RCSR_FEIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FEIE_SHIFT)) & I2S_RCSR_FEIE_MASK) +#define I2S_RCSR_SEIE_MASK (0x800U) +#define I2S_RCSR_SEIE_SHIFT (11U) +/*! SEIE - Sync Error Interrupt Enable + * 0b0..Disables interrupt. + * 0b1..Enables interrupt. + */ +#define I2S_RCSR_SEIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_SEIE_SHIFT)) & I2S_RCSR_SEIE_MASK) +#define I2S_RCSR_WSIE_MASK (0x1000U) +#define I2S_RCSR_WSIE_SHIFT (12U) +/*! WSIE - Word Start Interrupt Enable + * 0b0..Disables interrupt. + * 0b1..Enables interrupt. + */ +#define I2S_RCSR_WSIE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_WSIE_SHIFT)) & I2S_RCSR_WSIE_MASK) +#define I2S_RCSR_FRF_MASK (0x10000U) +#define I2S_RCSR_FRF_SHIFT (16U) +/*! FRF - FIFO Request Flag + * 0b0..Receive FIFO watermark not reached. + * 0b1..Receive FIFO watermark has been reached. + */ +#define I2S_RCSR_FRF(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FRF_SHIFT)) & I2S_RCSR_FRF_MASK) +#define I2S_RCSR_FWF_MASK (0x20000U) +#define I2S_RCSR_FWF_SHIFT (17U) +/*! FWF - FIFO Warning Flag + * 0b0..No enabled receive FIFO is full. + * 0b1..Enabled receive FIFO is full. + */ +#define I2S_RCSR_FWF(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FWF_SHIFT)) & I2S_RCSR_FWF_MASK) +#define I2S_RCSR_FEF_MASK (0x40000U) +#define I2S_RCSR_FEF_SHIFT (18U) +/*! FEF - FIFO Error Flag + * 0b0..Receive overflow not detected. + * 0b1..Receive overflow detected. + */ +#define I2S_RCSR_FEF(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FEF_SHIFT)) & I2S_RCSR_FEF_MASK) +#define I2S_RCSR_SEF_MASK (0x80000U) +#define I2S_RCSR_SEF_SHIFT (19U) +/*! SEF - Sync Error Flag + * 0b0..Sync error not detected. + * 0b1..Frame sync error detected. + */ +#define I2S_RCSR_SEF(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_SEF_SHIFT)) & I2S_RCSR_SEF_MASK) +#define I2S_RCSR_WSF_MASK (0x100000U) +#define I2S_RCSR_WSF_SHIFT (20U) +/*! WSF - Word Start Flag + * 0b0..Start of word not detected. + * 0b1..Start of word detected. + */ +#define I2S_RCSR_WSF(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_WSF_SHIFT)) & I2S_RCSR_WSF_MASK) +#define I2S_RCSR_SR_MASK (0x1000000U) +#define I2S_RCSR_SR_SHIFT (24U) +/*! SR - Software Reset + * 0b0..No effect. + * 0b1..Software reset. + */ +#define I2S_RCSR_SR(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_SR_SHIFT)) & I2S_RCSR_SR_MASK) +#define I2S_RCSR_FR_MASK (0x2000000U) +#define I2S_RCSR_FR_SHIFT (25U) +/*! FR - FIFO Reset + * 0b0..No effect. + * 0b1..FIFO reset. + */ +#define I2S_RCSR_FR(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_FR_SHIFT)) & I2S_RCSR_FR_MASK) +#define I2S_RCSR_BCE_MASK (0x10000000U) +#define I2S_RCSR_BCE_SHIFT (28U) +/*! BCE - Bit Clock Enable + * 0b0..Receive bit clock is disabled. + * 0b1..Receive bit clock is enabled. + */ +#define I2S_RCSR_BCE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_BCE_SHIFT)) & I2S_RCSR_BCE_MASK) +#define I2S_RCSR_DBGE_MASK (0x20000000U) +#define I2S_RCSR_DBGE_SHIFT (29U) +/*! DBGE - Debug Enable + * 0b0..Receiver is disabled in Debug mode, after completing the current frame. + * 0b1..Receiver is enabled in Debug mode. + */ +#define I2S_RCSR_DBGE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_DBGE_SHIFT)) & I2S_RCSR_DBGE_MASK) +#define I2S_RCSR_STOPE_MASK (0x40000000U) +#define I2S_RCSR_STOPE_SHIFT (30U) +/*! STOPE - Stop Enable + * 0b0..Receiver disabled in Stop mode. + * 0b1..Receiver enabled in Stop mode. + */ +#define I2S_RCSR_STOPE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_STOPE_SHIFT)) & I2S_RCSR_STOPE_MASK) +#define I2S_RCSR_RE_MASK (0x80000000U) +#define I2S_RCSR_RE_SHIFT (31U) +/*! RE - Receiver Enable + * 0b0..Receiver is disabled. + * 0b1..Receiver is enabled, or receiver has been disabled and has not yet reached end of frame. + */ +#define I2S_RCSR_RE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCSR_RE_SHIFT)) & I2S_RCSR_RE_MASK) +/*! @} */ + +/*! @name RCR1 - SAI Receive Configuration 1 Register */ +/*! @{ */ +#define I2S_RCR1_RFW_MASK (0x7U) +#define I2S_RCR1_RFW_SHIFT (0U) +#define I2S_RCR1_RFW(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR1_RFW_SHIFT)) & I2S_RCR1_RFW_MASK) +/*! @} */ + +/*! @name RCR2 - SAI Receive Configuration 2 Register */ +/*! @{ */ +#define I2S_RCR2_DIV_MASK (0xFFU) +#define I2S_RCR2_DIV_SHIFT (0U) +#define I2S_RCR2_DIV(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_DIV_SHIFT)) & I2S_RCR2_DIV_MASK) +#define I2S_RCR2_BCD_MASK (0x1000000U) +#define I2S_RCR2_BCD_SHIFT (24U) +/*! BCD - Bit Clock Direction + * 0b0..Bit clock is generated externally in Slave mode. + * 0b1..Bit clock is generated internally in Master mode. + */ +#define I2S_RCR2_BCD(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_BCD_SHIFT)) & I2S_RCR2_BCD_MASK) +#define I2S_RCR2_BCP_MASK (0x2000000U) +#define I2S_RCR2_BCP_SHIFT (25U) +/*! BCP - Bit Clock Polarity + * 0b0..Bit Clock is active high with drive outputs on rising edge and sample inputs on falling edge. + * 0b1..Bit Clock is active low with drive outputs on falling edge and sample inputs on rising edge. + */ +#define I2S_RCR2_BCP(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_BCP_SHIFT)) & I2S_RCR2_BCP_MASK) +#define I2S_RCR2_MSEL_MASK (0xC000000U) +#define I2S_RCR2_MSEL_SHIFT (26U) +/*! MSEL - MCLK Select + * 0b00..Bus Clock selected. + * 0b01..Master Clock (MCLK) 1 option selected. + * 0b10..Master Clock (MCLK) 2 option selected. + * 0b11..Master Clock (MCLK) 3 option selected. + */ +#define I2S_RCR2_MSEL(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_MSEL_SHIFT)) & I2S_RCR2_MSEL_MASK) +#define I2S_RCR2_BCI_MASK (0x10000000U) +#define I2S_RCR2_BCI_SHIFT (28U) +/*! BCI - Bit Clock Input + * 0b0..No effect. + * 0b1..Internal logic is clocked as if bit clock was externally generated. + */ +#define I2S_RCR2_BCI(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_BCI_SHIFT)) & I2S_RCR2_BCI_MASK) +#define I2S_RCR2_BCS_MASK (0x20000000U) +#define I2S_RCR2_BCS_SHIFT (29U) +/*! BCS - Bit Clock Swap + * 0b0..Use the normal bit clock source. + * 0b1..Swap the bit clock source. + */ +#define I2S_RCR2_BCS(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_BCS_SHIFT)) & I2S_RCR2_BCS_MASK) +#define I2S_RCR2_SYNC_MASK (0xC0000000U) +#define I2S_RCR2_SYNC_SHIFT (30U) +/*! SYNC - Synchronous Mode + * 0b00..Asynchronous mode. + * 0b01..Synchronous with transmitter. + * 0b10..Synchronous with another SAI receiver. + * 0b11..Synchronous with another SAI transmitter. + */ +#define I2S_RCR2_SYNC(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR2_SYNC_SHIFT)) & I2S_RCR2_SYNC_MASK) +/*! @} */ + +/*! @name RCR3 - SAI Receive Configuration 3 Register */ +/*! @{ */ +#define I2S_RCR3_WDFL_MASK (0x1FU) +#define I2S_RCR3_WDFL_SHIFT (0U) +#define I2S_RCR3_WDFL(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR3_WDFL_SHIFT)) & I2S_RCR3_WDFL_MASK) +#define I2S_RCR3_RCE_MASK (0x30000U) +#define I2S_RCR3_RCE_SHIFT (16U) +/*! RCE - Receive Channel Enable + * 0b00..Receive data channel N is disabled. + * 0b01..Receive data channel N is enabled. + */ +#define I2S_RCR3_RCE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR3_RCE_SHIFT)) & I2S_RCR3_RCE_MASK) +/*! @} */ + +/*! @name RCR4 - SAI Receive Configuration 4 Register */ +/*! @{ */ +#define I2S_RCR4_FSD_MASK (0x1U) +#define I2S_RCR4_FSD_SHIFT (0U) +/*! FSD - Frame Sync Direction + * 0b0..Frame Sync is generated externally in Slave mode. + * 0b1..Frame Sync is generated internally in Master mode. + */ +#define I2S_RCR4_FSD(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_FSD_SHIFT)) & I2S_RCR4_FSD_MASK) +#define I2S_RCR4_FSP_MASK (0x2U) +#define I2S_RCR4_FSP_SHIFT (1U) +/*! FSP - Frame Sync Polarity + * 0b0..Frame sync is active high. + * 0b1..Frame sync is active low. + */ +#define I2S_RCR4_FSP(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_FSP_SHIFT)) & I2S_RCR4_FSP_MASK) +#define I2S_RCR4_FSE_MASK (0x8U) +#define I2S_RCR4_FSE_SHIFT (3U) +/*! FSE - Frame Sync Early + * 0b0..Frame sync asserts with the first bit of the frame. + * 0b1..Frame sync asserts one bit before the first bit of the frame. + */ +#define I2S_RCR4_FSE(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_FSE_SHIFT)) & I2S_RCR4_FSE_MASK) +#define I2S_RCR4_MF_MASK (0x10U) +#define I2S_RCR4_MF_SHIFT (4U) +/*! MF - MSB First + * 0b0..LSB is received first. + * 0b1..MSB is received first. + */ +#define I2S_RCR4_MF(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_MF_SHIFT)) & I2S_RCR4_MF_MASK) +#define I2S_RCR4_SYWD_MASK (0x1F00U) +#define I2S_RCR4_SYWD_SHIFT (8U) +#define I2S_RCR4_SYWD(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_SYWD_SHIFT)) & I2S_RCR4_SYWD_MASK) +#define I2S_RCR4_FRSZ_MASK (0x1F0000U) +#define I2S_RCR4_FRSZ_SHIFT (16U) +#define I2S_RCR4_FRSZ(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR4_FRSZ_SHIFT)) & I2S_RCR4_FRSZ_MASK) +/*! @} */ + +/*! @name RCR5 - SAI Receive Configuration 5 Register */ +/*! @{ */ +#define I2S_RCR5_FBT_MASK (0x1F00U) +#define I2S_RCR5_FBT_SHIFT (8U) +#define I2S_RCR5_FBT(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR5_FBT_SHIFT)) & I2S_RCR5_FBT_MASK) +#define I2S_RCR5_W0W_MASK (0x1F0000U) +#define I2S_RCR5_W0W_SHIFT (16U) +#define I2S_RCR5_W0W(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR5_W0W_SHIFT)) & I2S_RCR5_W0W_MASK) +#define I2S_RCR5_WNW_MASK (0x1F000000U) +#define I2S_RCR5_WNW_SHIFT (24U) +#define I2S_RCR5_WNW(x) (((uint32_t)(((uint32_t)(x)) << I2S_RCR5_WNW_SHIFT)) & I2S_RCR5_WNW_MASK) +/*! @} */ + +/*! @name RDR - SAI Receive Data Register */ +/*! @{ */ +#define I2S_RDR_RDR_MASK (0xFFFFFFFFU) +#define I2S_RDR_RDR_SHIFT (0U) +#define I2S_RDR_RDR(x) (((uint32_t)(((uint32_t)(x)) << I2S_RDR_RDR_SHIFT)) & I2S_RDR_RDR_MASK) +/*! @} */ + +/* The count of I2S_RDR */ +#define I2S_RDR_COUNT (2U) + +/*! @name RFR - SAI Receive FIFO Register */ +/*! @{ */ +#define I2S_RFR_RFP_MASK (0xFU) +#define I2S_RFR_RFP_SHIFT (0U) +#define I2S_RFR_RFP(x) (((uint32_t)(((uint32_t)(x)) << I2S_RFR_RFP_SHIFT)) & I2S_RFR_RFP_MASK) +#define I2S_RFR_WFP_MASK (0xF0000U) +#define I2S_RFR_WFP_SHIFT (16U) +#define I2S_RFR_WFP(x) (((uint32_t)(((uint32_t)(x)) << I2S_RFR_WFP_SHIFT)) & I2S_RFR_WFP_MASK) +/*! @} */ + +/* The count of I2S_RFR */ +#define I2S_RFR_COUNT (2U) + +/*! @name RMR - SAI Receive Mask Register */ +/*! @{ */ +#define I2S_RMR_RWM_MASK (0xFFFFFFFFU) +#define I2S_RMR_RWM_SHIFT (0U) +/*! RWM - Receive Word Mask + * 0b00000000000000000000000000000000..Word N is enabled. + * 0b00000000000000000000000000000001..Word N is masked. + */ +#define I2S_RMR_RWM(x) (((uint32_t)(((uint32_t)(x)) << I2S_RMR_RWM_SHIFT)) & I2S_RMR_RWM_MASK) +/*! @} */ + +/*! @name MCR - SAI MCLK Control Register */ +/*! @{ */ +#define I2S_MCR_MICS_MASK (0x3000000U) +#define I2S_MCR_MICS_SHIFT (24U) +/*! MICS - MCLK Input Clock Select + * 0b00..MCLK divider input clock 0 selected. + * 0b01..MCLK divider input clock 1 selected. + * 0b10..MCLK divider input clock 2 selected. + * 0b11..MCLK divider input clock 3 selected. + */ +#define I2S_MCR_MICS(x) (((uint32_t)(((uint32_t)(x)) << I2S_MCR_MICS_SHIFT)) & I2S_MCR_MICS_MASK) +#define I2S_MCR_MOE_MASK (0x40000000U) +#define I2S_MCR_MOE_SHIFT (30U) +/*! MOE - MCLK Output Enable + * 0b0..MCLK signal pin is configured as an input that bypasses the MCLK divider. + * 0b1..MCLK signal pin is configured as an output from the MCLK divider and the MCLK divider is enabled. + */ +#define I2S_MCR_MOE(x) (((uint32_t)(((uint32_t)(x)) << I2S_MCR_MOE_SHIFT)) & I2S_MCR_MOE_MASK) +#define I2S_MCR_DUF_MASK (0x80000000U) +#define I2S_MCR_DUF_SHIFT (31U) +/*! DUF - Divider Update Flag + * 0b0..MCLK divider ratio is not being updated currently. + * 0b1..MCLK divider ratio is updating on-the-fly. Further updates to the MCLK divider ratio are blocked while this flag remains set. + */ +#define I2S_MCR_DUF(x) (((uint32_t)(((uint32_t)(x)) << I2S_MCR_DUF_SHIFT)) & I2S_MCR_DUF_MASK) +/*! @} */ + +/*! @name MDR - SAI MCLK Divide Register */ +/*! @{ */ +#define I2S_MDR_DIVIDE_MASK (0xFFFU) +#define I2S_MDR_DIVIDE_SHIFT (0U) +#define I2S_MDR_DIVIDE(x) (((uint32_t)(((uint32_t)(x)) << I2S_MDR_DIVIDE_SHIFT)) & I2S_MDR_DIVIDE_MASK) +#define I2S_MDR_FRACT_MASK (0xFF000U) +#define I2S_MDR_FRACT_SHIFT (12U) +#define I2S_MDR_FRACT(x) (((uint32_t)(((uint32_t)(x)) << I2S_MDR_FRACT_SHIFT)) & I2S_MDR_FRACT_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group I2S_Register_Masks */ + + +/* I2S - Peripheral instance base addresses */ +/** Peripheral I2S0 base address */ +#define I2S0_BASE (0x4002F000u) +/** Peripheral I2S0 base pointer */ +#define I2S0 ((I2S_Type *)I2S0_BASE) +/** Array initializer of I2S peripheral base addresses */ +#define I2S_BASE_ADDRS { I2S0_BASE } +/** Array initializer of I2S peripheral base pointers */ +#define I2S_BASE_PTRS { I2S0 } +/** Interrupt vectors for the I2S peripheral type */ +#define I2S_RX_IRQS { I2S0_Rx_IRQn } +#define I2S_TX_IRQS { I2S0_Tx_IRQn } + +/*! + * @} + */ /* end of group I2S_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- LLWU Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LLWU_Peripheral_Access_Layer LLWU Peripheral Access Layer + * @{ + */ + +/** LLWU - Register Layout Typedef */ +typedef struct { + __IO uint8_t PE1; /**< LLWU Pin Enable 1 register, offset: 0x0 */ + __IO uint8_t PE2; /**< LLWU Pin Enable 2 register, offset: 0x1 */ + __IO uint8_t PE3; /**< LLWU Pin Enable 3 register, offset: 0x2 */ + __IO uint8_t PE4; /**< LLWU Pin Enable 4 register, offset: 0x3 */ + __IO uint8_t ME; /**< LLWU Module Enable register, offset: 0x4 */ + __IO uint8_t F1; /**< LLWU Flag 1 register, offset: 0x5 */ + __IO uint8_t F2; /**< LLWU Flag 2 register, offset: 0x6 */ + __I uint8_t F3; /**< LLWU Flag 3 register, offset: 0x7 */ + __IO uint8_t FILT1; /**< LLWU Pin Filter 1 register, offset: 0x8 */ + __IO uint8_t FILT2; /**< LLWU Pin Filter 2 register, offset: 0x9 */ + __IO uint8_t RST; /**< LLWU Reset Enable register, offset: 0xA */ +} LLWU_Type; + +/* ---------------------------------------------------------------------------- + -- LLWU Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LLWU_Register_Masks LLWU Register Masks + * @{ + */ + +/*! @name PE1 - LLWU Pin Enable 1 register */ +/*! @{ */ +#define LLWU_PE1_WUPE0_MASK (0x3U) +#define LLWU_PE1_WUPE0_SHIFT (0U) +/*! WUPE0 - Wakeup Pin Enable For LLWU_P0 + * 0b00..External input pin disabled as wakeup input + * 0b01..External input pin enabled with rising edge detection + * 0b10..External input pin enabled with falling edge detection + * 0b11..External input pin enabled with any change detection + */ +#define LLWU_PE1_WUPE0(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE1_WUPE0_SHIFT)) & LLWU_PE1_WUPE0_MASK) +#define LLWU_PE1_WUPE1_MASK (0xCU) +#define LLWU_PE1_WUPE1_SHIFT (2U) +/*! WUPE1 - Wakeup Pin Enable For LLWU_P1 + * 0b00..External input pin disabled as wakeup input + * 0b01..External input pin enabled with rising edge detection + * 0b10..External input pin enabled with falling edge detection + * 0b11..External input pin enabled with any change detection + */ +#define LLWU_PE1_WUPE1(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE1_WUPE1_SHIFT)) & LLWU_PE1_WUPE1_MASK) +#define LLWU_PE1_WUPE2_MASK (0x30U) +#define LLWU_PE1_WUPE2_SHIFT (4U) +/*! WUPE2 - Wakeup Pin Enable For LLWU_P2 + * 0b00..External input pin disabled as wakeup input + * 0b01..External input pin enabled with rising edge detection + * 0b10..External input pin enabled with falling edge detection + * 0b11..External input pin enabled with any change detection + */ +#define LLWU_PE1_WUPE2(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE1_WUPE2_SHIFT)) & LLWU_PE1_WUPE2_MASK) +#define LLWU_PE1_WUPE3_MASK (0xC0U) +#define LLWU_PE1_WUPE3_SHIFT (6U) +/*! WUPE3 - Wakeup Pin Enable For LLWU_P3 + * 0b00..External input pin disabled as wakeup input + * 0b01..External input pin enabled with rising edge detection + * 0b10..External input pin enabled with falling edge detection + * 0b11..External input pin enabled with any change detection + */ +#define LLWU_PE1_WUPE3(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE1_WUPE3_SHIFT)) & LLWU_PE1_WUPE3_MASK) +/*! @} */ + +/*! @name PE2 - LLWU Pin Enable 2 register */ +/*! @{ */ +#define LLWU_PE2_WUPE4_MASK (0x3U) +#define LLWU_PE2_WUPE4_SHIFT (0U) +/*! WUPE4 - Wakeup Pin Enable For LLWU_P4 + * 0b00..External input pin disabled as wakeup input + * 0b01..External input pin enabled with rising edge detection + * 0b10..External input pin enabled with falling edge detection + * 0b11..External input pin enabled with any change detection + */ +#define LLWU_PE2_WUPE4(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE2_WUPE4_SHIFT)) & LLWU_PE2_WUPE4_MASK) +#define LLWU_PE2_WUPE5_MASK (0xCU) +#define LLWU_PE2_WUPE5_SHIFT (2U) +/*! WUPE5 - Wakeup Pin Enable For LLWU_P5 + * 0b00..External input pin disabled as wakeup input + * 0b01..External input pin enabled with rising edge detection + * 0b10..External input pin enabled with falling edge detection + * 0b11..External input pin enabled with any change detection + */ +#define LLWU_PE2_WUPE5(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE2_WUPE5_SHIFT)) & LLWU_PE2_WUPE5_MASK) +#define LLWU_PE2_WUPE6_MASK (0x30U) +#define LLWU_PE2_WUPE6_SHIFT (4U) +/*! WUPE6 - Wakeup Pin Enable For LLWU_P6 + * 0b00..External input pin disabled as wakeup input + * 0b01..External input pin enabled with rising edge detection + * 0b10..External input pin enabled with falling edge detection + * 0b11..External input pin enabled with any change detection + */ +#define LLWU_PE2_WUPE6(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE2_WUPE6_SHIFT)) & LLWU_PE2_WUPE6_MASK) +#define LLWU_PE2_WUPE7_MASK (0xC0U) +#define LLWU_PE2_WUPE7_SHIFT (6U) +/*! WUPE7 - Wakeup Pin Enable For LLWU_P7 + * 0b00..External input pin disabled as wakeup input + * 0b01..External input pin enabled with rising edge detection + * 0b10..External input pin enabled with falling edge detection + * 0b11..External input pin enabled with any change detection + */ +#define LLWU_PE2_WUPE7(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE2_WUPE7_SHIFT)) & LLWU_PE2_WUPE7_MASK) +/*! @} */ + +/*! @name PE3 - LLWU Pin Enable 3 register */ +/*! @{ */ +#define LLWU_PE3_WUPE8_MASK (0x3U) +#define LLWU_PE3_WUPE8_SHIFT (0U) +/*! WUPE8 - Wakeup Pin Enable For LLWU_P8 + * 0b00..External input pin disabled as wakeup input + * 0b01..External input pin enabled with rising edge detection + * 0b10..External input pin enabled with falling edge detection + * 0b11..External input pin enabled with any change detection + */ +#define LLWU_PE3_WUPE8(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE3_WUPE8_SHIFT)) & LLWU_PE3_WUPE8_MASK) +#define LLWU_PE3_WUPE9_MASK (0xCU) +#define LLWU_PE3_WUPE9_SHIFT (2U) +/*! WUPE9 - Wakeup Pin Enable For LLWU_P9 + * 0b00..External input pin disabled as wakeup input + * 0b01..External input pin enabled with rising edge detection + * 0b10..External input pin enabled with falling edge detection + * 0b11..External input pin enabled with any change detection + */ +#define LLWU_PE3_WUPE9(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE3_WUPE9_SHIFT)) & LLWU_PE3_WUPE9_MASK) +#define LLWU_PE3_WUPE10_MASK (0x30U) +#define LLWU_PE3_WUPE10_SHIFT (4U) +/*! WUPE10 - Wakeup Pin Enable For LLWU_P10 + * 0b00..External input pin disabled as wakeup input + * 0b01..External input pin enabled with rising edge detection + * 0b10..External input pin enabled with falling edge detection + * 0b11..External input pin enabled with any change detection + */ +#define LLWU_PE3_WUPE10(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE3_WUPE10_SHIFT)) & LLWU_PE3_WUPE10_MASK) +#define LLWU_PE3_WUPE11_MASK (0xC0U) +#define LLWU_PE3_WUPE11_SHIFT (6U) +/*! WUPE11 - Wakeup Pin Enable For LLWU_P11 + * 0b00..External input pin disabled as wakeup input + * 0b01..External input pin enabled with rising edge detection + * 0b10..External input pin enabled with falling edge detection + * 0b11..External input pin enabled with any change detection + */ +#define LLWU_PE3_WUPE11(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE3_WUPE11_SHIFT)) & LLWU_PE3_WUPE11_MASK) +/*! @} */ + +/*! @name PE4 - LLWU Pin Enable 4 register */ +/*! @{ */ +#define LLWU_PE4_WUPE12_MASK (0x3U) +#define LLWU_PE4_WUPE12_SHIFT (0U) +/*! WUPE12 - Wakeup Pin Enable For LLWU_P12 + * 0b00..External input pin disabled as wakeup input + * 0b01..External input pin enabled with rising edge detection + * 0b10..External input pin enabled with falling edge detection + * 0b11..External input pin enabled with any change detection + */ +#define LLWU_PE4_WUPE12(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE4_WUPE12_SHIFT)) & LLWU_PE4_WUPE12_MASK) +#define LLWU_PE4_WUPE13_MASK (0xCU) +#define LLWU_PE4_WUPE13_SHIFT (2U) +/*! WUPE13 - Wakeup Pin Enable For LLWU_P13 + * 0b00..External input pin disabled as wakeup input + * 0b01..External input pin enabled with rising edge detection + * 0b10..External input pin enabled with falling edge detection + * 0b11..External input pin enabled with any change detection + */ +#define LLWU_PE4_WUPE13(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE4_WUPE13_SHIFT)) & LLWU_PE4_WUPE13_MASK) +#define LLWU_PE4_WUPE14_MASK (0x30U) +#define LLWU_PE4_WUPE14_SHIFT (4U) +/*! WUPE14 - Wakeup Pin Enable For LLWU_P14 + * 0b00..External input pin disabled as wakeup input + * 0b01..External input pin enabled with rising edge detection + * 0b10..External input pin enabled with falling edge detection + * 0b11..External input pin enabled with any change detection + */ +#define LLWU_PE4_WUPE14(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE4_WUPE14_SHIFT)) & LLWU_PE4_WUPE14_MASK) +#define LLWU_PE4_WUPE15_MASK (0xC0U) +#define LLWU_PE4_WUPE15_SHIFT (6U) +/*! WUPE15 - Wakeup Pin Enable For LLWU_P15 + * 0b00..External input pin disabled as wakeup input + * 0b01..External input pin enabled with rising edge detection + * 0b10..External input pin enabled with falling edge detection + * 0b11..External input pin enabled with any change detection + */ +#define LLWU_PE4_WUPE15(x) (((uint8_t)(((uint8_t)(x)) << LLWU_PE4_WUPE15_SHIFT)) & LLWU_PE4_WUPE15_MASK) +/*! @} */ + +/*! @name ME - LLWU Module Enable register */ +/*! @{ */ +#define LLWU_ME_WUME0_MASK (0x1U) +#define LLWU_ME_WUME0_SHIFT (0U) +/*! WUME0 - Wakeup Module Enable For Module 0 + * 0b0..Internal module flag not used as wakeup source + * 0b1..Internal module flag used as wakeup source + */ +#define LLWU_ME_WUME0(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME0_SHIFT)) & LLWU_ME_WUME0_MASK) +#define LLWU_ME_WUME1_MASK (0x2U) +#define LLWU_ME_WUME1_SHIFT (1U) +/*! WUME1 - Wakeup Module Enable for Module 1 + * 0b0..Internal module flag not used as wakeup source + * 0b1..Internal module flag used as wakeup source + */ +#define LLWU_ME_WUME1(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME1_SHIFT)) & LLWU_ME_WUME1_MASK) +#define LLWU_ME_WUME2_MASK (0x4U) +#define LLWU_ME_WUME2_SHIFT (2U) +/*! WUME2 - Wakeup Module Enable For Module 2 + * 0b0..Internal module flag not used as wakeup source + * 0b1..Internal module flag used as wakeup source + */ +#define LLWU_ME_WUME2(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME2_SHIFT)) & LLWU_ME_WUME2_MASK) +#define LLWU_ME_WUME3_MASK (0x8U) +#define LLWU_ME_WUME3_SHIFT (3U) +/*! WUME3 - Wakeup Module Enable For Module 3 + * 0b0..Internal module flag not used as wakeup source + * 0b1..Internal module flag used as wakeup source + */ +#define LLWU_ME_WUME3(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME3_SHIFT)) & LLWU_ME_WUME3_MASK) +#define LLWU_ME_WUME4_MASK (0x10U) +#define LLWU_ME_WUME4_SHIFT (4U) +/*! WUME4 - Wakeup Module Enable For Module 4 + * 0b0..Internal module flag not used as wakeup source + * 0b1..Internal module flag used as wakeup source + */ +#define LLWU_ME_WUME4(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME4_SHIFT)) & LLWU_ME_WUME4_MASK) +#define LLWU_ME_WUME5_MASK (0x20U) +#define LLWU_ME_WUME5_SHIFT (5U) +/*! WUME5 - Wakeup Module Enable For Module 5 + * 0b0..Internal module flag not used as wakeup source + * 0b1..Internal module flag used as wakeup source + */ +#define LLWU_ME_WUME5(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME5_SHIFT)) & LLWU_ME_WUME5_MASK) +#define LLWU_ME_WUME6_MASK (0x40U) +#define LLWU_ME_WUME6_SHIFT (6U) +/*! WUME6 - Wakeup Module Enable For Module 6 + * 0b0..Internal module flag not used as wakeup source + * 0b1..Internal module flag used as wakeup source + */ +#define LLWU_ME_WUME6(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME6_SHIFT)) & LLWU_ME_WUME6_MASK) +#define LLWU_ME_WUME7_MASK (0x80U) +#define LLWU_ME_WUME7_SHIFT (7U) +/*! WUME7 - Wakeup Module Enable For Module 7 + * 0b0..Internal module flag not used as wakeup source + * 0b1..Internal module flag used as wakeup source + */ +#define LLWU_ME_WUME7(x) (((uint8_t)(((uint8_t)(x)) << LLWU_ME_WUME7_SHIFT)) & LLWU_ME_WUME7_MASK) +/*! @} */ + +/*! @name F1 - LLWU Flag 1 register */ +/*! @{ */ +#define LLWU_F1_WUF0_MASK (0x1U) +#define LLWU_F1_WUF0_SHIFT (0U) +/*! WUF0 - Wakeup Flag For LLWU_P0 + * 0b0..LLWU_P0 input was not a wakeup source + * 0b1..LLWU_P0 input was a wakeup source + */ +#define LLWU_F1_WUF0(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F1_WUF0_SHIFT)) & LLWU_F1_WUF0_MASK) +#define LLWU_F1_WUF1_MASK (0x2U) +#define LLWU_F1_WUF1_SHIFT (1U) +/*! WUF1 - Wakeup Flag For LLWU_P1 + * 0b0..LLWU_P1 input was not a wakeup source + * 0b1..LLWU_P1 input was a wakeup source + */ +#define LLWU_F1_WUF1(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F1_WUF1_SHIFT)) & LLWU_F1_WUF1_MASK) +#define LLWU_F1_WUF2_MASK (0x4U) +#define LLWU_F1_WUF2_SHIFT (2U) +/*! WUF2 - Wakeup Flag For LLWU_P2 + * 0b0..LLWU_P2 input was not a wakeup source + * 0b1..LLWU_P2 input was a wakeup source + */ +#define LLWU_F1_WUF2(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F1_WUF2_SHIFT)) & LLWU_F1_WUF2_MASK) +#define LLWU_F1_WUF3_MASK (0x8U) +#define LLWU_F1_WUF3_SHIFT (3U) +/*! WUF3 - Wakeup Flag For LLWU_P3 + * 0b0..LLWU_P3 input was not a wake-up source + * 0b1..LLWU_P3 input was a wake-up source + */ +#define LLWU_F1_WUF3(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F1_WUF3_SHIFT)) & LLWU_F1_WUF3_MASK) +#define LLWU_F1_WUF4_MASK (0x10U) +#define LLWU_F1_WUF4_SHIFT (4U) +/*! WUF4 - Wakeup Flag For LLWU_P4 + * 0b0..LLWU_P4 input was not a wakeup source + * 0b1..LLWU_P4 input was a wakeup source + */ +#define LLWU_F1_WUF4(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F1_WUF4_SHIFT)) & LLWU_F1_WUF4_MASK) +#define LLWU_F1_WUF5_MASK (0x20U) +#define LLWU_F1_WUF5_SHIFT (5U) +/*! WUF5 - Wakeup Flag For LLWU_P5 + * 0b0..LLWU_P5 input was not a wakeup source + * 0b1..LLWU_P5 input was a wakeup source + */ +#define LLWU_F1_WUF5(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F1_WUF5_SHIFT)) & LLWU_F1_WUF5_MASK) +#define LLWU_F1_WUF6_MASK (0x40U) +#define LLWU_F1_WUF6_SHIFT (6U) +/*! WUF6 - Wakeup Flag For LLWU_P6 + * 0b0..LLWU_P6 input was not a wakeup source + * 0b1..LLWU_P6 input was a wakeup source + */ +#define LLWU_F1_WUF6(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F1_WUF6_SHIFT)) & LLWU_F1_WUF6_MASK) +#define LLWU_F1_WUF7_MASK (0x80U) +#define LLWU_F1_WUF7_SHIFT (7U) +/*! WUF7 - Wakeup Flag For LLWU_P7 + * 0b0..LLWU_P7 input was not a wakeup source + * 0b1..LLWU_P7 input was a wakeup source + */ +#define LLWU_F1_WUF7(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F1_WUF7_SHIFT)) & LLWU_F1_WUF7_MASK) +/*! @} */ + +/*! @name F2 - LLWU Flag 2 register */ +/*! @{ */ +#define LLWU_F2_WUF8_MASK (0x1U) +#define LLWU_F2_WUF8_SHIFT (0U) +/*! WUF8 - Wakeup Flag For LLWU_P8 + * 0b0..LLWU_P8 input was not a wakeup source + * 0b1..LLWU_P8 input was a wakeup source + */ +#define LLWU_F2_WUF8(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F2_WUF8_SHIFT)) & LLWU_F2_WUF8_MASK) +#define LLWU_F2_WUF9_MASK (0x2U) +#define LLWU_F2_WUF9_SHIFT (1U) +/*! WUF9 - Wakeup Flag For LLWU_P9 + * 0b0..LLWU_P9 input was not a wakeup source + * 0b1..LLWU_P9 input was a wakeup source + */ +#define LLWU_F2_WUF9(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F2_WUF9_SHIFT)) & LLWU_F2_WUF9_MASK) +#define LLWU_F2_WUF10_MASK (0x4U) +#define LLWU_F2_WUF10_SHIFT (2U) +/*! WUF10 - Wakeup Flag For LLWU_P10 + * 0b0..LLWU_P10 input was not a wakeup source + * 0b1..LLWU_P10 input was a wakeup source + */ +#define LLWU_F2_WUF10(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F2_WUF10_SHIFT)) & LLWU_F2_WUF10_MASK) +#define LLWU_F2_WUF11_MASK (0x8U) +#define LLWU_F2_WUF11_SHIFT (3U) +/*! WUF11 - Wakeup Flag For LLWU_P11 + * 0b0..LLWU_P11 input was not a wakeup source + * 0b1..LLWU_P11 input was a wakeup source + */ +#define LLWU_F2_WUF11(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F2_WUF11_SHIFT)) & LLWU_F2_WUF11_MASK) +#define LLWU_F2_WUF12_MASK (0x10U) +#define LLWU_F2_WUF12_SHIFT (4U) +/*! WUF12 - Wakeup Flag For LLWU_P12 + * 0b0..LLWU_P12 input was not a wakeup source + * 0b1..LLWU_P12 input was a wakeup source + */ +#define LLWU_F2_WUF12(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F2_WUF12_SHIFT)) & LLWU_F2_WUF12_MASK) +#define LLWU_F2_WUF13_MASK (0x20U) +#define LLWU_F2_WUF13_SHIFT (5U) +/*! WUF13 - Wakeup Flag For LLWU_P13 + * 0b0..LLWU_P13 input was not a wakeup source + * 0b1..LLWU_P13 input was a wakeup source + */ +#define LLWU_F2_WUF13(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F2_WUF13_SHIFT)) & LLWU_F2_WUF13_MASK) +#define LLWU_F2_WUF14_MASK (0x40U) +#define LLWU_F2_WUF14_SHIFT (6U) +/*! WUF14 - Wakeup Flag For LLWU_P14 + * 0b0..LLWU_P14 input was not a wakeup source + * 0b1..LLWU_P14 input was a wakeup source + */ +#define LLWU_F2_WUF14(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F2_WUF14_SHIFT)) & LLWU_F2_WUF14_MASK) +#define LLWU_F2_WUF15_MASK (0x80U) +#define LLWU_F2_WUF15_SHIFT (7U) +/*! WUF15 - Wakeup Flag For LLWU_P15 + * 0b0..LLWU_P15 input was not a wakeup source + * 0b1..LLWU_P15 input was a wakeup source + */ +#define LLWU_F2_WUF15(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F2_WUF15_SHIFT)) & LLWU_F2_WUF15_MASK) +/*! @} */ + +/*! @name F3 - LLWU Flag 3 register */ +/*! @{ */ +#define LLWU_F3_MWUF0_MASK (0x1U) +#define LLWU_F3_MWUF0_SHIFT (0U) +/*! MWUF0 - Wakeup flag For module 0 + * 0b0..Module 0 input was not a wakeup source + * 0b1..Module 0 input was a wakeup source + */ +#define LLWU_F3_MWUF0(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F3_MWUF0_SHIFT)) & LLWU_F3_MWUF0_MASK) +#define LLWU_F3_MWUF1_MASK (0x2U) +#define LLWU_F3_MWUF1_SHIFT (1U) +/*! MWUF1 - Wakeup flag For module 1 + * 0b0..Module 1 input was not a wakeup source + * 0b1..Module 1 input was a wakeup source + */ +#define LLWU_F3_MWUF1(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F3_MWUF1_SHIFT)) & LLWU_F3_MWUF1_MASK) +#define LLWU_F3_MWUF2_MASK (0x4U) +#define LLWU_F3_MWUF2_SHIFT (2U) +/*! MWUF2 - Wakeup flag For module 2 + * 0b0..Module 2 input was not a wakeup source + * 0b1..Module 2 input was a wakeup source + */ +#define LLWU_F3_MWUF2(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F3_MWUF2_SHIFT)) & LLWU_F3_MWUF2_MASK) +#define LLWU_F3_MWUF3_MASK (0x8U) +#define LLWU_F3_MWUF3_SHIFT (3U) +/*! MWUF3 - Wakeup flag For module 3 + * 0b0..Module 3 input was not a wakeup source + * 0b1..Module 3 input was a wakeup source + */ +#define LLWU_F3_MWUF3(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F3_MWUF3_SHIFT)) & LLWU_F3_MWUF3_MASK) +#define LLWU_F3_MWUF4_MASK (0x10U) +#define LLWU_F3_MWUF4_SHIFT (4U) +/*! MWUF4 - Wakeup flag For module 4 + * 0b0..Module 4 input was not a wakeup source + * 0b1..Module 4 input was a wakeup source + */ +#define LLWU_F3_MWUF4(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F3_MWUF4_SHIFT)) & LLWU_F3_MWUF4_MASK) +#define LLWU_F3_MWUF5_MASK (0x20U) +#define LLWU_F3_MWUF5_SHIFT (5U) +/*! MWUF5 - Wakeup flag For module 5 + * 0b0..Module 5 input was not a wakeup source + * 0b1..Module 5 input was a wakeup source + */ +#define LLWU_F3_MWUF5(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F3_MWUF5_SHIFT)) & LLWU_F3_MWUF5_MASK) +#define LLWU_F3_MWUF6_MASK (0x40U) +#define LLWU_F3_MWUF6_SHIFT (6U) +/*! MWUF6 - Wakeup flag For module 6 + * 0b0..Module 6 input was not a wakeup source + * 0b1..Module 6 input was a wakeup source + */ +#define LLWU_F3_MWUF6(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F3_MWUF6_SHIFT)) & LLWU_F3_MWUF6_MASK) +#define LLWU_F3_MWUF7_MASK (0x80U) +#define LLWU_F3_MWUF7_SHIFT (7U) +/*! MWUF7 - Wakeup flag For module 7 + * 0b0..Module 7 input was not a wakeup source + * 0b1..Module 7 input was a wakeup source + */ +#define LLWU_F3_MWUF7(x) (((uint8_t)(((uint8_t)(x)) << LLWU_F3_MWUF7_SHIFT)) & LLWU_F3_MWUF7_MASK) +/*! @} */ + +/*! @name FILT1 - LLWU Pin Filter 1 register */ +/*! @{ */ +#define LLWU_FILT1_FILTSEL_MASK (0xFU) +#define LLWU_FILT1_FILTSEL_SHIFT (0U) +/*! FILTSEL - Filter Pin Select + * 0b0000..Select LLWU_P0 for filter + * 0b1111..Select LLWU_P15 for filter + */ +#define LLWU_FILT1_FILTSEL(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT1_FILTSEL_SHIFT)) & LLWU_FILT1_FILTSEL_MASK) +#define LLWU_FILT1_FILTE_MASK (0x60U) +#define LLWU_FILT1_FILTE_SHIFT (5U) +/*! FILTE - Digital Filter On External Pin + * 0b00..Filter disabled + * 0b01..Filter posedge detect enabled + * 0b10..Filter negedge detect enabled + * 0b11..Filter any edge detect enabled + */ +#define LLWU_FILT1_FILTE(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT1_FILTE_SHIFT)) & LLWU_FILT1_FILTE_MASK) +#define LLWU_FILT1_FILTF_MASK (0x80U) +#define LLWU_FILT1_FILTF_SHIFT (7U) +/*! FILTF - Filter Detect Flag + * 0b0..Pin Filter 1 was not a wakeup source + * 0b1..Pin Filter 1 was a wakeup source + */ +#define LLWU_FILT1_FILTF(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT1_FILTF_SHIFT)) & LLWU_FILT1_FILTF_MASK) +/*! @} */ + +/*! @name FILT2 - LLWU Pin Filter 2 register */ +/*! @{ */ +#define LLWU_FILT2_FILTSEL_MASK (0xFU) +#define LLWU_FILT2_FILTSEL_SHIFT (0U) +/*! FILTSEL - Filter Pin Select + * 0b0000..Select LLWU_P0 for filter + * 0b1111..Select LLWU_P15 for filter + */ +#define LLWU_FILT2_FILTSEL(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT2_FILTSEL_SHIFT)) & LLWU_FILT2_FILTSEL_MASK) +#define LLWU_FILT2_FILTE_MASK (0x60U) +#define LLWU_FILT2_FILTE_SHIFT (5U) +/*! FILTE - Digital Filter On External Pin + * 0b00..Filter disabled + * 0b01..Filter posedge detect enabled + * 0b10..Filter negedge detect enabled + * 0b11..Filter any edge detect enabled + */ +#define LLWU_FILT2_FILTE(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT2_FILTE_SHIFT)) & LLWU_FILT2_FILTE_MASK) +#define LLWU_FILT2_FILTF_MASK (0x80U) +#define LLWU_FILT2_FILTF_SHIFT (7U) +/*! FILTF - Filter Detect Flag + * 0b0..Pin Filter 2 was not a wakeup source + * 0b1..Pin Filter 2 was a wakeup source + */ +#define LLWU_FILT2_FILTF(x) (((uint8_t)(((uint8_t)(x)) << LLWU_FILT2_FILTF_SHIFT)) & LLWU_FILT2_FILTF_MASK) +/*! @} */ + +/*! @name RST - LLWU Reset Enable register */ +/*! @{ */ +#define LLWU_RST_RSTFILT_MASK (0x1U) +#define LLWU_RST_RSTFILT_SHIFT (0U) +/*! RSTFILT - Digital Filter On RESET Pin + * 0b0..Filter not enabled + * 0b1..Filter enabled + */ +#define LLWU_RST_RSTFILT(x) (((uint8_t)(((uint8_t)(x)) << LLWU_RST_RSTFILT_SHIFT)) & LLWU_RST_RSTFILT_MASK) +#define LLWU_RST_LLRSTE_MASK (0x2U) +#define LLWU_RST_LLRSTE_SHIFT (1U) +/*! LLRSTE - Low-Leakage Mode RESET Enable + * 0b0..RESET pin not enabled as a leakage mode exit source + * 0b1..RESET pin enabled as a low leakage mode exit source + */ +#define LLWU_RST_LLRSTE(x) (((uint8_t)(((uint8_t)(x)) << LLWU_RST_LLRSTE_SHIFT)) & LLWU_RST_LLRSTE_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group LLWU_Register_Masks */ + + +/* LLWU - Peripheral instance base addresses */ +/** Peripheral LLWU base address */ +#define LLWU_BASE (0x4007C000u) +/** Peripheral LLWU base pointer */ +#define LLWU ((LLWU_Type *)LLWU_BASE) +/** Array initializer of LLWU peripheral base addresses */ +#define LLWU_BASE_ADDRS { LLWU_BASE } +/** Array initializer of LLWU peripheral base pointers */ +#define LLWU_BASE_PTRS { LLWU } +/** Interrupt vectors for the LLWU peripheral type */ +#define LLWU_IRQS { LLWU_IRQn } + +/*! + * @} + */ /* end of group LLWU_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- LPTMR Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LPTMR_Peripheral_Access_Layer LPTMR Peripheral Access Layer + * @{ + */ + +/** LPTMR - Register Layout Typedef */ +typedef struct { + __IO uint32_t CSR; /**< Low Power Timer Control Status Register, offset: 0x0 */ + __IO uint32_t PSR; /**< Low Power Timer Prescale Register, offset: 0x4 */ + __IO uint32_t CMR; /**< Low Power Timer Compare Register, offset: 0x8 */ + __IO uint32_t CNR; /**< Low Power Timer Counter Register, offset: 0xC */ +} LPTMR_Type; + +/* ---------------------------------------------------------------------------- + -- LPTMR Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup LPTMR_Register_Masks LPTMR Register Masks + * @{ + */ + +/*! @name CSR - Low Power Timer Control Status Register */ +/*! @{ */ +#define LPTMR_CSR_TEN_MASK (0x1U) +#define LPTMR_CSR_TEN_SHIFT (0U) +/*! TEN - Timer Enable + * 0b0..LPTMR is disabled and internal logic is reset. + * 0b1..LPTMR is enabled. + */ +#define LPTMR_CSR_TEN(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TEN_SHIFT)) & LPTMR_CSR_TEN_MASK) +#define LPTMR_CSR_TMS_MASK (0x2U) +#define LPTMR_CSR_TMS_SHIFT (1U) +/*! TMS - Timer Mode Select + * 0b0..Time Counter mode. + * 0b1..Pulse Counter mode. + */ +#define LPTMR_CSR_TMS(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TMS_SHIFT)) & LPTMR_CSR_TMS_MASK) +#define LPTMR_CSR_TFC_MASK (0x4U) +#define LPTMR_CSR_TFC_SHIFT (2U) +/*! TFC - Timer Free-Running Counter + * 0b0..CNR is reset whenever TCF is set. + * 0b1..CNR is reset on overflow. + */ +#define LPTMR_CSR_TFC(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TFC_SHIFT)) & LPTMR_CSR_TFC_MASK) +#define LPTMR_CSR_TPP_MASK (0x8U) +#define LPTMR_CSR_TPP_SHIFT (3U) +/*! TPP - Timer Pin Polarity + * 0b0..Pulse Counter input source is active-high, and the CNR will increment on the rising-edge. + * 0b1..Pulse Counter input source is active-low, and the CNR will increment on the falling-edge. + */ +#define LPTMR_CSR_TPP(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TPP_SHIFT)) & LPTMR_CSR_TPP_MASK) +#define LPTMR_CSR_TPS_MASK (0x30U) +#define LPTMR_CSR_TPS_SHIFT (4U) +/*! TPS - Timer Pin Select + * 0b00..Pulse counter input 0 is selected. + * 0b01..Pulse counter input 1 is selected. + * 0b10..Pulse counter input 2 is selected. + * 0b11..Pulse counter input 3 is selected. + */ +#define LPTMR_CSR_TPS(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TPS_SHIFT)) & LPTMR_CSR_TPS_MASK) +#define LPTMR_CSR_TIE_MASK (0x40U) +#define LPTMR_CSR_TIE_SHIFT (6U) +/*! TIE - Timer Interrupt Enable + * 0b0..Timer interrupt disabled. + * 0b1..Timer interrupt enabled. + */ +#define LPTMR_CSR_TIE(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TIE_SHIFT)) & LPTMR_CSR_TIE_MASK) +#define LPTMR_CSR_TCF_MASK (0x80U) +#define LPTMR_CSR_TCF_SHIFT (7U) +/*! TCF - Timer Compare Flag + * 0b0..The value of CNR is not equal to CMR and increments. + * 0b1..The value of CNR is equal to CMR and increments. + */ +#define LPTMR_CSR_TCF(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CSR_TCF_SHIFT)) & LPTMR_CSR_TCF_MASK) +/*! @} */ + +/*! @name PSR - Low Power Timer Prescale Register */ +/*! @{ */ +#define LPTMR_PSR_PCS_MASK (0x3U) +#define LPTMR_PSR_PCS_SHIFT (0U) +/*! PCS - Prescaler Clock Select + * 0b00..Prescaler/glitch filter clock 0 selected. + * 0b01..Prescaler/glitch filter clock 1 selected. + * 0b10..Prescaler/glitch filter clock 2 selected. + * 0b11..Prescaler/glitch filter clock 3 selected. + */ +#define LPTMR_PSR_PCS(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_PSR_PCS_SHIFT)) & LPTMR_PSR_PCS_MASK) +#define LPTMR_PSR_PBYP_MASK (0x4U) +#define LPTMR_PSR_PBYP_SHIFT (2U) +/*! PBYP - Prescaler Bypass + * 0b0..Prescaler/glitch filter is enabled. + * 0b1..Prescaler/glitch filter is bypassed. + */ +#define LPTMR_PSR_PBYP(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_PSR_PBYP_SHIFT)) & LPTMR_PSR_PBYP_MASK) +#define LPTMR_PSR_PRESCALE_MASK (0x78U) +#define LPTMR_PSR_PRESCALE_SHIFT (3U) +/*! PRESCALE - Prescale Value + * 0b0000..Prescaler divides the prescaler clock by 2; glitch filter does not support this configuration. + * 0b0001..Prescaler divides the prescaler clock by 4; glitch filter recognizes change on input pin after 2 rising clock edges. + * 0b0010..Prescaler divides the prescaler clock by 8; glitch filter recognizes change on input pin after 4 rising clock edges. + * 0b0011..Prescaler divides the prescaler clock by 16; glitch filter recognizes change on input pin after 8 rising clock edges. + * 0b0100..Prescaler divides the prescaler clock by 32; glitch filter recognizes change on input pin after 16 rising clock edges. + * 0b0101..Prescaler divides the prescaler clock by 64; glitch filter recognizes change on input pin after 32 rising clock edges. + * 0b0110..Prescaler divides the prescaler clock by 128; glitch filter recognizes change on input pin after 64 rising clock edges. + * 0b0111..Prescaler divides the prescaler clock by 256; glitch filter recognizes change on input pin after 128 rising clock edges. + * 0b1000..Prescaler divides the prescaler clock by 512; glitch filter recognizes change on input pin after 256 rising clock edges. + * 0b1001..Prescaler divides the prescaler clock by 1024; glitch filter recognizes change on input pin after 512 rising clock edges. + * 0b1010..Prescaler divides the prescaler clock by 2048; glitch filter recognizes change on input pin after 1024 rising clock edges. + * 0b1011..Prescaler divides the prescaler clock by 4096; glitch filter recognizes change on input pin after 2048 rising clock edges. + * 0b1100..Prescaler divides the prescaler clock by 8192; glitch filter recognizes change on input pin after 4096 rising clock edges. + * 0b1101..Prescaler divides the prescaler clock by 16,384; glitch filter recognizes change on input pin after 8192 rising clock edges. + * 0b1110..Prescaler divides the prescaler clock by 32,768; glitch filter recognizes change on input pin after 16,384 rising clock edges. + * 0b1111..Prescaler divides the prescaler clock by 65,536; glitch filter recognizes change on input pin after 32,768 rising clock edges. + */ +#define LPTMR_PSR_PRESCALE(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_PSR_PRESCALE_SHIFT)) & LPTMR_PSR_PRESCALE_MASK) +/*! @} */ + +/*! @name CMR - Low Power Timer Compare Register */ +/*! @{ */ +#define LPTMR_CMR_COMPARE_MASK (0xFFFFU) +#define LPTMR_CMR_COMPARE_SHIFT (0U) +#define LPTMR_CMR_COMPARE(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CMR_COMPARE_SHIFT)) & LPTMR_CMR_COMPARE_MASK) +/*! @} */ + +/*! @name CNR - Low Power Timer Counter Register */ +/*! @{ */ +#define LPTMR_CNR_COUNTER_MASK (0xFFFFU) +#define LPTMR_CNR_COUNTER_SHIFT (0U) +#define LPTMR_CNR_COUNTER(x) (((uint32_t)(((uint32_t)(x)) << LPTMR_CNR_COUNTER_SHIFT)) & LPTMR_CNR_COUNTER_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group LPTMR_Register_Masks */ + + +/* LPTMR - Peripheral instance base addresses */ +/** Peripheral LPTMR0 base address */ +#define LPTMR0_BASE (0x40040000u) +/** Peripheral LPTMR0 base pointer */ +#define LPTMR0 ((LPTMR_Type *)LPTMR0_BASE) +/** Array initializer of LPTMR peripheral base addresses */ +#define LPTMR_BASE_ADDRS { LPTMR0_BASE } +/** Array initializer of LPTMR peripheral base pointers */ +#define LPTMR_BASE_PTRS { LPTMR0 } +/** Interrupt vectors for the LPTMR peripheral type */ +#define LPTMR_IRQS { LPTMR0_IRQn } + +/*! + * @} + */ /* end of group LPTMR_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- MCG Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MCG_Peripheral_Access_Layer MCG Peripheral Access Layer + * @{ + */ + +/** MCG - Register Layout Typedef */ +typedef struct { + __IO uint8_t C1; /**< MCG Control 1 Register, offset: 0x0 */ + __IO uint8_t C2; /**< MCG Control 2 Register, offset: 0x1 */ + __IO uint8_t C3; /**< MCG Control 3 Register, offset: 0x2 */ + __IO uint8_t C4; /**< MCG Control 4 Register, offset: 0x3 */ + __IO uint8_t C5; /**< MCG Control 5 Register, offset: 0x4 */ + __IO uint8_t C6; /**< MCG Control 6 Register, offset: 0x5 */ + __IO uint8_t S; /**< MCG Status Register, offset: 0x6 */ + uint8_t RESERVED_0[1]; + __IO uint8_t SC; /**< MCG Status and Control Register, offset: 0x8 */ + uint8_t RESERVED_1[1]; + __IO uint8_t ATCVH; /**< MCG Auto Trim Compare Value High Register, offset: 0xA */ + __IO uint8_t ATCVL; /**< MCG Auto Trim Compare Value Low Register, offset: 0xB */ + __IO uint8_t C7; /**< MCG Control 7 Register, offset: 0xC */ + __IO uint8_t C8; /**< MCG Control 8 Register, offset: 0xD */ +} MCG_Type; + +/* ---------------------------------------------------------------------------- + -- MCG Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MCG_Register_Masks MCG Register Masks + * @{ + */ + +/*! @name C1 - MCG Control 1 Register */ +/*! @{ */ +#define MCG_C1_IREFSTEN_MASK (0x1U) +#define MCG_C1_IREFSTEN_SHIFT (0U) +/*! IREFSTEN - Internal Reference Stop Enable + * 0b0..Internal reference clock is disabled in Stop mode. + * 0b1..Internal reference clock is enabled in Stop mode if IRCLKEN is set or if MCG is in FEI, FBI, or BLPI modes before entering Stop mode. + */ +#define MCG_C1_IREFSTEN(x) (((uint8_t)(((uint8_t)(x)) << MCG_C1_IREFSTEN_SHIFT)) & MCG_C1_IREFSTEN_MASK) +#define MCG_C1_IRCLKEN_MASK (0x2U) +#define MCG_C1_IRCLKEN_SHIFT (1U) +/*! IRCLKEN - Internal Reference Clock Enable + * 0b0..MCGIRCLK inactive. + * 0b1..MCGIRCLK active. + */ +#define MCG_C1_IRCLKEN(x) (((uint8_t)(((uint8_t)(x)) << MCG_C1_IRCLKEN_SHIFT)) & MCG_C1_IRCLKEN_MASK) +#define MCG_C1_IREFS_MASK (0x4U) +#define MCG_C1_IREFS_SHIFT (2U) +/*! IREFS - Internal Reference Select + * 0b0..External reference clock is selected. + * 0b1..The slow internal reference clock is selected. + */ +#define MCG_C1_IREFS(x) (((uint8_t)(((uint8_t)(x)) << MCG_C1_IREFS_SHIFT)) & MCG_C1_IREFS_MASK) +#define MCG_C1_FRDIV_MASK (0x38U) +#define MCG_C1_FRDIV_SHIFT (3U) +/*! FRDIV - FLL External Reference Divider + * 0b000..If RANGE = 0 or OSCSEL=1 , Divide Factor is 1; for all other RANGE values, Divide Factor is 32. + * 0b001..If RANGE = 0 or OSCSEL=1 , Divide Factor is 2; for all other RANGE values, Divide Factor is 64. + * 0b010..If RANGE = 0 or OSCSEL=1 , Divide Factor is 4; for all other RANGE values, Divide Factor is 128. + * 0b011..If RANGE = 0 or OSCSEL=1 , Divide Factor is 8; for all other RANGE values, Divide Factor is 256. + * 0b100..If RANGE = 0 or OSCSEL=1 , Divide Factor is 16; for all other RANGE values, Divide Factor is 512. + * 0b101..If RANGE = 0 or OSCSEL=1 , Divide Factor is 32; for all other RANGE values, Divide Factor is 1024. + * 0b110..If RANGE = 0 or OSCSEL=1 , Divide Factor is 64; for all other RANGE values, Divide Factor is 1280 . + * 0b111..If RANGE = 0 or OSCSEL=1 , Divide Factor is 128; for all other RANGE values, Divide Factor is 1536 . + */ +#define MCG_C1_FRDIV(x) (((uint8_t)(((uint8_t)(x)) << MCG_C1_FRDIV_SHIFT)) & MCG_C1_FRDIV_MASK) +#define MCG_C1_CLKS_MASK (0xC0U) +#define MCG_C1_CLKS_SHIFT (6U) +/*! CLKS - Clock Source Select + * 0b00..Encoding 0 - Output of FLL or PLL is selected (depends on PLLS control bit). + * 0b01..Encoding 1 - Internal reference clock is selected. + * 0b10..Encoding 2 - External reference clock is selected. + * 0b11..Encoding 3 - Reserved. + */ +#define MCG_C1_CLKS(x) (((uint8_t)(((uint8_t)(x)) << MCG_C1_CLKS_SHIFT)) & MCG_C1_CLKS_MASK) +/*! @} */ + +/*! @name C2 - MCG Control 2 Register */ +/*! @{ */ +#define MCG_C2_IRCS_MASK (0x1U) +#define MCG_C2_IRCS_SHIFT (0U) +/*! IRCS - Internal Reference Clock Select + * 0b0..Slow internal reference clock selected. + * 0b1..Fast internal reference clock selected. + */ +#define MCG_C2_IRCS(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_IRCS_SHIFT)) & MCG_C2_IRCS_MASK) +#define MCG_C2_LP_MASK (0x2U) +#define MCG_C2_LP_SHIFT (1U) +/*! LP - Low Power Select + * 0b0..FLL or PLL is not disabled in bypass modes. + * 0b1..FLL or PLL is disabled in bypass modes (lower power) + */ +#define MCG_C2_LP(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_LP_SHIFT)) & MCG_C2_LP_MASK) +#define MCG_C2_EREFS_MASK (0x4U) +#define MCG_C2_EREFS_SHIFT (2U) +/*! EREFS - External Reference Select + * 0b0..External reference clock requested. + * 0b1..Oscillator requested. + */ +#define MCG_C2_EREFS(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_EREFS_SHIFT)) & MCG_C2_EREFS_MASK) +#define MCG_C2_HGO_MASK (0x8U) +#define MCG_C2_HGO_SHIFT (3U) +/*! HGO - High Gain Oscillator Select + * 0b0..Configure crystal oscillator for low-power operation. + * 0b1..Configure crystal oscillator for high-gain operation. + */ +#define MCG_C2_HGO(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_HGO_SHIFT)) & MCG_C2_HGO_MASK) +#define MCG_C2_RANGE_MASK (0x30U) +#define MCG_C2_RANGE_SHIFT (4U) +/*! RANGE - Frequency Range Select + * 0b00..Encoding 0 - Low frequency range selected for the crystal oscillator . + * 0b01..Encoding 1 - High frequency range selected for the crystal oscillator . + * 0b1x..Encoding 2 - Very high frequency range selected for the crystal oscillator . + */ +#define MCG_C2_RANGE(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_RANGE_SHIFT)) & MCG_C2_RANGE_MASK) +#define MCG_C2_FCFTRIM_MASK (0x40U) +#define MCG_C2_FCFTRIM_SHIFT (6U) +#define MCG_C2_FCFTRIM(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_FCFTRIM_SHIFT)) & MCG_C2_FCFTRIM_MASK) +#define MCG_C2_LOCRE0_MASK (0x80U) +#define MCG_C2_LOCRE0_SHIFT (7U) +/*! LOCRE0 - Loss of Clock Reset Enable + * 0b0..Interrupt request is generated on a loss of OSC0 external reference clock. + * 0b1..Generate a reset request on a loss of OSC0 external reference clock. + */ +#define MCG_C2_LOCRE0(x) (((uint8_t)(((uint8_t)(x)) << MCG_C2_LOCRE0_SHIFT)) & MCG_C2_LOCRE0_MASK) +/*! @} */ + +/*! @name C3 - MCG Control 3 Register */ +/*! @{ */ +#define MCG_C3_SCTRIM_MASK (0xFFU) +#define MCG_C3_SCTRIM_SHIFT (0U) +#define MCG_C3_SCTRIM(x) (((uint8_t)(((uint8_t)(x)) << MCG_C3_SCTRIM_SHIFT)) & MCG_C3_SCTRIM_MASK) +/*! @} */ + +/*! @name C4 - MCG Control 4 Register */ +/*! @{ */ +#define MCG_C4_SCFTRIM_MASK (0x1U) +#define MCG_C4_SCFTRIM_SHIFT (0U) +#define MCG_C4_SCFTRIM(x) (((uint8_t)(((uint8_t)(x)) << MCG_C4_SCFTRIM_SHIFT)) & MCG_C4_SCFTRIM_MASK) +#define MCG_C4_FCTRIM_MASK (0x1EU) +#define MCG_C4_FCTRIM_SHIFT (1U) +#define MCG_C4_FCTRIM(x) (((uint8_t)(((uint8_t)(x)) << MCG_C4_FCTRIM_SHIFT)) & MCG_C4_FCTRIM_MASK) +#define MCG_C4_DRST_DRS_MASK (0x60U) +#define MCG_C4_DRST_DRS_SHIFT (5U) +/*! DRST_DRS - DCO Range Select + * 0b00..Encoding 0 - Low range (reset default). + * 0b01..Encoding 1 - Mid range. + * 0b10..Encoding 2 - Mid-high range. + * 0b11..Encoding 3 - High range. + */ +#define MCG_C4_DRST_DRS(x) (((uint8_t)(((uint8_t)(x)) << MCG_C4_DRST_DRS_SHIFT)) & MCG_C4_DRST_DRS_MASK) +#define MCG_C4_DMX32_MASK (0x80U) +#define MCG_C4_DMX32_SHIFT (7U) +/*! DMX32 - DCO Maximum Frequency with 32.768 kHz Reference + * 0b0..DCO has a default range of 25%. + * 0b1..DCO is fine-tuned for maximum frequency with 32.768 kHz reference. + */ +#define MCG_C4_DMX32(x) (((uint8_t)(((uint8_t)(x)) << MCG_C4_DMX32_SHIFT)) & MCG_C4_DMX32_MASK) +/*! @} */ + +/*! @name C5 - MCG Control 5 Register */ +/*! @{ */ +#define MCG_C5_PRDIV0_MASK (0x1FU) +#define MCG_C5_PRDIV0_SHIFT (0U) +/*! PRDIV0 - PLL External Reference Divider + * 0b00000..Divide Factor is 1 + * 0b00001..Divide Factor is 2 + * 0b00010..Divide Factor is 3 + * 0b00011..Divide Factor is 4 + * 0b00100..Divide Factor is 5 + * 0b00101..Divide Factor is 6 + * 0b00110..Divide Factor is 7 + * 0b00111..Divide Factor is 8 + * 0b01000..Divide Factor is 9 + * 0b01001..Divide Factor is 10 + * 0b01010..Divide Factor is 11 + * 0b01011..Divide Factor is 12 + * 0b01100..Divide Factor is 13 + * 0b01101..Divide Factor is 14 + * 0b01110..Divide Factor is 15 + * 0b01111..Divide Factor is 16 + * 0b10000..Divide Factor is 17 + * 0b10001..Divide Factor is 18 + * 0b10010..Divide Factor is 19 + * 0b10011..Divide Factor is 20 + * 0b10100..Divide Factor is 21 + * 0b10101..Divide Factor is 22 + * 0b10110..Divide Factor is 23 + * 0b10111..Divide Factor is 24 + * 0b11000..Divide Factor is 25 + * 0b11001..Divide Factor is 26 + * 0b11010..Divide Factor is 27 + * 0b11011..Divide Factor is 28 + * 0b11100..Divide Factor is 29 + * 0b11101..Divide Factor is 30 + * 0b11110..Divide Factor is 31 + * 0b11111..Divide Factor is 32 + */ +#define MCG_C5_PRDIV0(x) (((uint8_t)(((uint8_t)(x)) << MCG_C5_PRDIV0_SHIFT)) & MCG_C5_PRDIV0_MASK) +#define MCG_C5_PLLSTEN0_MASK (0x20U) +#define MCG_C5_PLLSTEN0_SHIFT (5U) +/*! PLLSTEN0 - PLL Stop Enable + * 0b0..MCGPLLCLK is disabled in any of the Stop modes. + * 0b1..MCGPLLCLK is enabled if system is in Normal Stop mode. + */ +#define MCG_C5_PLLSTEN0(x) (((uint8_t)(((uint8_t)(x)) << MCG_C5_PLLSTEN0_SHIFT)) & MCG_C5_PLLSTEN0_MASK) +#define MCG_C5_PLLCLKEN0_MASK (0x40U) +#define MCG_C5_PLLCLKEN0_SHIFT (6U) +/*! PLLCLKEN0 - PLL Clock Enable + * 0b0..MCGPLLCLK is inactive. + * 0b1..MCGPLLCLK is active. + */ +#define MCG_C5_PLLCLKEN0(x) (((uint8_t)(((uint8_t)(x)) << MCG_C5_PLLCLKEN0_SHIFT)) & MCG_C5_PLLCLKEN0_MASK) +/*! @} */ + +/*! @name C6 - MCG Control 6 Register */ +/*! @{ */ +#define MCG_C6_VDIV0_MASK (0x1FU) +#define MCG_C6_VDIV0_SHIFT (0U) +/*! VDIV0 - VCO 0 Divider + * 0b00000..Multiply Factor is 24 + * 0b00001..Multiply Factor is 25 + * 0b00010..Multiply Factor is 26 + * 0b00011..Multiply Factor is 27 + * 0b00100..Multiply Factor is 28 + * 0b00101..Multiply Factor is 29 + * 0b00110..Multiply Factor is 30 + * 0b00111..Multiply Factor is 31 + * 0b01000..Multiply Factor is 32 + * 0b01001..Multiply Factor is 33 + * 0b01010..Multiply Factor is 34 + * 0b01011..Multiply Factor is 35 + * 0b01100..Multiply Factor is 36 + * 0b01101..Multiply Factor is 37 + * 0b01110..Multiply Factor is 38 + * 0b01111..Multiply Factor is 39 + * 0b10000..Multiply Factor is 40 + * 0b10001..Multiply Factor is 41 + * 0b10010..Multiply Factor is 42 + * 0b10011..Multiply Factor is 43 + * 0b10100..Multiply Factor is 44 + * 0b10101..Multiply Factor is 45 + * 0b10110..Multiply Factor is 46 + * 0b10111..Multiply Factor is 47 + * 0b11000..Multiply Factor is 48 + * 0b11001..Multiply Factor is 49 + * 0b11010..Multiply Factor is 50 + * 0b11011..Multiply Factor is 51 + * 0b11100..Multiply Factor is 52 + * 0b11101..Multiply Factor is 53 + * 0b11110..Multiply Factor is 54 + * 0b11111..Multiply Factor is 55 + */ +#define MCG_C6_VDIV0(x) (((uint8_t)(((uint8_t)(x)) << MCG_C6_VDIV0_SHIFT)) & MCG_C6_VDIV0_MASK) +#define MCG_C6_CME0_MASK (0x20U) +#define MCG_C6_CME0_SHIFT (5U) +/*! CME0 - Clock Monitor Enable + * 0b0..External clock monitor is disabled for OSC0. + * 0b1..External clock monitor is enabled for OSC0. + */ +#define MCG_C6_CME0(x) (((uint8_t)(((uint8_t)(x)) << MCG_C6_CME0_SHIFT)) & MCG_C6_CME0_MASK) +#define MCG_C6_PLLS_MASK (0x40U) +#define MCG_C6_PLLS_SHIFT (6U) +/*! PLLS - PLL Select + * 0b0..FLL is selected. + * 0b1..PLL is selected (PRDIV 0 need to be programmed to the correct divider to generate a PLL reference clock in the range of 2-4 MHz prior to setting the PLLS bit). + */ +#define MCG_C6_PLLS(x) (((uint8_t)(((uint8_t)(x)) << MCG_C6_PLLS_SHIFT)) & MCG_C6_PLLS_MASK) +#define MCG_C6_LOLIE0_MASK (0x80U) +#define MCG_C6_LOLIE0_SHIFT (7U) +/*! LOLIE0 - Loss of Lock Interrrupt Enable + * 0b0..No interrupt request is generated on loss of lock. + * 0b1..Generate an interrupt request on loss of lock. + */ +#define MCG_C6_LOLIE0(x) (((uint8_t)(((uint8_t)(x)) << MCG_C6_LOLIE0_SHIFT)) & MCG_C6_LOLIE0_MASK) +/*! @} */ + +/*! @name S - MCG Status Register */ +/*! @{ */ +#define MCG_S_IRCST_MASK (0x1U) +#define MCG_S_IRCST_SHIFT (0U) +/*! IRCST - Internal Reference Clock Status + * 0b0..Source of internal reference clock is the slow clock (32 kHz IRC). + * 0b1..Source of internal reference clock is the fast clock (4 MHz IRC). + */ +#define MCG_S_IRCST(x) (((uint8_t)(((uint8_t)(x)) << MCG_S_IRCST_SHIFT)) & MCG_S_IRCST_MASK) +#define MCG_S_OSCINIT0_MASK (0x2U) +#define MCG_S_OSCINIT0_SHIFT (1U) +#define MCG_S_OSCINIT0(x) (((uint8_t)(((uint8_t)(x)) << MCG_S_OSCINIT0_SHIFT)) & MCG_S_OSCINIT0_MASK) +#define MCG_S_CLKST_MASK (0xCU) +#define MCG_S_CLKST_SHIFT (2U) +/*! CLKST - Clock Mode Status + * 0b00..Encoding 0 - Output of the FLL is selected (reset default). + * 0b01..Encoding 1 - Internal reference clock is selected. + * 0b10..Encoding 2 - External reference clock is selected. + * 0b11..Encoding 3 - Output of the PLL is selected. + */ +#define MCG_S_CLKST(x) (((uint8_t)(((uint8_t)(x)) << MCG_S_CLKST_SHIFT)) & MCG_S_CLKST_MASK) +#define MCG_S_IREFST_MASK (0x10U) +#define MCG_S_IREFST_SHIFT (4U) +/*! IREFST - Internal Reference Status + * 0b0..Source of FLL reference clock is the external reference clock. + * 0b1..Source of FLL reference clock is the internal reference clock. + */ +#define MCG_S_IREFST(x) (((uint8_t)(((uint8_t)(x)) << MCG_S_IREFST_SHIFT)) & MCG_S_IREFST_MASK) +#define MCG_S_PLLST_MASK (0x20U) +#define MCG_S_PLLST_SHIFT (5U) +/*! PLLST - PLL Select Status + * 0b0..Source of PLLS clock is FLL clock. + * 0b1..Source of PLLS clock is PLL output clock. + */ +#define MCG_S_PLLST(x) (((uint8_t)(((uint8_t)(x)) << MCG_S_PLLST_SHIFT)) & MCG_S_PLLST_MASK) +#define MCG_S_LOCK0_MASK (0x40U) +#define MCG_S_LOCK0_SHIFT (6U) +/*! LOCK0 - Lock Status + * 0b0..PLL is currently unlocked. + * 0b1..PLL is currently locked. + */ +#define MCG_S_LOCK0(x) (((uint8_t)(((uint8_t)(x)) << MCG_S_LOCK0_SHIFT)) & MCG_S_LOCK0_MASK) +#define MCG_S_LOLS0_MASK (0x80U) +#define MCG_S_LOLS0_SHIFT (7U) +/*! LOLS0 - Loss of Lock Status + * 0b0..PLL has not lost lock since LOLS 0 was last cleared. + * 0b1..PLL has lost lock since LOLS 0 was last cleared. + */ +#define MCG_S_LOLS0(x) (((uint8_t)(((uint8_t)(x)) << MCG_S_LOLS0_SHIFT)) & MCG_S_LOLS0_MASK) +/*! @} */ + +/*! @name SC - MCG Status and Control Register */ +/*! @{ */ +#define MCG_SC_LOCS0_MASK (0x1U) +#define MCG_SC_LOCS0_SHIFT (0U) +/*! LOCS0 - OSC0 Loss of Clock Status + * 0b0..Loss of OSC0 has not occurred. + * 0b1..Loss of OSC0 has occurred. + */ +#define MCG_SC_LOCS0(x) (((uint8_t)(((uint8_t)(x)) << MCG_SC_LOCS0_SHIFT)) & MCG_SC_LOCS0_MASK) +#define MCG_SC_FCRDIV_MASK (0xEU) +#define MCG_SC_FCRDIV_SHIFT (1U) +/*! FCRDIV - Fast Clock Internal Reference Divider + * 0b000..Divide Factor is 1 + * 0b001..Divide Factor is 2. + * 0b010..Divide Factor is 4. + * 0b011..Divide Factor is 8. + * 0b100..Divide Factor is 16 + * 0b101..Divide Factor is 32 + * 0b110..Divide Factor is 64 + * 0b111..Divide Factor is 128. + */ +#define MCG_SC_FCRDIV(x) (((uint8_t)(((uint8_t)(x)) << MCG_SC_FCRDIV_SHIFT)) & MCG_SC_FCRDIV_MASK) +#define MCG_SC_FLTPRSRV_MASK (0x10U) +#define MCG_SC_FLTPRSRV_SHIFT (4U) +/*! FLTPRSRV - FLL Filter Preserve Enable + * 0b0..FLL filter and FLL frequency will reset on changes to currect clock mode. + * 0b1..Fll filter and FLL frequency retain their previous values during new clock mode change. + */ +#define MCG_SC_FLTPRSRV(x) (((uint8_t)(((uint8_t)(x)) << MCG_SC_FLTPRSRV_SHIFT)) & MCG_SC_FLTPRSRV_MASK) +#define MCG_SC_ATMF_MASK (0x20U) +#define MCG_SC_ATMF_SHIFT (5U) +/*! ATMF - Automatic Trim Machine Fail Flag + * 0b0..Automatic Trim Machine completed normally. + * 0b1..Automatic Trim Machine failed. + */ +#define MCG_SC_ATMF(x) (((uint8_t)(((uint8_t)(x)) << MCG_SC_ATMF_SHIFT)) & MCG_SC_ATMF_MASK) +#define MCG_SC_ATMS_MASK (0x40U) +#define MCG_SC_ATMS_SHIFT (6U) +/*! ATMS - Automatic Trim Machine Select + * 0b0..32 kHz Internal Reference Clock selected. + * 0b1..4 MHz Internal Reference Clock selected. + */ +#define MCG_SC_ATMS(x) (((uint8_t)(((uint8_t)(x)) << MCG_SC_ATMS_SHIFT)) & MCG_SC_ATMS_MASK) +#define MCG_SC_ATME_MASK (0x80U) +#define MCG_SC_ATME_SHIFT (7U) +/*! ATME - Automatic Trim Machine Enable + * 0b0..Auto Trim Machine disabled. + * 0b1..Auto Trim Machine enabled. + */ +#define MCG_SC_ATME(x) (((uint8_t)(((uint8_t)(x)) << MCG_SC_ATME_SHIFT)) & MCG_SC_ATME_MASK) +/*! @} */ + +/*! @name ATCVH - MCG Auto Trim Compare Value High Register */ +/*! @{ */ +#define MCG_ATCVH_ATCVH_MASK (0xFFU) +#define MCG_ATCVH_ATCVH_SHIFT (0U) +#define MCG_ATCVH_ATCVH(x) (((uint8_t)(((uint8_t)(x)) << MCG_ATCVH_ATCVH_SHIFT)) & MCG_ATCVH_ATCVH_MASK) +/*! @} */ + +/*! @name ATCVL - MCG Auto Trim Compare Value Low Register */ +/*! @{ */ +#define MCG_ATCVL_ATCVL_MASK (0xFFU) +#define MCG_ATCVL_ATCVL_SHIFT (0U) +#define MCG_ATCVL_ATCVL(x) (((uint8_t)(((uint8_t)(x)) << MCG_ATCVL_ATCVL_SHIFT)) & MCG_ATCVL_ATCVL_MASK) +/*! @} */ + +/*! @name C7 - MCG Control 7 Register */ +/*! @{ */ +#define MCG_C7_OSCSEL_MASK (0x3U) +#define MCG_C7_OSCSEL_SHIFT (0U) +/*! OSCSEL - MCG OSC Clock Select + * 0b00..Selects Oscillator (OSCCLK0). + * 0b01..Selects 32 kHz RTC Oscillator. + * 0b10..Selects Oscillator (OSCCLK1). + * 0b11..RESERVED + */ +#define MCG_C7_OSCSEL(x) (((uint8_t)(((uint8_t)(x)) << MCG_C7_OSCSEL_SHIFT)) & MCG_C7_OSCSEL_MASK) +/*! @} */ + +/*! @name C8 - MCG Control 8 Register */ +/*! @{ */ +#define MCG_C8_LOCS1_MASK (0x1U) +#define MCG_C8_LOCS1_SHIFT (0U) +/*! LOCS1 - RTC Loss of Clock Status + * 0b0..Loss of RTC has not occur. + * 0b1..Loss of RTC has occur + */ +#define MCG_C8_LOCS1(x) (((uint8_t)(((uint8_t)(x)) << MCG_C8_LOCS1_SHIFT)) & MCG_C8_LOCS1_MASK) +#define MCG_C8_CME1_MASK (0x20U) +#define MCG_C8_CME1_SHIFT (5U) +/*! CME1 - Clock Monitor Enable1 + * 0b0..External clock monitor is disabled for RTC clock. + * 0b1..External clock monitor is enabled for RTC clock. + */ +#define MCG_C8_CME1(x) (((uint8_t)(((uint8_t)(x)) << MCG_C8_CME1_SHIFT)) & MCG_C8_CME1_MASK) +#define MCG_C8_LOLRE_MASK (0x40U) +#define MCG_C8_LOLRE_SHIFT (6U) +/*! LOLRE - PLL Loss of Lock Reset Enable + * 0b0..Interrupt request is generated on a PLL loss of lock indication. The PLL loss of lock interrupt enable bit must also be set to generate the interrupt request. + * 0b1..Generate a reset request on a PLL loss of lock indication. + */ +#define MCG_C8_LOLRE(x) (((uint8_t)(((uint8_t)(x)) << MCG_C8_LOLRE_SHIFT)) & MCG_C8_LOLRE_MASK) +#define MCG_C8_LOCRE1_MASK (0x80U) +#define MCG_C8_LOCRE1_SHIFT (7U) +/*! LOCRE1 - Loss of Clock Reset Enable + * 0b0..Interrupt request is generated on a loss of RTC external reference clock. + * 0b1..Generate a reset request on a loss of RTC external reference clock + */ +#define MCG_C8_LOCRE1(x) (((uint8_t)(((uint8_t)(x)) << MCG_C8_LOCRE1_SHIFT)) & MCG_C8_LOCRE1_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group MCG_Register_Masks */ + + +/* MCG - Peripheral instance base addresses */ +/** Peripheral MCG base address */ +#define MCG_BASE (0x40064000u) +/** Peripheral MCG base pointer */ +#define MCG ((MCG_Type *)MCG_BASE) +/** Array initializer of MCG peripheral base addresses */ +#define MCG_BASE_ADDRS { MCG_BASE } +/** Array initializer of MCG peripheral base pointers */ +#define MCG_BASE_PTRS { MCG } + +/*! + * @} + */ /* end of group MCG_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- MCM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MCM_Peripheral_Access_Layer MCM Peripheral Access Layer + * @{ + */ + +/** MCM - Register Layout Typedef */ +typedef struct { + uint8_t RESERVED_0[8]; + __I uint16_t PLASC; /**< Crossbar Switch (AXBS) Slave Configuration, offset: 0x8 */ + __I uint16_t PLAMC; /**< Crossbar Switch (AXBS) Master Configuration, offset: 0xA */ + __IO uint32_t CR; /**< Control Register, offset: 0xC */ + __IO uint32_t ISCR; /**< Interrupt Status Register, offset: 0x10 */ + __IO uint32_t ETBCC; /**< ETB Counter Control register, offset: 0x14 */ + __IO uint32_t ETBRL; /**< ETB Reload register, offset: 0x18 */ + __I uint32_t ETBCNT; /**< ETB Counter Value register, offset: 0x1C */ + uint8_t RESERVED_1[16]; + __IO uint32_t PID; /**< Process ID register, offset: 0x30 */ +} MCM_Type; + +/* ---------------------------------------------------------------------------- + -- MCM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MCM_Register_Masks MCM Register Masks + * @{ + */ + +/*! @name PLASC - Crossbar Switch (AXBS) Slave Configuration */ +/*! @{ */ +#define MCM_PLASC_ASC_MASK (0xFFU) +#define MCM_PLASC_ASC_SHIFT (0U) +/*! ASC - Each bit in the ASC field indicates whether there is a corresponding connection to the crossbar switch's slave input port. + * 0b00000000..A bus slave connection to AXBS input port n is absent + * 0b00000001..A bus slave connection to AXBS input port n is present + */ +#define MCM_PLASC_ASC(x) (((uint16_t)(((uint16_t)(x)) << MCM_PLASC_ASC_SHIFT)) & MCM_PLASC_ASC_MASK) +/*! @} */ + +/*! @name PLAMC - Crossbar Switch (AXBS) Master Configuration */ +/*! @{ */ +#define MCM_PLAMC_AMC_MASK (0xFFU) +#define MCM_PLAMC_AMC_SHIFT (0U) +/*! AMC - Each bit in the AMC field indicates whether there is a corresponding connection to the AXBS master input port. + * 0b00000000..A bus master connection to AXBS input port n is absent + * 0b00000001..A bus master connection to AXBS input port n is present + */ +#define MCM_PLAMC_AMC(x) (((uint16_t)(((uint16_t)(x)) << MCM_PLAMC_AMC_SHIFT)) & MCM_PLAMC_AMC_MASK) +/*! @} */ + +/*! @name CR - Control Register */ +/*! @{ */ +#define MCM_CR_SRAMUAP_MASK (0x3000000U) +#define MCM_CR_SRAMUAP_SHIFT (24U) +/*! SRAMUAP - SRAM_U arbitration priority + * 0b00..Round robin + * 0b01..Special round robin (favors SRAM backoor accesses over the processor) + * 0b10..Fixed priority. Processor has highest, backdoor has lowest + * 0b11..Fixed priority. Backdoor has highest, processor has lowest + */ +#define MCM_CR_SRAMUAP(x) (((uint32_t)(((uint32_t)(x)) << MCM_CR_SRAMUAP_SHIFT)) & MCM_CR_SRAMUAP_MASK) +#define MCM_CR_SRAMUWP_MASK (0x4000000U) +#define MCM_CR_SRAMUWP_SHIFT (26U) +#define MCM_CR_SRAMUWP(x) (((uint32_t)(((uint32_t)(x)) << MCM_CR_SRAMUWP_SHIFT)) & MCM_CR_SRAMUWP_MASK) +#define MCM_CR_SRAMLAP_MASK (0x30000000U) +#define MCM_CR_SRAMLAP_SHIFT (28U) +/*! SRAMLAP - SRAM_L arbitration priority + * 0b00..Round robin + * 0b01..Special round robin (favors SRAM backoor accesses over the processor) + * 0b10..Fixed priority. Processor has highest, backdoor has lowest + * 0b11..Fixed priority. Backdoor has highest, processor has lowest + */ +#define MCM_CR_SRAMLAP(x) (((uint32_t)(((uint32_t)(x)) << MCM_CR_SRAMLAP_SHIFT)) & MCM_CR_SRAMLAP_MASK) +#define MCM_CR_SRAMLWP_MASK (0x40000000U) +#define MCM_CR_SRAMLWP_SHIFT (30U) +#define MCM_CR_SRAMLWP(x) (((uint32_t)(((uint32_t)(x)) << MCM_CR_SRAMLWP_SHIFT)) & MCM_CR_SRAMLWP_MASK) +/*! @} */ + +/*! @name ISCR - Interrupt Status Register */ +/*! @{ */ +#define MCM_ISCR_IRQ_MASK (0x2U) +#define MCM_ISCR_IRQ_SHIFT (1U) +/*! IRQ - Normal Interrupt Pending + * 0b0..No pending interrupt + * 0b1..Due to the ETB counter expiring, a normal interrupt is pending + */ +#define MCM_ISCR_IRQ(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_IRQ_SHIFT)) & MCM_ISCR_IRQ_MASK) +#define MCM_ISCR_NMI_MASK (0x4U) +#define MCM_ISCR_NMI_SHIFT (2U) +/*! NMI - Non-maskable Interrupt Pending + * 0b0..No pending NMI + * 0b1..Due to the ETB counter expiring, an NMI is pending + */ +#define MCM_ISCR_NMI(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_NMI_SHIFT)) & MCM_ISCR_NMI_MASK) +#define MCM_ISCR_DHREQ_MASK (0x8U) +#define MCM_ISCR_DHREQ_SHIFT (3U) +/*! DHREQ - Debug Halt Request Indicator + * 0b0..No debug halt request + * 0b1..Debug halt request initiated + */ +#define MCM_ISCR_DHREQ(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_DHREQ_SHIFT)) & MCM_ISCR_DHREQ_MASK) +#define MCM_ISCR_FIOC_MASK (0x100U) +#define MCM_ISCR_FIOC_SHIFT (8U) +/*! FIOC - FPU invalid operation interrupt status + * 0b0..No interrupt + * 0b1..Interrupt occurred + */ +#define MCM_ISCR_FIOC(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FIOC_SHIFT)) & MCM_ISCR_FIOC_MASK) +#define MCM_ISCR_FDZC_MASK (0x200U) +#define MCM_ISCR_FDZC_SHIFT (9U) +/*! FDZC - FPU divide-by-zero interrupt status + * 0b0..No interrupt + * 0b1..Interrupt occurred + */ +#define MCM_ISCR_FDZC(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FDZC_SHIFT)) & MCM_ISCR_FDZC_MASK) +#define MCM_ISCR_FOFC_MASK (0x400U) +#define MCM_ISCR_FOFC_SHIFT (10U) +/*! FOFC - FPU overflow interrupt status + * 0b0..No interrupt + * 0b1..Interrupt occurred + */ +#define MCM_ISCR_FOFC(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FOFC_SHIFT)) & MCM_ISCR_FOFC_MASK) +#define MCM_ISCR_FUFC_MASK (0x800U) +#define MCM_ISCR_FUFC_SHIFT (11U) +/*! FUFC - FPU underflow interrupt status + * 0b0..No interrupt + * 0b1..Interrupt occurred + */ +#define MCM_ISCR_FUFC(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FUFC_SHIFT)) & MCM_ISCR_FUFC_MASK) +#define MCM_ISCR_FIXC_MASK (0x1000U) +#define MCM_ISCR_FIXC_SHIFT (12U) +/*! FIXC - FPU inexact interrupt status + * 0b0..No interrupt + * 0b1..Interrupt occurred + */ +#define MCM_ISCR_FIXC(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FIXC_SHIFT)) & MCM_ISCR_FIXC_MASK) +#define MCM_ISCR_FIDC_MASK (0x8000U) +#define MCM_ISCR_FIDC_SHIFT (15U) +/*! FIDC - FPU input denormal interrupt status + * 0b0..No interrupt + * 0b1..Interrupt occurred + */ +#define MCM_ISCR_FIDC(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FIDC_SHIFT)) & MCM_ISCR_FIDC_MASK) +#define MCM_ISCR_FIOCE_MASK (0x1000000U) +#define MCM_ISCR_FIOCE_SHIFT (24U) +/*! FIOCE - FPU invalid operation interrupt enable + * 0b0..Disable interrupt + * 0b1..Enable interrupt + */ +#define MCM_ISCR_FIOCE(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FIOCE_SHIFT)) & MCM_ISCR_FIOCE_MASK) +#define MCM_ISCR_FDZCE_MASK (0x2000000U) +#define MCM_ISCR_FDZCE_SHIFT (25U) +/*! FDZCE - FPU divide-by-zero interrupt enable + * 0b0..Disable interrupt + * 0b1..Enable interrupt + */ +#define MCM_ISCR_FDZCE(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FDZCE_SHIFT)) & MCM_ISCR_FDZCE_MASK) +#define MCM_ISCR_FOFCE_MASK (0x4000000U) +#define MCM_ISCR_FOFCE_SHIFT (26U) +/*! FOFCE - FPU overflow interrupt enable + * 0b0..Disable interrupt + * 0b1..Enable interrupt + */ +#define MCM_ISCR_FOFCE(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FOFCE_SHIFT)) & MCM_ISCR_FOFCE_MASK) +#define MCM_ISCR_FUFCE_MASK (0x8000000U) +#define MCM_ISCR_FUFCE_SHIFT (27U) +/*! FUFCE - FPU underflow interrupt enable + * 0b0..Disable interrupt + * 0b1..Enable interrupt + */ +#define MCM_ISCR_FUFCE(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FUFCE_SHIFT)) & MCM_ISCR_FUFCE_MASK) +#define MCM_ISCR_FIXCE_MASK (0x10000000U) +#define MCM_ISCR_FIXCE_SHIFT (28U) +/*! FIXCE - FPU inexact interrupt enable + * 0b0..Disable interrupt + * 0b1..Enable interrupt + */ +#define MCM_ISCR_FIXCE(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FIXCE_SHIFT)) & MCM_ISCR_FIXCE_MASK) +#define MCM_ISCR_FIDCE_MASK (0x80000000U) +#define MCM_ISCR_FIDCE_SHIFT (31U) +/*! FIDCE - FPU input denormal interrupt enable + * 0b0..Disable interrupt + * 0b1..Enable interrupt + */ +#define MCM_ISCR_FIDCE(x) (((uint32_t)(((uint32_t)(x)) << MCM_ISCR_FIDCE_SHIFT)) & MCM_ISCR_FIDCE_MASK) +/*! @} */ + +/*! @name ETBCC - ETB Counter Control register */ +/*! @{ */ +#define MCM_ETBCC_CNTEN_MASK (0x1U) +#define MCM_ETBCC_CNTEN_SHIFT (0U) +/*! CNTEN - Counter Enable + * 0b0..ETB counter disabled + * 0b1..ETB counter enabled + */ +#define MCM_ETBCC_CNTEN(x) (((uint32_t)(((uint32_t)(x)) << MCM_ETBCC_CNTEN_SHIFT)) & MCM_ETBCC_CNTEN_MASK) +#define MCM_ETBCC_RSPT_MASK (0x6U) +#define MCM_ETBCC_RSPT_SHIFT (1U) +/*! RSPT - Response Type + * 0b00..No response when the ETB count expires + * 0b01..Generate a normal interrupt when the ETB count expires + * 0b10..Generate an NMI when the ETB count expires + * 0b11..Generate a debug halt when the ETB count expires + */ +#define MCM_ETBCC_RSPT(x) (((uint32_t)(((uint32_t)(x)) << MCM_ETBCC_RSPT_SHIFT)) & MCM_ETBCC_RSPT_MASK) +#define MCM_ETBCC_RLRQ_MASK (0x8U) +#define MCM_ETBCC_RLRQ_SHIFT (3U) +/*! RLRQ - Reload Request + * 0b0..No effect + * 0b1..Clears pending debug halt, NMI, or IRQ interrupt requests + */ +#define MCM_ETBCC_RLRQ(x) (((uint32_t)(((uint32_t)(x)) << MCM_ETBCC_RLRQ_SHIFT)) & MCM_ETBCC_RLRQ_MASK) +#define MCM_ETBCC_ETDIS_MASK (0x10U) +#define MCM_ETBCC_ETDIS_SHIFT (4U) +/*! ETDIS - ETM-To-TPIU Disable + * 0b0..ETM-to-TPIU trace path enabled + * 0b1..ETM-to-TPIU trace path disabled + */ +#define MCM_ETBCC_ETDIS(x) (((uint32_t)(((uint32_t)(x)) << MCM_ETBCC_ETDIS_SHIFT)) & MCM_ETBCC_ETDIS_MASK) +#define MCM_ETBCC_ITDIS_MASK (0x20U) +#define MCM_ETBCC_ITDIS_SHIFT (5U) +/*! ITDIS - ITM-To-TPIU Disable + * 0b0..ITM-to-TPIU trace path enabled + * 0b1..ITM-to-TPIU trace path disabled + */ +#define MCM_ETBCC_ITDIS(x) (((uint32_t)(((uint32_t)(x)) << MCM_ETBCC_ITDIS_SHIFT)) & MCM_ETBCC_ITDIS_MASK) +/*! @} */ + +/*! @name ETBRL - ETB Reload register */ +/*! @{ */ +#define MCM_ETBRL_RELOAD_MASK (0x7FFU) +#define MCM_ETBRL_RELOAD_SHIFT (0U) +#define MCM_ETBRL_RELOAD(x) (((uint32_t)(((uint32_t)(x)) << MCM_ETBRL_RELOAD_SHIFT)) & MCM_ETBRL_RELOAD_MASK) +/*! @} */ + +/*! @name ETBCNT - ETB Counter Value register */ +/*! @{ */ +#define MCM_ETBCNT_COUNTER_MASK (0x7FFU) +#define MCM_ETBCNT_COUNTER_SHIFT (0U) +#define MCM_ETBCNT_COUNTER(x) (((uint32_t)(((uint32_t)(x)) << MCM_ETBCNT_COUNTER_SHIFT)) & MCM_ETBCNT_COUNTER_MASK) +/*! @} */ + +/*! @name PID - Process ID register */ +/*! @{ */ +#define MCM_PID_PID_MASK (0xFFU) +#define MCM_PID_PID_SHIFT (0U) +#define MCM_PID_PID(x) (((uint32_t)(((uint32_t)(x)) << MCM_PID_PID_SHIFT)) & MCM_PID_PID_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group MCM_Register_Masks */ + + +/* MCM - Peripheral instance base addresses */ +/** Peripheral MCM base address */ +#define MCM_BASE (0xE0080000u) +/** Peripheral MCM base pointer */ +#define MCM ((MCM_Type *)MCM_BASE) +/** Array initializer of MCM peripheral base addresses */ +#define MCM_BASE_ADDRS { MCM_BASE } +/** Array initializer of MCM peripheral base pointers */ +#define MCM_BASE_PTRS { MCM } +/** Interrupt vectors for the MCM peripheral type */ +#define MCM_IRQS { MCM_IRQn } + +/*! + * @} + */ /* end of group MCM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- NV Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup NV_Peripheral_Access_Layer NV Peripheral Access Layer + * @{ + */ + +/** NV - Register Layout Typedef */ +typedef struct { + __I uint8_t BACKKEY3; /**< Backdoor Comparison Key 3., offset: 0x0 */ + __I uint8_t BACKKEY2; /**< Backdoor Comparison Key 2., offset: 0x1 */ + __I uint8_t BACKKEY1; /**< Backdoor Comparison Key 1., offset: 0x2 */ + __I uint8_t BACKKEY0; /**< Backdoor Comparison Key 0., offset: 0x3 */ + __I uint8_t BACKKEY7; /**< Backdoor Comparison Key 7., offset: 0x4 */ + __I uint8_t BACKKEY6; /**< Backdoor Comparison Key 6., offset: 0x5 */ + __I uint8_t BACKKEY5; /**< Backdoor Comparison Key 5., offset: 0x6 */ + __I uint8_t BACKKEY4; /**< Backdoor Comparison Key 4., offset: 0x7 */ + __I uint8_t FPROT3; /**< Non-volatile P-Flash Protection 1 - Low Register, offset: 0x8 */ + __I uint8_t FPROT2; /**< Non-volatile P-Flash Protection 1 - High Register, offset: 0x9 */ + __I uint8_t FPROT1; /**< Non-volatile P-Flash Protection 0 - Low Register, offset: 0xA */ + __I uint8_t FPROT0; /**< Non-volatile P-Flash Protection 0 - High Register, offset: 0xB */ + __I uint8_t FSEC; /**< Non-volatile Flash Security Register, offset: 0xC */ + __I uint8_t FOPT; /**< Non-volatile Flash Option Register, offset: 0xD */ + __I uint8_t FEPROT; /**< Non-volatile EERAM Protection Register, offset: 0xE */ + __I uint8_t FDPROT; /**< Non-volatile D-Flash Protection Register, offset: 0xF */ +} NV_Type; + +/* ---------------------------------------------------------------------------- + -- NV Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup NV_Register_Masks NV Register Masks + * @{ + */ + +/*! @name BACKKEY3 - Backdoor Comparison Key 3. */ +/*! @{ */ +#define NV_BACKKEY3_KEY_MASK (0xFFU) +#define NV_BACKKEY3_KEY_SHIFT (0U) +#define NV_BACKKEY3_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY3_KEY_SHIFT)) & NV_BACKKEY3_KEY_MASK) +/*! @} */ + +/*! @name BACKKEY2 - Backdoor Comparison Key 2. */ +/*! @{ */ +#define NV_BACKKEY2_KEY_MASK (0xFFU) +#define NV_BACKKEY2_KEY_SHIFT (0U) +#define NV_BACKKEY2_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY2_KEY_SHIFT)) & NV_BACKKEY2_KEY_MASK) +/*! @} */ + +/*! @name BACKKEY1 - Backdoor Comparison Key 1. */ +/*! @{ */ +#define NV_BACKKEY1_KEY_MASK (0xFFU) +#define NV_BACKKEY1_KEY_SHIFT (0U) +#define NV_BACKKEY1_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY1_KEY_SHIFT)) & NV_BACKKEY1_KEY_MASK) +/*! @} */ + +/*! @name BACKKEY0 - Backdoor Comparison Key 0. */ +/*! @{ */ +#define NV_BACKKEY0_KEY_MASK (0xFFU) +#define NV_BACKKEY0_KEY_SHIFT (0U) +#define NV_BACKKEY0_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY0_KEY_SHIFT)) & NV_BACKKEY0_KEY_MASK) +/*! @} */ + +/*! @name BACKKEY7 - Backdoor Comparison Key 7. */ +/*! @{ */ +#define NV_BACKKEY7_KEY_MASK (0xFFU) +#define NV_BACKKEY7_KEY_SHIFT (0U) +#define NV_BACKKEY7_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY7_KEY_SHIFT)) & NV_BACKKEY7_KEY_MASK) +/*! @} */ + +/*! @name BACKKEY6 - Backdoor Comparison Key 6. */ +/*! @{ */ +#define NV_BACKKEY6_KEY_MASK (0xFFU) +#define NV_BACKKEY6_KEY_SHIFT (0U) +#define NV_BACKKEY6_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY6_KEY_SHIFT)) & NV_BACKKEY6_KEY_MASK) +/*! @} */ + +/*! @name BACKKEY5 - Backdoor Comparison Key 5. */ +/*! @{ */ +#define NV_BACKKEY5_KEY_MASK (0xFFU) +#define NV_BACKKEY5_KEY_SHIFT (0U) +#define NV_BACKKEY5_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY5_KEY_SHIFT)) & NV_BACKKEY5_KEY_MASK) +/*! @} */ + +/*! @name BACKKEY4 - Backdoor Comparison Key 4. */ +/*! @{ */ +#define NV_BACKKEY4_KEY_MASK (0xFFU) +#define NV_BACKKEY4_KEY_SHIFT (0U) +#define NV_BACKKEY4_KEY(x) (((uint8_t)(((uint8_t)(x)) << NV_BACKKEY4_KEY_SHIFT)) & NV_BACKKEY4_KEY_MASK) +/*! @} */ + +/*! @name FPROT3 - Non-volatile P-Flash Protection 1 - Low Register */ +/*! @{ */ +#define NV_FPROT3_PROT_MASK (0xFFU) +#define NV_FPROT3_PROT_SHIFT (0U) +#define NV_FPROT3_PROT(x) (((uint8_t)(((uint8_t)(x)) << NV_FPROT3_PROT_SHIFT)) & NV_FPROT3_PROT_MASK) +/*! @} */ + +/*! @name FPROT2 - Non-volatile P-Flash Protection 1 - High Register */ +/*! @{ */ +#define NV_FPROT2_PROT_MASK (0xFFU) +#define NV_FPROT2_PROT_SHIFT (0U) +#define NV_FPROT2_PROT(x) (((uint8_t)(((uint8_t)(x)) << NV_FPROT2_PROT_SHIFT)) & NV_FPROT2_PROT_MASK) +/*! @} */ + +/*! @name FPROT1 - Non-volatile P-Flash Protection 0 - Low Register */ +/*! @{ */ +#define NV_FPROT1_PROT_MASK (0xFFU) +#define NV_FPROT1_PROT_SHIFT (0U) +#define NV_FPROT1_PROT(x) (((uint8_t)(((uint8_t)(x)) << NV_FPROT1_PROT_SHIFT)) & NV_FPROT1_PROT_MASK) +/*! @} */ + +/*! @name FPROT0 - Non-volatile P-Flash Protection 0 - High Register */ +/*! @{ */ +#define NV_FPROT0_PROT_MASK (0xFFU) +#define NV_FPROT0_PROT_SHIFT (0U) +#define NV_FPROT0_PROT(x) (((uint8_t)(((uint8_t)(x)) << NV_FPROT0_PROT_SHIFT)) & NV_FPROT0_PROT_MASK) +/*! @} */ + +/*! @name FSEC - Non-volatile Flash Security Register */ +/*! @{ */ +#define NV_FSEC_SEC_MASK (0x3U) +#define NV_FSEC_SEC_SHIFT (0U) +/*! SEC - Flash Security + * 0b10..MCU security status is unsecure + * 0b11..MCU security status is secure + */ +#define NV_FSEC_SEC(x) (((uint8_t)(((uint8_t)(x)) << NV_FSEC_SEC_SHIFT)) & NV_FSEC_SEC_MASK) +#define NV_FSEC_FSLACC_MASK (0xCU) +#define NV_FSEC_FSLACC_SHIFT (2U) +/*! FSLACC - Freescale Failure Analysis Access Code + * 0b10..Freescale factory access denied + * 0b11..Freescale factory access granted + */ +#define NV_FSEC_FSLACC(x) (((uint8_t)(((uint8_t)(x)) << NV_FSEC_FSLACC_SHIFT)) & NV_FSEC_FSLACC_MASK) +#define NV_FSEC_MEEN_MASK (0x30U) +#define NV_FSEC_MEEN_SHIFT (4U) +/*! MEEN + * 0b10..Mass erase is disabled + * 0b11..Mass erase is enabled + */ +#define NV_FSEC_MEEN(x) (((uint8_t)(((uint8_t)(x)) << NV_FSEC_MEEN_SHIFT)) & NV_FSEC_MEEN_MASK) +#define NV_FSEC_KEYEN_MASK (0xC0U) +#define NV_FSEC_KEYEN_SHIFT (6U) +/*! KEYEN - Backdoor Key Security Enable + * 0b10..Backdoor key access enabled + * 0b11..Backdoor key access disabled + */ +#define NV_FSEC_KEYEN(x) (((uint8_t)(((uint8_t)(x)) << NV_FSEC_KEYEN_SHIFT)) & NV_FSEC_KEYEN_MASK) +/*! @} */ + +/*! @name FOPT - Non-volatile Flash Option Register */ +/*! @{ */ +#define NV_FOPT_LPBOOT_MASK (0x1U) +#define NV_FOPT_LPBOOT_SHIFT (0U) +/*! LPBOOT + * 0b0..Low-power boot + * 0b1..Normal boot + */ +#define NV_FOPT_LPBOOT(x) (((uint8_t)(((uint8_t)(x)) << NV_FOPT_LPBOOT_SHIFT)) & NV_FOPT_LPBOOT_MASK) +#define NV_FOPT_EZPORT_DIS_MASK (0x2U) +#define NV_FOPT_EZPORT_DIS_SHIFT (1U) +/*! EZPORT_DIS + * 0b0..EzPort operation is disabled + * 0b1..EzPort operation is enabled + */ +#define NV_FOPT_EZPORT_DIS(x) (((uint8_t)(((uint8_t)(x)) << NV_FOPT_EZPORT_DIS_SHIFT)) & NV_FOPT_EZPORT_DIS_MASK) +/*! @} */ + +/*! @name FEPROT - Non-volatile EERAM Protection Register */ +/*! @{ */ +#define NV_FEPROT_EPROT_MASK (0xFFU) +#define NV_FEPROT_EPROT_SHIFT (0U) +#define NV_FEPROT_EPROT(x) (((uint8_t)(((uint8_t)(x)) << NV_FEPROT_EPROT_SHIFT)) & NV_FEPROT_EPROT_MASK) +/*! @} */ + +/*! @name FDPROT - Non-volatile D-Flash Protection Register */ +/*! @{ */ +#define NV_FDPROT_DPROT_MASK (0xFFU) +#define NV_FDPROT_DPROT_SHIFT (0U) +#define NV_FDPROT_DPROT(x) (((uint8_t)(((uint8_t)(x)) << NV_FDPROT_DPROT_SHIFT)) & NV_FDPROT_DPROT_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group NV_Register_Masks */ + + +/* NV - Peripheral instance base addresses */ +/** Peripheral FTFE_FlashConfig base address */ +#define FTFE_FlashConfig_BASE (0x400u) +/** Peripheral FTFE_FlashConfig base pointer */ +#define FTFE_FlashConfig ((NV_Type *)FTFE_FlashConfig_BASE) +/** Array initializer of NV peripheral base addresses */ +#define NV_BASE_ADDRS { FTFE_FlashConfig_BASE } +/** Array initializer of NV peripheral base pointers */ +#define NV_BASE_PTRS { FTFE_FlashConfig } + +/*! + * @} + */ /* end of group NV_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- OSC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup OSC_Peripheral_Access_Layer OSC Peripheral Access Layer + * @{ + */ + +/** OSC - Register Layout Typedef */ +typedef struct { + __IO uint8_t CR; /**< OSC Control Register, offset: 0x0 */ +} OSC_Type; + +/* ---------------------------------------------------------------------------- + -- OSC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup OSC_Register_Masks OSC Register Masks + * @{ + */ + +/*! @name CR - OSC Control Register */ +/*! @{ */ +#define OSC_CR_SC16P_MASK (0x1U) +#define OSC_CR_SC16P_SHIFT (0U) +/*! SC16P - Oscillator 16 pF Capacitor Load Configure + * 0b0..Disable the selection. + * 0b1..Add 16 pF capacitor to the oscillator load. + */ +#define OSC_CR_SC16P(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_SC16P_SHIFT)) & OSC_CR_SC16P_MASK) +#define OSC_CR_SC8P_MASK (0x2U) +#define OSC_CR_SC8P_SHIFT (1U) +/*! SC8P - Oscillator 8 pF Capacitor Load Configure + * 0b0..Disable the selection. + * 0b1..Add 8 pF capacitor to the oscillator load. + */ +#define OSC_CR_SC8P(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_SC8P_SHIFT)) & OSC_CR_SC8P_MASK) +#define OSC_CR_SC4P_MASK (0x4U) +#define OSC_CR_SC4P_SHIFT (2U) +/*! SC4P - Oscillator 4 pF Capacitor Load Configure + * 0b0..Disable the selection. + * 0b1..Add 4 pF capacitor to the oscillator load. + */ +#define OSC_CR_SC4P(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_SC4P_SHIFT)) & OSC_CR_SC4P_MASK) +#define OSC_CR_SC2P_MASK (0x8U) +#define OSC_CR_SC2P_SHIFT (3U) +/*! SC2P - Oscillator 2 pF Capacitor Load Configure + * 0b0..Disable the selection. + * 0b1..Add 2 pF capacitor to the oscillator load. + */ +#define OSC_CR_SC2P(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_SC2P_SHIFT)) & OSC_CR_SC2P_MASK) +#define OSC_CR_EREFSTEN_MASK (0x20U) +#define OSC_CR_EREFSTEN_SHIFT (5U) +/*! EREFSTEN - External Reference Stop Enable + * 0b0..External reference clock is disabled in Stop mode. + * 0b1..External reference clock stays enabled in Stop mode if ERCLKEN is set before entering Stop mode. + */ +#define OSC_CR_EREFSTEN(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_EREFSTEN_SHIFT)) & OSC_CR_EREFSTEN_MASK) +#define OSC_CR_ERCLKEN_MASK (0x80U) +#define OSC_CR_ERCLKEN_SHIFT (7U) +/*! ERCLKEN - External Reference Enable + * 0b0..External reference clock is inactive. + * 0b1..External reference clock is enabled. + */ +#define OSC_CR_ERCLKEN(x) (((uint8_t)(((uint8_t)(x)) << OSC_CR_ERCLKEN_SHIFT)) & OSC_CR_ERCLKEN_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group OSC_Register_Masks */ + + +/* OSC - Peripheral instance base addresses */ +/** Peripheral OSC base address */ +#define OSC_BASE (0x40065000u) +/** Peripheral OSC base pointer */ +#define OSC ((OSC_Type *)OSC_BASE) +/** Array initializer of OSC peripheral base addresses */ +#define OSC_BASE_ADDRS { OSC_BASE } +/** Array initializer of OSC peripheral base pointers */ +#define OSC_BASE_PTRS { OSC } + +/*! + * @} + */ /* end of group OSC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- PDB Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PDB_Peripheral_Access_Layer PDB Peripheral Access Layer + * @{ + */ + +/** PDB - Register Layout Typedef */ +typedef struct { + __IO uint32_t SC; /**< Status and Control register, offset: 0x0 */ + __IO uint32_t MOD; /**< Modulus register, offset: 0x4 */ + __I uint32_t CNT; /**< Counter register, offset: 0x8 */ + __IO uint32_t IDLY; /**< Interrupt Delay register, offset: 0xC */ + struct { /* offset: 0x10, array step: 0x28 */ + __IO uint32_t C1; /**< Channel n Control register 1, array offset: 0x10, array step: 0x28 */ + __IO uint32_t S; /**< Channel n Status register, array offset: 0x14, array step: 0x28 */ + __IO uint32_t DLY[2]; /**< Channel n Delay 0 register..Channel n Delay 1 register, array offset: 0x18, array step: index*0x28, index2*0x4 */ + uint8_t RESERVED_0[24]; + } CH[2]; + uint8_t RESERVED_0[240]; + struct { /* offset: 0x150, array step: 0x8 */ + __IO uint32_t INTC; /**< DAC Interval Trigger n Control register, array offset: 0x150, array step: 0x8 */ + __IO uint32_t INT; /**< DAC Interval n register, array offset: 0x154, array step: 0x8 */ + } DAC[2]; + uint8_t RESERVED_1[48]; + __IO uint32_t POEN; /**< Pulse-Out n Enable register, offset: 0x190 */ + __IO uint32_t PODLY[3]; /**< Pulse-Out n Delay register, array offset: 0x194, array step: 0x4 */ +} PDB_Type; + +/* ---------------------------------------------------------------------------- + -- PDB Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PDB_Register_Masks PDB Register Masks + * @{ + */ + +/*! @name SC - Status and Control register */ +/*! @{ */ +#define PDB_SC_LDOK_MASK (0x1U) +#define PDB_SC_LDOK_SHIFT (0U) +#define PDB_SC_LDOK(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_LDOK_SHIFT)) & PDB_SC_LDOK_MASK) +#define PDB_SC_CONT_MASK (0x2U) +#define PDB_SC_CONT_SHIFT (1U) +/*! CONT - Continuous Mode Enable + * 0b0..PDB operation in One-Shot mode + * 0b1..PDB operation in Continuous mode + */ +#define PDB_SC_CONT(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_CONT_SHIFT)) & PDB_SC_CONT_MASK) +#define PDB_SC_MULT_MASK (0xCU) +#define PDB_SC_MULT_SHIFT (2U) +/*! MULT - Multiplication Factor Select for Prescaler + * 0b00..Multiplication factor is 1. + * 0b01..Multiplication factor is 10. + * 0b10..Multiplication factor is 20. + * 0b11..Multiplication factor is 40. + */ +#define PDB_SC_MULT(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_MULT_SHIFT)) & PDB_SC_MULT_MASK) +#define PDB_SC_PDBIE_MASK (0x20U) +#define PDB_SC_PDBIE_SHIFT (5U) +/*! PDBIE - PDB Interrupt Enable + * 0b0..PDB interrupt disabled. + * 0b1..PDB interrupt enabled. + */ +#define PDB_SC_PDBIE(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_PDBIE_SHIFT)) & PDB_SC_PDBIE_MASK) +#define PDB_SC_PDBIF_MASK (0x40U) +#define PDB_SC_PDBIF_SHIFT (6U) +#define PDB_SC_PDBIF(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_PDBIF_SHIFT)) & PDB_SC_PDBIF_MASK) +#define PDB_SC_PDBEN_MASK (0x80U) +#define PDB_SC_PDBEN_SHIFT (7U) +/*! PDBEN - PDB Enable + * 0b0..PDB disabled. Counter is off. + * 0b1..PDB enabled. + */ +#define PDB_SC_PDBEN(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_PDBEN_SHIFT)) & PDB_SC_PDBEN_MASK) +#define PDB_SC_TRGSEL_MASK (0xF00U) +#define PDB_SC_TRGSEL_SHIFT (8U) +/*! TRGSEL - Trigger Input Source Select + * 0b0000..Trigger-In 0 is selected. + * 0b0001..Trigger-In 1 is selected. + * 0b0010..Trigger-In 2 is selected. + * 0b0011..Trigger-In 3 is selected. + * 0b0100..Trigger-In 4 is selected. + * 0b0101..Trigger-In 5 is selected. + * 0b0110..Trigger-In 6 is selected. + * 0b0111..Trigger-In 7 is selected. + * 0b1000..Trigger-In 8 is selected. + * 0b1001..Trigger-In 9 is selected. + * 0b1010..Trigger-In 10 is selected. + * 0b1011..Trigger-In 11 is selected. + * 0b1100..Trigger-In 12 is selected. + * 0b1101..Trigger-In 13 is selected. + * 0b1110..Trigger-In 14 is selected. + * 0b1111..Software trigger is selected. + */ +#define PDB_SC_TRGSEL(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_TRGSEL_SHIFT)) & PDB_SC_TRGSEL_MASK) +#define PDB_SC_PRESCALER_MASK (0x7000U) +#define PDB_SC_PRESCALER_SHIFT (12U) +/*! PRESCALER - Prescaler Divider Select + * 0b000..Counting uses the peripheral clock divided by multiplication factor selected by MULT. + * 0b001..Counting uses the peripheral clock divided by twice of the multiplication factor selected by MULT. + * 0b010..Counting uses the peripheral clock divided by four times of the multiplication factor selected by MULT. + * 0b011..Counting uses the peripheral clock divided by eight times of the multiplication factor selected by MULT. + * 0b100..Counting uses the peripheral clock divided by 16 times of the multiplication factor selected by MULT. + * 0b101..Counting uses the peripheral clock divided by 32 times of the multiplication factor selected by MULT. + * 0b110..Counting uses the peripheral clock divided by 64 times of the multiplication factor selected by MULT. + * 0b111..Counting uses the peripheral clock divided by 128 times of the multiplication factor selected by MULT. + */ +#define PDB_SC_PRESCALER(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_PRESCALER_SHIFT)) & PDB_SC_PRESCALER_MASK) +#define PDB_SC_DMAEN_MASK (0x8000U) +#define PDB_SC_DMAEN_SHIFT (15U) +/*! DMAEN - DMA Enable + * 0b0..DMA disabled. + * 0b1..DMA enabled. + */ +#define PDB_SC_DMAEN(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_DMAEN_SHIFT)) & PDB_SC_DMAEN_MASK) +#define PDB_SC_SWTRIG_MASK (0x10000U) +#define PDB_SC_SWTRIG_SHIFT (16U) +#define PDB_SC_SWTRIG(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_SWTRIG_SHIFT)) & PDB_SC_SWTRIG_MASK) +#define PDB_SC_PDBEIE_MASK (0x20000U) +#define PDB_SC_PDBEIE_SHIFT (17U) +/*! PDBEIE - PDB Sequence Error Interrupt Enable + * 0b0..PDB sequence error interrupt disabled. + * 0b1..PDB sequence error interrupt enabled. + */ +#define PDB_SC_PDBEIE(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_PDBEIE_SHIFT)) & PDB_SC_PDBEIE_MASK) +#define PDB_SC_LDMOD_MASK (0xC0000U) +#define PDB_SC_LDMOD_SHIFT (18U) +/*! LDMOD - Load Mode Select + * 0b00..The internal registers are loaded with the values from their buffers immediately after 1 is written to LDOK. + * 0b01..The internal registers are loaded with the values from their buffers when the PDB counter reaches the MOD register value after 1 is written to LDOK. + * 0b10..The internal registers are loaded with the values from their buffers when a trigger input event is detected after 1 is written to LDOK. + * 0b11..The internal registers are loaded with the values from their buffers when either the PDB counter reaches the MOD register value or a trigger input event is detected, after 1 is written to LDOK. + */ +#define PDB_SC_LDMOD(x) (((uint32_t)(((uint32_t)(x)) << PDB_SC_LDMOD_SHIFT)) & PDB_SC_LDMOD_MASK) +/*! @} */ + +/*! @name MOD - Modulus register */ +/*! @{ */ +#define PDB_MOD_MOD_MASK (0xFFFFU) +#define PDB_MOD_MOD_SHIFT (0U) +#define PDB_MOD_MOD(x) (((uint32_t)(((uint32_t)(x)) << PDB_MOD_MOD_SHIFT)) & PDB_MOD_MOD_MASK) +/*! @} */ + +/*! @name CNT - Counter register */ +/*! @{ */ +#define PDB_CNT_CNT_MASK (0xFFFFU) +#define PDB_CNT_CNT_SHIFT (0U) +#define PDB_CNT_CNT(x) (((uint32_t)(((uint32_t)(x)) << PDB_CNT_CNT_SHIFT)) & PDB_CNT_CNT_MASK) +/*! @} */ + +/*! @name IDLY - Interrupt Delay register */ +/*! @{ */ +#define PDB_IDLY_IDLY_MASK (0xFFFFU) +#define PDB_IDLY_IDLY_SHIFT (0U) +#define PDB_IDLY_IDLY(x) (((uint32_t)(((uint32_t)(x)) << PDB_IDLY_IDLY_SHIFT)) & PDB_IDLY_IDLY_MASK) +/*! @} */ + +/*! @name C1 - Channel n Control register 1 */ +/*! @{ */ +#define PDB_C1_EN_MASK (0xFFU) +#define PDB_C1_EN_SHIFT (0U) +/*! EN - PDB Channel Pre-Trigger Enable + * 0b00000000..PDB channel's corresponding pre-trigger disabled. + * 0b00000001..PDB channel's corresponding pre-trigger enabled. + */ +#define PDB_C1_EN(x) (((uint32_t)(((uint32_t)(x)) << PDB_C1_EN_SHIFT)) & PDB_C1_EN_MASK) +#define PDB_C1_TOS_MASK (0xFF00U) +#define PDB_C1_TOS_SHIFT (8U) +/*! TOS - PDB Channel Pre-Trigger Output Select + * 0b00000000..PDB channel's corresponding pre-trigger is in bypassed mode. The pre-trigger asserts one peripheral clock cycle after a rising edge is detected on selected trigger input source or software trigger is selected and SWTRIG is written with 1. + * 0b00000001..PDB channel's corresponding pre-trigger asserts when the counter reaches the channel delay register and one peripheral clock cycle after a rising edge is detected on selected trigger input source or software trigger is selected and SETRIG is written with 1. + */ +#define PDB_C1_TOS(x) (((uint32_t)(((uint32_t)(x)) << PDB_C1_TOS_SHIFT)) & PDB_C1_TOS_MASK) +#define PDB_C1_BB_MASK (0xFF0000U) +#define PDB_C1_BB_SHIFT (16U) +/*! BB - PDB Channel Pre-Trigger Back-to-Back Operation Enable + * 0b00000000..PDB channel's corresponding pre-trigger back-to-back operation disabled. + * 0b00000001..PDB channel's corresponding pre-trigger back-to-back operation enabled. + */ +#define PDB_C1_BB(x) (((uint32_t)(((uint32_t)(x)) << PDB_C1_BB_SHIFT)) & PDB_C1_BB_MASK) +/*! @} */ + +/* The count of PDB_C1 */ +#define PDB_C1_COUNT (2U) + +/*! @name S - Channel n Status register */ +/*! @{ */ +#define PDB_S_ERR_MASK (0xFFU) +#define PDB_S_ERR_SHIFT (0U) +/*! ERR - PDB Channel Sequence Error Flags + * 0b00000000..Sequence error not detected on PDB channel's corresponding pre-trigger. + * 0b00000001..Sequence error detected on PDB channel's corresponding pre-trigger. ADCn block can be triggered for a conversion by one pre-trigger from PDB channel n. When one conversion, which is triggered by one of the pre-triggers from PDB channel n, is in progress, new trigger from PDB channel's corresponding pre-trigger m cannot be accepted by ADCn, and ERR[m] is set. Writing 0's to clear the sequence error flags. + */ +#define PDB_S_ERR(x) (((uint32_t)(((uint32_t)(x)) << PDB_S_ERR_SHIFT)) & PDB_S_ERR_MASK) +#define PDB_S_CF_MASK (0xFF0000U) +#define PDB_S_CF_SHIFT (16U) +#define PDB_S_CF(x) (((uint32_t)(((uint32_t)(x)) << PDB_S_CF_SHIFT)) & PDB_S_CF_MASK) +/*! @} */ + +/* The count of PDB_S */ +#define PDB_S_COUNT (2U) + +/*! @name DLY - Channel n Delay 0 register..Channel n Delay 1 register */ +/*! @{ */ +#define PDB_DLY_DLY_MASK (0xFFFFU) +#define PDB_DLY_DLY_SHIFT (0U) +#define PDB_DLY_DLY(x) (((uint32_t)(((uint32_t)(x)) << PDB_DLY_DLY_SHIFT)) & PDB_DLY_DLY_MASK) +/*! @} */ + +/* The count of PDB_DLY */ +#define PDB_DLY_COUNT (2U) + +/* The count of PDB_DLY */ +#define PDB_DLY_COUNT2 (2U) + +/*! @name INTC - DAC Interval Trigger n Control register */ +/*! @{ */ +#define PDB_INTC_TOE_MASK (0x1U) +#define PDB_INTC_TOE_SHIFT (0U) +/*! TOE - DAC Interval Trigger Enable + * 0b0..DAC interval trigger disabled. + * 0b1..DAC interval trigger enabled. + */ +#define PDB_INTC_TOE(x) (((uint32_t)(((uint32_t)(x)) << PDB_INTC_TOE_SHIFT)) & PDB_INTC_TOE_MASK) +#define PDB_INTC_EXT_MASK (0x2U) +#define PDB_INTC_EXT_SHIFT (1U) +/*! EXT - DAC External Trigger Input Enable + * 0b0..DAC external trigger input disabled. DAC interval counter is reset and counting starts when a rising edge is detected on selected trigger input source or software trigger is selected and SWTRIG is written with 1. + * 0b1..DAC external trigger input enabled. DAC interval counter is bypassed and DAC external trigger input triggers the DAC interval trigger. + */ +#define PDB_INTC_EXT(x) (((uint32_t)(((uint32_t)(x)) << PDB_INTC_EXT_SHIFT)) & PDB_INTC_EXT_MASK) +/*! @} */ + +/* The count of PDB_INTC */ +#define PDB_INTC_COUNT (2U) + +/*! @name INT - DAC Interval n register */ +/*! @{ */ +#define PDB_INT_INT_MASK (0xFFFFU) +#define PDB_INT_INT_SHIFT (0U) +#define PDB_INT_INT(x) (((uint32_t)(((uint32_t)(x)) << PDB_INT_INT_SHIFT)) & PDB_INT_INT_MASK) +/*! @} */ + +/* The count of PDB_INT */ +#define PDB_INT_COUNT (2U) + +/*! @name POEN - Pulse-Out n Enable register */ +/*! @{ */ +#define PDB_POEN_POEN_MASK (0xFFU) +#define PDB_POEN_POEN_SHIFT (0U) +/*! POEN - PDB Pulse-Out Enable + * 0b00000000..PDB Pulse-Out disabled + * 0b00000001..PDB Pulse-Out enabled + */ +#define PDB_POEN_POEN(x) (((uint32_t)(((uint32_t)(x)) << PDB_POEN_POEN_SHIFT)) & PDB_POEN_POEN_MASK) +/*! @} */ + +/*! @name PODLY - Pulse-Out n Delay register */ +/*! @{ */ +#define PDB_PODLY_DLY2_MASK (0xFFFFU) +#define PDB_PODLY_DLY2_SHIFT (0U) +#define PDB_PODLY_DLY2(x) (((uint32_t)(((uint32_t)(x)) << PDB_PODLY_DLY2_SHIFT)) & PDB_PODLY_DLY2_MASK) +#define PDB_PODLY_DLY1_MASK (0xFFFF0000U) +#define PDB_PODLY_DLY1_SHIFT (16U) +#define PDB_PODLY_DLY1(x) (((uint32_t)(((uint32_t)(x)) << PDB_PODLY_DLY1_SHIFT)) & PDB_PODLY_DLY1_MASK) +/*! @} */ + +/* The count of PDB_PODLY */ +#define PDB_PODLY_COUNT (3U) + + +/*! + * @} + */ /* end of group PDB_Register_Masks */ + + +/* PDB - Peripheral instance base addresses */ +/** Peripheral PDB0 base address */ +#define PDB0_BASE (0x40036000u) +/** Peripheral PDB0 base pointer */ +#define PDB0 ((PDB_Type *)PDB0_BASE) +/** Array initializer of PDB peripheral base addresses */ +#define PDB_BASE_ADDRS { PDB0_BASE } +/** Array initializer of PDB peripheral base pointers */ +#define PDB_BASE_PTRS { PDB0 } +/** Interrupt vectors for the PDB peripheral type */ +#define PDB_IRQS { PDB0_IRQn } + +/*! + * @} + */ /* end of group PDB_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- PIT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PIT_Peripheral_Access_Layer PIT Peripheral Access Layer + * @{ + */ + +/** PIT - Register Layout Typedef */ +typedef struct { + __IO uint32_t MCR; /**< PIT Module Control Register, offset: 0x0 */ + uint8_t RESERVED_0[252]; + struct { /* offset: 0x100, array step: 0x10 */ + __IO uint32_t LDVAL; /**< Timer Load Value Register, array offset: 0x100, array step: 0x10 */ + __I uint32_t CVAL; /**< Current Timer Value Register, array offset: 0x104, array step: 0x10 */ + __IO uint32_t TCTRL; /**< Timer Control Register, array offset: 0x108, array step: 0x10 */ + __IO uint32_t TFLG; /**< Timer Flag Register, array offset: 0x10C, array step: 0x10 */ + } CHANNEL[4]; +} PIT_Type; + +/* ---------------------------------------------------------------------------- + -- PIT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PIT_Register_Masks PIT Register Masks + * @{ + */ + +/*! @name MCR - PIT Module Control Register */ +/*! @{ */ +#define PIT_MCR_FRZ_MASK (0x1U) +#define PIT_MCR_FRZ_SHIFT (0U) +/*! FRZ - Freeze + * 0b0..Timers continue to run in Debug mode. + * 0b1..Timers are stopped in Debug mode. + */ +#define PIT_MCR_FRZ(x) (((uint32_t)(((uint32_t)(x)) << PIT_MCR_FRZ_SHIFT)) & PIT_MCR_FRZ_MASK) +#define PIT_MCR_MDIS_MASK (0x2U) +#define PIT_MCR_MDIS_SHIFT (1U) +/*! MDIS - Module Disable - (PIT section) + * 0b0..Clock for standard PIT timers is enabled. + * 0b1..Clock for standard PIT timers is disabled. + */ +#define PIT_MCR_MDIS(x) (((uint32_t)(((uint32_t)(x)) << PIT_MCR_MDIS_SHIFT)) & PIT_MCR_MDIS_MASK) +/*! @} */ + +/*! @name LDVAL - Timer Load Value Register */ +/*! @{ */ +#define PIT_LDVAL_TSV_MASK (0xFFFFFFFFU) +#define PIT_LDVAL_TSV_SHIFT (0U) +#define PIT_LDVAL_TSV(x) (((uint32_t)(((uint32_t)(x)) << PIT_LDVAL_TSV_SHIFT)) & PIT_LDVAL_TSV_MASK) +/*! @} */ + +/* The count of PIT_LDVAL */ +#define PIT_LDVAL_COUNT (4U) + +/*! @name CVAL - Current Timer Value Register */ +/*! @{ */ +#define PIT_CVAL_TVL_MASK (0xFFFFFFFFU) +#define PIT_CVAL_TVL_SHIFT (0U) +#define PIT_CVAL_TVL(x) (((uint32_t)(((uint32_t)(x)) << PIT_CVAL_TVL_SHIFT)) & PIT_CVAL_TVL_MASK) +/*! @} */ + +/* The count of PIT_CVAL */ +#define PIT_CVAL_COUNT (4U) + +/*! @name TCTRL - Timer Control Register */ +/*! @{ */ +#define PIT_TCTRL_TEN_MASK (0x1U) +#define PIT_TCTRL_TEN_SHIFT (0U) +/*! TEN - Timer Enable + * 0b0..Timer n is disabled. + * 0b1..Timer n is enabled. + */ +#define PIT_TCTRL_TEN(x) (((uint32_t)(((uint32_t)(x)) << PIT_TCTRL_TEN_SHIFT)) & PIT_TCTRL_TEN_MASK) +#define PIT_TCTRL_TIE_MASK (0x2U) +#define PIT_TCTRL_TIE_SHIFT (1U) +/*! TIE - Timer Interrupt Enable + * 0b0..Interrupt requests from Timer n are disabled. + * 0b1..Interrupt will be requested whenever TIF is set. + */ +#define PIT_TCTRL_TIE(x) (((uint32_t)(((uint32_t)(x)) << PIT_TCTRL_TIE_SHIFT)) & PIT_TCTRL_TIE_MASK) +#define PIT_TCTRL_CHN_MASK (0x4U) +#define PIT_TCTRL_CHN_SHIFT (2U) +/*! CHN - Chain Mode + * 0b0..Timer is not chained. + * 0b1..Timer is chained to previous timer. For example, for Channel 2, if this field is set, Timer 2 is chained to Timer 1. + */ +#define PIT_TCTRL_CHN(x) (((uint32_t)(((uint32_t)(x)) << PIT_TCTRL_CHN_SHIFT)) & PIT_TCTRL_CHN_MASK) +/*! @} */ + +/* The count of PIT_TCTRL */ +#define PIT_TCTRL_COUNT (4U) + +/*! @name TFLG - Timer Flag Register */ +/*! @{ */ +#define PIT_TFLG_TIF_MASK (0x1U) +#define PIT_TFLG_TIF_SHIFT (0U) +/*! TIF - Timer Interrupt Flag + * 0b0..Timeout has not yet occurred. + * 0b1..Timeout has occurred. + */ +#define PIT_TFLG_TIF(x) (((uint32_t)(((uint32_t)(x)) << PIT_TFLG_TIF_SHIFT)) & PIT_TFLG_TIF_MASK) +/*! @} */ + +/* The count of PIT_TFLG */ +#define PIT_TFLG_COUNT (4U) + + +/*! + * @} + */ /* end of group PIT_Register_Masks */ + + +/* PIT - Peripheral instance base addresses */ +/** Peripheral PIT base address */ +#define PIT_BASE (0x40037000u) +/** Peripheral PIT base pointer */ +#define PIT ((PIT_Type *)PIT_BASE) +/** Array initializer of PIT peripheral base addresses */ +#define PIT_BASE_ADDRS { PIT_BASE } +/** Array initializer of PIT peripheral base pointers */ +#define PIT_BASE_PTRS { PIT } +/** Interrupt vectors for the PIT peripheral type */ +#define PIT_IRQS { { PIT0_IRQn, PIT1_IRQn, PIT2_IRQn, PIT3_IRQn } } + +/*! + * @} + */ /* end of group PIT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- PMC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PMC_Peripheral_Access_Layer PMC Peripheral Access Layer + * @{ + */ + +/** PMC - Register Layout Typedef */ +typedef struct { + __IO uint8_t LVDSC1; /**< Low Voltage Detect Status And Control 1 register, offset: 0x0 */ + __IO uint8_t LVDSC2; /**< Low Voltage Detect Status And Control 2 register, offset: 0x1 */ + __IO uint8_t REGSC; /**< Regulator Status And Control register, offset: 0x2 */ +} PMC_Type; + +/* ---------------------------------------------------------------------------- + -- PMC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PMC_Register_Masks PMC Register Masks + * @{ + */ + +/*! @name LVDSC1 - Low Voltage Detect Status And Control 1 register */ +/*! @{ */ +#define PMC_LVDSC1_LVDV_MASK (0x3U) +#define PMC_LVDSC1_LVDV_SHIFT (0U) +/*! LVDV - Low-Voltage Detect Voltage Select + * 0b00..Low trip point selected (V LVD = V LVDL ) + * 0b01..High trip point selected (V LVD = V LVDH ) + * 0b10..Reserved + * 0b11..Reserved + */ +#define PMC_LVDSC1_LVDV(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC1_LVDV_SHIFT)) & PMC_LVDSC1_LVDV_MASK) +#define PMC_LVDSC1_LVDRE_MASK (0x10U) +#define PMC_LVDSC1_LVDRE_SHIFT (4U) +/*! LVDRE - Low-Voltage Detect Reset Enable + * 0b0..LVDF does not generate hardware resets + * 0b1..Force an MCU reset when LVDF = 1 + */ +#define PMC_LVDSC1_LVDRE(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC1_LVDRE_SHIFT)) & PMC_LVDSC1_LVDRE_MASK) +#define PMC_LVDSC1_LVDIE_MASK (0x20U) +#define PMC_LVDSC1_LVDIE_SHIFT (5U) +/*! LVDIE - Low-Voltage Detect Interrupt Enable + * 0b0..Hardware interrupt disabled (use polling) + * 0b1..Request a hardware interrupt when LVDF = 1 + */ +#define PMC_LVDSC1_LVDIE(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC1_LVDIE_SHIFT)) & PMC_LVDSC1_LVDIE_MASK) +#define PMC_LVDSC1_LVDACK_MASK (0x40U) +#define PMC_LVDSC1_LVDACK_SHIFT (6U) +#define PMC_LVDSC1_LVDACK(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC1_LVDACK_SHIFT)) & PMC_LVDSC1_LVDACK_MASK) +#define PMC_LVDSC1_LVDF_MASK (0x80U) +#define PMC_LVDSC1_LVDF_SHIFT (7U) +/*! LVDF - Low-Voltage Detect Flag + * 0b0..Low-voltage event not detected + * 0b1..Low-voltage event detected + */ +#define PMC_LVDSC1_LVDF(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC1_LVDF_SHIFT)) & PMC_LVDSC1_LVDF_MASK) +/*! @} */ + +/*! @name LVDSC2 - Low Voltage Detect Status And Control 2 register */ +/*! @{ */ +#define PMC_LVDSC2_LVWV_MASK (0x3U) +#define PMC_LVDSC2_LVWV_SHIFT (0U) +/*! LVWV - Low-Voltage Warning Voltage Select + * 0b00..Low trip point selected (VLVW = VLVW1) + * 0b01..Mid 1 trip point selected (VLVW = VLVW2) + * 0b10..Mid 2 trip point selected (VLVW = VLVW3) + * 0b11..High trip point selected (VLVW = VLVW4) + */ +#define PMC_LVDSC2_LVWV(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC2_LVWV_SHIFT)) & PMC_LVDSC2_LVWV_MASK) +#define PMC_LVDSC2_LVWIE_MASK (0x20U) +#define PMC_LVDSC2_LVWIE_SHIFT (5U) +/*! LVWIE - Low-Voltage Warning Interrupt Enable + * 0b0..Hardware interrupt disabled (use polling) + * 0b1..Request a hardware interrupt when LVWF = 1 + */ +#define PMC_LVDSC2_LVWIE(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC2_LVWIE_SHIFT)) & PMC_LVDSC2_LVWIE_MASK) +#define PMC_LVDSC2_LVWACK_MASK (0x40U) +#define PMC_LVDSC2_LVWACK_SHIFT (6U) +#define PMC_LVDSC2_LVWACK(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC2_LVWACK_SHIFT)) & PMC_LVDSC2_LVWACK_MASK) +#define PMC_LVDSC2_LVWF_MASK (0x80U) +#define PMC_LVDSC2_LVWF_SHIFT (7U) +/*! LVWF - Low-Voltage Warning Flag + * 0b0..Low-voltage warning event not detected + * 0b1..Low-voltage warning event detected + */ +#define PMC_LVDSC2_LVWF(x) (((uint8_t)(((uint8_t)(x)) << PMC_LVDSC2_LVWF_SHIFT)) & PMC_LVDSC2_LVWF_MASK) +/*! @} */ + +/*! @name REGSC - Regulator Status And Control register */ +/*! @{ */ +#define PMC_REGSC_BGBE_MASK (0x1U) +#define PMC_REGSC_BGBE_SHIFT (0U) +/*! BGBE - Bandgap Buffer Enable + * 0b0..Bandgap buffer not enabled + * 0b1..Bandgap buffer enabled + */ +#define PMC_REGSC_BGBE(x) (((uint8_t)(((uint8_t)(x)) << PMC_REGSC_BGBE_SHIFT)) & PMC_REGSC_BGBE_MASK) +#define PMC_REGSC_REGONS_MASK (0x4U) +#define PMC_REGSC_REGONS_SHIFT (2U) +/*! REGONS - Regulator In Run Regulation Status + * 0b0..Regulator is in stop regulation or in transition to/from it + * 0b1..Regulator is in run regulation + */ +#define PMC_REGSC_REGONS(x) (((uint8_t)(((uint8_t)(x)) << PMC_REGSC_REGONS_SHIFT)) & PMC_REGSC_REGONS_MASK) +#define PMC_REGSC_ACKISO_MASK (0x8U) +#define PMC_REGSC_ACKISO_SHIFT (3U) +/*! ACKISO - Acknowledge Isolation + * 0b0..Peripherals and I/O pads are in normal run state. + * 0b1..Certain peripherals and I/O pads are in an isolated and latched state. + */ +#define PMC_REGSC_ACKISO(x) (((uint8_t)(((uint8_t)(x)) << PMC_REGSC_ACKISO_SHIFT)) & PMC_REGSC_ACKISO_MASK) +#define PMC_REGSC_BGEN_MASK (0x10U) +#define PMC_REGSC_BGEN_SHIFT (4U) +/*! BGEN - Bandgap Enable In VLPx Operation + * 0b0..Bandgap voltage reference is disabled in VLPx , LLS , and VLLSx modes. + * 0b1..Bandgap voltage reference is enabled in VLPx , LLS , and VLLSx modes. + */ +#define PMC_REGSC_BGEN(x) (((uint8_t)(((uint8_t)(x)) << PMC_REGSC_BGEN_SHIFT)) & PMC_REGSC_BGEN_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group PMC_Register_Masks */ + + +/* PMC - Peripheral instance base addresses */ +/** Peripheral PMC base address */ +#define PMC_BASE (0x4007D000u) +/** Peripheral PMC base pointer */ +#define PMC ((PMC_Type *)PMC_BASE) +/** Array initializer of PMC peripheral base addresses */ +#define PMC_BASE_ADDRS { PMC_BASE } +/** Array initializer of PMC peripheral base pointers */ +#define PMC_BASE_PTRS { PMC } +/** Interrupt vectors for the PMC peripheral type */ +#define PMC_IRQS { LVD_LVW_IRQn } + +/*! + * @} + */ /* end of group PMC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- PORT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PORT_Peripheral_Access_Layer PORT Peripheral Access Layer + * @{ + */ + +/** PORT - Register Layout Typedef */ +typedef struct { + __IO uint32_t PCR[32]; /**< Pin Control Register n, array offset: 0x0, array step: 0x4 */ + __O uint32_t GPCLR; /**< Global Pin Control Low Register, offset: 0x80 */ + __O uint32_t GPCHR; /**< Global Pin Control High Register, offset: 0x84 */ + uint8_t RESERVED_0[24]; + __IO uint32_t ISFR; /**< Interrupt Status Flag Register, offset: 0xA0 */ + uint8_t RESERVED_1[28]; + __IO uint32_t DFER; /**< Digital Filter Enable Register, offset: 0xC0 */ + __IO uint32_t DFCR; /**< Digital Filter Clock Register, offset: 0xC4 */ + __IO uint32_t DFWR; /**< Digital Filter Width Register, offset: 0xC8 */ +} PORT_Type; + +/* ---------------------------------------------------------------------------- + -- PORT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PORT_Register_Masks PORT Register Masks + * @{ + */ + +/*! @name PCR - Pin Control Register n */ +/*! @{ */ +#define PORT_PCR_PS_MASK (0x1U) +#define PORT_PCR_PS_SHIFT (0U) +/*! PS - Pull Select + * 0b0..Internal pulldown resistor is enabled on the corresponding pin, if the corresponding PE field is set. + * 0b1..Internal pullup resistor is enabled on the corresponding pin, if the corresponding PE field is set. + */ +#define PORT_PCR_PS(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_PS_SHIFT)) & PORT_PCR_PS_MASK) +#define PORT_PCR_PE_MASK (0x2U) +#define PORT_PCR_PE_SHIFT (1U) +/*! PE - Pull Enable + * 0b0..Internal pullup or pulldown resistor is not enabled on the corresponding pin. + * 0b1..Internal pullup or pulldown resistor is enabled on the corresponding pin, if the pin is configured as a digital input. + */ +#define PORT_PCR_PE(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_PE_SHIFT)) & PORT_PCR_PE_MASK) +#define PORT_PCR_SRE_MASK (0x4U) +#define PORT_PCR_SRE_SHIFT (2U) +/*! SRE - Slew Rate Enable + * 0b0..Fast slew rate is configured on the corresponding pin, if the pin is configured as a digital output. + * 0b1..Slow slew rate is configured on the corresponding pin, if the pin is configured as a digital output. + */ +#define PORT_PCR_SRE(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_SRE_SHIFT)) & PORT_PCR_SRE_MASK) +#define PORT_PCR_PFE_MASK (0x10U) +#define PORT_PCR_PFE_SHIFT (4U) +/*! PFE - Passive Filter Enable + * 0b0..Passive input filter is disabled on the corresponding pin. + * 0b1..Passive input filter is enabled on the corresponding pin, if the pin is configured as a digital input. Refer to the device data sheet for filter characteristics. + */ +#define PORT_PCR_PFE(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_PFE_SHIFT)) & PORT_PCR_PFE_MASK) +#define PORT_PCR_ODE_MASK (0x20U) +#define PORT_PCR_ODE_SHIFT (5U) +/*! ODE - Open Drain Enable + * 0b0..Open drain output is disabled on the corresponding pin. + * 0b1..Open drain output is enabled on the corresponding pin, if the pin is configured as a digital output. + */ +#define PORT_PCR_ODE(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_ODE_SHIFT)) & PORT_PCR_ODE_MASK) +#define PORT_PCR_DSE_MASK (0x40U) +#define PORT_PCR_DSE_SHIFT (6U) +/*! DSE - Drive Strength Enable + * 0b0..Low drive strength is configured on the corresponding pin, if pin is configured as a digital output. + * 0b1..High drive strength is configured on the corresponding pin, if pin is configured as a digital output. + */ +#define PORT_PCR_DSE(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_DSE_SHIFT)) & PORT_PCR_DSE_MASK) +#define PORT_PCR_MUX_MASK (0x700U) +#define PORT_PCR_MUX_SHIFT (8U) +/*! MUX - Pin Mux Control + * 0b000..Pin disabled (analog). + * 0b001..Alternative 1 (GPIO). + * 0b010..Alternative 2 (chip-specific). + * 0b011..Alternative 3 (chip-specific). + * 0b100..Alternative 4 (chip-specific). + * 0b101..Alternative 5 (chip-specific). + * 0b110..Alternative 6 (chip-specific). + * 0b111..Alternative 7 (chip-specific). + */ +#define PORT_PCR_MUX(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_MUX_SHIFT)) & PORT_PCR_MUX_MASK) +#define PORT_PCR_LK_MASK (0x8000U) +#define PORT_PCR_LK_SHIFT (15U) +/*! LK - Lock Register + * 0b0..Pin Control Register fields [15:0] are not locked. + * 0b1..Pin Control Register fields [15:0] are locked and cannot be updated until the next system reset. + */ +#define PORT_PCR_LK(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_LK_SHIFT)) & PORT_PCR_LK_MASK) +#define PORT_PCR_IRQC_MASK (0xF0000U) +#define PORT_PCR_IRQC_SHIFT (16U) +/*! IRQC - Interrupt Configuration + * 0b0000..Interrupt/DMA request disabled. + * 0b0001..DMA request on rising edge. + * 0b0010..DMA request on falling edge. + * 0b0011..DMA request on either edge. + * 0b1000..Interrupt when logic 0. + * 0b1001..Interrupt on rising-edge. + * 0b1010..Interrupt on falling-edge. + * 0b1011..Interrupt on either edge. + * 0b1100..Interrupt when logic 1. + */ +#define PORT_PCR_IRQC(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_IRQC_SHIFT)) & PORT_PCR_IRQC_MASK) +#define PORT_PCR_ISF_MASK (0x1000000U) +#define PORT_PCR_ISF_SHIFT (24U) +/*! ISF - Interrupt Status Flag + * 0b0..Configured interrupt is not detected. + * 0b1..Configured interrupt is detected. If the pin is configured to generate a DMA request, then the corresponding flag will be cleared automatically at the completion of the requested DMA transfer. Otherwise, the flag remains set until a logic 1 is written to the flag. If the pin is configured for a level sensitive interrupt and the pin remains asserted, then the flag is set again immediately after it is cleared. + */ +#define PORT_PCR_ISF(x) (((uint32_t)(((uint32_t)(x)) << PORT_PCR_ISF_SHIFT)) & PORT_PCR_ISF_MASK) +/*! @} */ + +/* The count of PORT_PCR */ +#define PORT_PCR_COUNT (32U) + +/*! @name GPCLR - Global Pin Control Low Register */ +/*! @{ */ +#define PORT_GPCLR_GPWD_MASK (0xFFFFU) +#define PORT_GPCLR_GPWD_SHIFT (0U) +#define PORT_GPCLR_GPWD(x) (((uint32_t)(((uint32_t)(x)) << PORT_GPCLR_GPWD_SHIFT)) & PORT_GPCLR_GPWD_MASK) +#define PORT_GPCLR_GPWE_MASK (0xFFFF0000U) +#define PORT_GPCLR_GPWE_SHIFT (16U) +/*! GPWE - Global Pin Write Enable + * 0b0000000000000000..Corresponding Pin Control Register is not updated with the value in GPWD. + * 0b0000000000000001..Corresponding Pin Control Register is updated with the value in GPWD. + */ +#define PORT_GPCLR_GPWE(x) (((uint32_t)(((uint32_t)(x)) << PORT_GPCLR_GPWE_SHIFT)) & PORT_GPCLR_GPWE_MASK) +/*! @} */ + +/*! @name GPCHR - Global Pin Control High Register */ +/*! @{ */ +#define PORT_GPCHR_GPWD_MASK (0xFFFFU) +#define PORT_GPCHR_GPWD_SHIFT (0U) +#define PORT_GPCHR_GPWD(x) (((uint32_t)(((uint32_t)(x)) << PORT_GPCHR_GPWD_SHIFT)) & PORT_GPCHR_GPWD_MASK) +#define PORT_GPCHR_GPWE_MASK (0xFFFF0000U) +#define PORT_GPCHR_GPWE_SHIFT (16U) +/*! GPWE - Global Pin Write Enable + * 0b0000000000000000..Corresponding Pin Control Register is not updated with the value in GPWD. + * 0b0000000000000001..Corresponding Pin Control Register is updated with the value in GPWD. + */ +#define PORT_GPCHR_GPWE(x) (((uint32_t)(((uint32_t)(x)) << PORT_GPCHR_GPWE_SHIFT)) & PORT_GPCHR_GPWE_MASK) +/*! @} */ + +/*! @name ISFR - Interrupt Status Flag Register */ +/*! @{ */ +#define PORT_ISFR_ISF_MASK (0xFFFFFFFFU) +#define PORT_ISFR_ISF_SHIFT (0U) +/*! ISF - Interrupt Status Flag + * 0b00000000000000000000000000000000..Configured interrupt is not detected. + * 0b00000000000000000000000000000001..Configured interrupt is detected. If the pin is configured to generate a DMA request, then the corresponding flag will be cleared automatically at the completion of the requested DMA transfer. Otherwise, the flag remains set until a logic 1 is written to the flag. If the pin is configured for a level sensitive interrupt and the pin remains asserted, then the flag is set again immediately after it is cleared. + */ +#define PORT_ISFR_ISF(x) (((uint32_t)(((uint32_t)(x)) << PORT_ISFR_ISF_SHIFT)) & PORT_ISFR_ISF_MASK) +/*! @} */ + +/*! @name DFER - Digital Filter Enable Register */ +/*! @{ */ +#define PORT_DFER_DFE_MASK (0xFFFFFFFFU) +#define PORT_DFER_DFE_SHIFT (0U) +/*! DFE - Digital Filter Enable + * 0b00000000000000000000000000000000..Digital filter is disabled on the corresponding pin and output of the digital filter is reset to zero. + * 0b00000000000000000000000000000001..Digital filter is enabled on the corresponding pin, if the pin is configured as a digital input. + */ +#define PORT_DFER_DFE(x) (((uint32_t)(((uint32_t)(x)) << PORT_DFER_DFE_SHIFT)) & PORT_DFER_DFE_MASK) +/*! @} */ + +/*! @name DFCR - Digital Filter Clock Register */ +/*! @{ */ +#define PORT_DFCR_CS_MASK (0x1U) +#define PORT_DFCR_CS_SHIFT (0U) +/*! CS - Clock Source + * 0b0..Digital filters are clocked by the bus clock. + * 0b1..Digital filters are clocked by the 1 kHz LPO clock. + */ +#define PORT_DFCR_CS(x) (((uint32_t)(((uint32_t)(x)) << PORT_DFCR_CS_SHIFT)) & PORT_DFCR_CS_MASK) +/*! @} */ + +/*! @name DFWR - Digital Filter Width Register */ +/*! @{ */ +#define PORT_DFWR_FILT_MASK (0x1FU) +#define PORT_DFWR_FILT_SHIFT (0U) +#define PORT_DFWR_FILT(x) (((uint32_t)(((uint32_t)(x)) << PORT_DFWR_FILT_SHIFT)) & PORT_DFWR_FILT_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group PORT_Register_Masks */ + + +/* PORT - Peripheral instance base addresses */ +/** Peripheral PORTA base address */ +#define PORTA_BASE (0x40049000u) +/** Peripheral PORTA base pointer */ +#define PORTA ((PORT_Type *)PORTA_BASE) +/** Peripheral PORTB base address */ +#define PORTB_BASE (0x4004A000u) +/** Peripheral PORTB base pointer */ +#define PORTB ((PORT_Type *)PORTB_BASE) +/** Peripheral PORTC base address */ +#define PORTC_BASE (0x4004B000u) +/** Peripheral PORTC base pointer */ +#define PORTC ((PORT_Type *)PORTC_BASE) +/** Peripheral PORTD base address */ +#define PORTD_BASE (0x4004C000u) +/** Peripheral PORTD base pointer */ +#define PORTD ((PORT_Type *)PORTD_BASE) +/** Peripheral PORTE base address */ +#define PORTE_BASE (0x4004D000u) +/** Peripheral PORTE base pointer */ +#define PORTE ((PORT_Type *)PORTE_BASE) +/** Array initializer of PORT peripheral base addresses */ +#define PORT_BASE_ADDRS { PORTA_BASE, PORTB_BASE, PORTC_BASE, PORTD_BASE, PORTE_BASE } +/** Array initializer of PORT peripheral base pointers */ +#define PORT_BASE_PTRS { PORTA, PORTB, PORTC, PORTD, PORTE } +/** Interrupt vectors for the PORT peripheral type */ +#define PORT_IRQS { PORTA_IRQn, PORTB_IRQn, PORTC_IRQn, PORTD_IRQn, PORTE_IRQn } + +/*! + * @} + */ /* end of group PORT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- RCM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RCM_Peripheral_Access_Layer RCM Peripheral Access Layer + * @{ + */ + +/** RCM - Register Layout Typedef */ +typedef struct { + __I uint8_t SRS0; /**< System Reset Status Register 0, offset: 0x0 */ + __I uint8_t SRS1; /**< System Reset Status Register 1, offset: 0x1 */ + uint8_t RESERVED_0[2]; + __IO uint8_t RPFC; /**< Reset Pin Filter Control register, offset: 0x4 */ + __IO uint8_t RPFW; /**< Reset Pin Filter Width register, offset: 0x5 */ + uint8_t RESERVED_1[1]; + __I uint8_t MR; /**< Mode Register, offset: 0x7 */ +} RCM_Type; + +/* ---------------------------------------------------------------------------- + -- RCM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RCM_Register_Masks RCM Register Masks + * @{ + */ + +/*! @name SRS0 - System Reset Status Register 0 */ +/*! @{ */ +#define RCM_SRS0_WAKEUP_MASK (0x1U) +#define RCM_SRS0_WAKEUP_SHIFT (0U) +/*! WAKEUP - Low Leakage Wakeup Reset + * 0b0..Reset not caused by LLWU module wakeup source + * 0b1..Reset caused by LLWU module wakeup source + */ +#define RCM_SRS0_WAKEUP(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_WAKEUP_SHIFT)) & RCM_SRS0_WAKEUP_MASK) +#define RCM_SRS0_LVD_MASK (0x2U) +#define RCM_SRS0_LVD_SHIFT (1U) +/*! LVD - Low-Voltage Detect Reset + * 0b0..Reset not caused by LVD trip or POR + * 0b1..Reset caused by LVD trip or POR + */ +#define RCM_SRS0_LVD(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_LVD_SHIFT)) & RCM_SRS0_LVD_MASK) +#define RCM_SRS0_LOC_MASK (0x4U) +#define RCM_SRS0_LOC_SHIFT (2U) +/*! LOC - Loss-of-Clock Reset + * 0b0..Reset not caused by a loss of external clock. + * 0b1..Reset caused by a loss of external clock. + */ +#define RCM_SRS0_LOC(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_LOC_SHIFT)) & RCM_SRS0_LOC_MASK) +#define RCM_SRS0_LOL_MASK (0x8U) +#define RCM_SRS0_LOL_SHIFT (3U) +/*! LOL - Loss-of-Lock Reset + * 0b0..Reset not caused by a loss of lock in the PLL + * 0b1..Reset caused by a loss of lock in the PLL + */ +#define RCM_SRS0_LOL(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_LOL_SHIFT)) & RCM_SRS0_LOL_MASK) +#define RCM_SRS0_WDOG_MASK (0x20U) +#define RCM_SRS0_WDOG_SHIFT (5U) +/*! WDOG - Watchdog + * 0b0..Reset not caused by watchdog timeout + * 0b1..Reset caused by watchdog timeout + */ +#define RCM_SRS0_WDOG(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_WDOG_SHIFT)) & RCM_SRS0_WDOG_MASK) +#define RCM_SRS0_PIN_MASK (0x40U) +#define RCM_SRS0_PIN_SHIFT (6U) +/*! PIN - External Reset Pin + * 0b0..Reset not caused by external reset pin + * 0b1..Reset caused by external reset pin + */ +#define RCM_SRS0_PIN(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_PIN_SHIFT)) & RCM_SRS0_PIN_MASK) +#define RCM_SRS0_POR_MASK (0x80U) +#define RCM_SRS0_POR_SHIFT (7U) +/*! POR - Power-On Reset + * 0b0..Reset not caused by POR + * 0b1..Reset caused by POR + */ +#define RCM_SRS0_POR(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS0_POR_SHIFT)) & RCM_SRS0_POR_MASK) +/*! @} */ + +/*! @name SRS1 - System Reset Status Register 1 */ +/*! @{ */ +#define RCM_SRS1_JTAG_MASK (0x1U) +#define RCM_SRS1_JTAG_SHIFT (0U) +/*! JTAG - JTAG Generated Reset + * 0b0..Reset not caused by JTAG + * 0b1..Reset caused by JTAG + */ +#define RCM_SRS1_JTAG(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS1_JTAG_SHIFT)) & RCM_SRS1_JTAG_MASK) +#define RCM_SRS1_LOCKUP_MASK (0x2U) +#define RCM_SRS1_LOCKUP_SHIFT (1U) +/*! LOCKUP - Core Lockup + * 0b0..Reset not caused by core LOCKUP event + * 0b1..Reset caused by core LOCKUP event + */ +#define RCM_SRS1_LOCKUP(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS1_LOCKUP_SHIFT)) & RCM_SRS1_LOCKUP_MASK) +#define RCM_SRS1_SW_MASK (0x4U) +#define RCM_SRS1_SW_SHIFT (2U) +/*! SW - Software + * 0b0..Reset not caused by software setting of SYSRESETREQ bit + * 0b1..Reset caused by software setting of SYSRESETREQ bit + */ +#define RCM_SRS1_SW(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS1_SW_SHIFT)) & RCM_SRS1_SW_MASK) +#define RCM_SRS1_MDM_AP_MASK (0x8U) +#define RCM_SRS1_MDM_AP_SHIFT (3U) +/*! MDM_AP - MDM-AP System Reset Request + * 0b0..Reset not caused by host debugger system setting of the System Reset Request bit + * 0b1..Reset caused by host debugger system setting of the System Reset Request bit + */ +#define RCM_SRS1_MDM_AP(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS1_MDM_AP_SHIFT)) & RCM_SRS1_MDM_AP_MASK) +#define RCM_SRS1_EZPT_MASK (0x10U) +#define RCM_SRS1_EZPT_SHIFT (4U) +/*! EZPT - EzPort Reset + * 0b0..Reset not caused by EzPort receiving the RESET command while the device is in EzPort mode + * 0b1..Reset caused by EzPort receiving the RESET command while the device is in EzPort mode + */ +#define RCM_SRS1_EZPT(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS1_EZPT_SHIFT)) & RCM_SRS1_EZPT_MASK) +#define RCM_SRS1_SACKERR_MASK (0x20U) +#define RCM_SRS1_SACKERR_SHIFT (5U) +/*! SACKERR - Stop Mode Acknowledge Error Reset + * 0b0..Reset not caused by peripheral failure to acknowledge attempt to enter stop mode + * 0b1..Reset caused by peripheral failure to acknowledge attempt to enter stop mode + */ +#define RCM_SRS1_SACKERR(x) (((uint8_t)(((uint8_t)(x)) << RCM_SRS1_SACKERR_SHIFT)) & RCM_SRS1_SACKERR_MASK) +/*! @} */ + +/*! @name RPFC - Reset Pin Filter Control register */ +/*! @{ */ +#define RCM_RPFC_RSTFLTSRW_MASK (0x3U) +#define RCM_RPFC_RSTFLTSRW_SHIFT (0U) +/*! RSTFLTSRW - Reset Pin Filter Select in Run and Wait Modes + * 0b00..All filtering disabled + * 0b01..Bus clock filter enabled for normal operation + * 0b10..LPO clock filter enabled for normal operation + * 0b11..Reserved + */ +#define RCM_RPFC_RSTFLTSRW(x) (((uint8_t)(((uint8_t)(x)) << RCM_RPFC_RSTFLTSRW_SHIFT)) & RCM_RPFC_RSTFLTSRW_MASK) +#define RCM_RPFC_RSTFLTSS_MASK (0x4U) +#define RCM_RPFC_RSTFLTSS_SHIFT (2U) +/*! RSTFLTSS - Reset Pin Filter Select in Stop Mode + * 0b0..All filtering disabled + * 0b1..LPO clock filter enabled + */ +#define RCM_RPFC_RSTFLTSS(x) (((uint8_t)(((uint8_t)(x)) << RCM_RPFC_RSTFLTSS_SHIFT)) & RCM_RPFC_RSTFLTSS_MASK) +/*! @} */ + +/*! @name RPFW - Reset Pin Filter Width register */ +/*! @{ */ +#define RCM_RPFW_RSTFLTSEL_MASK (0x1FU) +#define RCM_RPFW_RSTFLTSEL_SHIFT (0U) +/*! RSTFLTSEL - Reset Pin Filter Bus Clock Select + * 0b00000..Bus clock filter count is 1 + * 0b00001..Bus clock filter count is 2 + * 0b00010..Bus clock filter count is 3 + * 0b00011..Bus clock filter count is 4 + * 0b00100..Bus clock filter count is 5 + * 0b00101..Bus clock filter count is 6 + * 0b00110..Bus clock filter count is 7 + * 0b00111..Bus clock filter count is 8 + * 0b01000..Bus clock filter count is 9 + * 0b01001..Bus clock filter count is 10 + * 0b01010..Bus clock filter count is 11 + * 0b01011..Bus clock filter count is 12 + * 0b01100..Bus clock filter count is 13 + * 0b01101..Bus clock filter count is 14 + * 0b01110..Bus clock filter count is 15 + * 0b01111..Bus clock filter count is 16 + * 0b10000..Bus clock filter count is 17 + * 0b10001..Bus clock filter count is 18 + * 0b10010..Bus clock filter count is 19 + * 0b10011..Bus clock filter count is 20 + * 0b10100..Bus clock filter count is 21 + * 0b10101..Bus clock filter count is 22 + * 0b10110..Bus clock filter count is 23 + * 0b10111..Bus clock filter count is 24 + * 0b11000..Bus clock filter count is 25 + * 0b11001..Bus clock filter count is 26 + * 0b11010..Bus clock filter count is 27 + * 0b11011..Bus clock filter count is 28 + * 0b11100..Bus clock filter count is 29 + * 0b11101..Bus clock filter count is 30 + * 0b11110..Bus clock filter count is 31 + * 0b11111..Bus clock filter count is 32 + */ +#define RCM_RPFW_RSTFLTSEL(x) (((uint8_t)(((uint8_t)(x)) << RCM_RPFW_RSTFLTSEL_SHIFT)) & RCM_RPFW_RSTFLTSEL_MASK) +/*! @} */ + +/*! @name MR - Mode Register */ +/*! @{ */ +#define RCM_MR_EZP_MS_MASK (0x2U) +#define RCM_MR_EZP_MS_SHIFT (1U) +/*! EZP_MS - EZP_MS_B pin state + * 0b0..Pin deasserted (logic 1) + * 0b1..Pin asserted (logic 0) + */ +#define RCM_MR_EZP_MS(x) (((uint8_t)(((uint8_t)(x)) << RCM_MR_EZP_MS_SHIFT)) & RCM_MR_EZP_MS_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group RCM_Register_Masks */ + + +/* RCM - Peripheral instance base addresses */ +/** Peripheral RCM base address */ +#define RCM_BASE (0x4007F000u) +/** Peripheral RCM base pointer */ +#define RCM ((RCM_Type *)RCM_BASE) +/** Array initializer of RCM peripheral base addresses */ +#define RCM_BASE_ADDRS { RCM_BASE } +/** Array initializer of RCM peripheral base pointers */ +#define RCM_BASE_PTRS { RCM } + +/*! + * @} + */ /* end of group RCM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- RFSYS Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RFSYS_Peripheral_Access_Layer RFSYS Peripheral Access Layer + * @{ + */ + +/** RFSYS - Register Layout Typedef */ +typedef struct { + __IO uint32_t REG[8]; /**< Register file register, array offset: 0x0, array step: 0x4 */ +} RFSYS_Type; + +/* ---------------------------------------------------------------------------- + -- RFSYS Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RFSYS_Register_Masks RFSYS Register Masks + * @{ + */ + +/*! @name REG - Register file register */ +/*! @{ */ +#define RFSYS_REG_LL_MASK (0xFFU) +#define RFSYS_REG_LL_SHIFT (0U) +#define RFSYS_REG_LL(x) (((uint32_t)(((uint32_t)(x)) << RFSYS_REG_LL_SHIFT)) & RFSYS_REG_LL_MASK) +#define RFSYS_REG_LH_MASK (0xFF00U) +#define RFSYS_REG_LH_SHIFT (8U) +#define RFSYS_REG_LH(x) (((uint32_t)(((uint32_t)(x)) << RFSYS_REG_LH_SHIFT)) & RFSYS_REG_LH_MASK) +#define RFSYS_REG_HL_MASK (0xFF0000U) +#define RFSYS_REG_HL_SHIFT (16U) +#define RFSYS_REG_HL(x) (((uint32_t)(((uint32_t)(x)) << RFSYS_REG_HL_SHIFT)) & RFSYS_REG_HL_MASK) +#define RFSYS_REG_HH_MASK (0xFF000000U) +#define RFSYS_REG_HH_SHIFT (24U) +#define RFSYS_REG_HH(x) (((uint32_t)(((uint32_t)(x)) << RFSYS_REG_HH_SHIFT)) & RFSYS_REG_HH_MASK) +/*! @} */ + +/* The count of RFSYS_REG */ +#define RFSYS_REG_COUNT (8U) + + +/*! + * @} + */ /* end of group RFSYS_Register_Masks */ + + +/* RFSYS - Peripheral instance base addresses */ +/** Peripheral RFSYS base address */ +#define RFSYS_BASE (0x40041000u) +/** Peripheral RFSYS base pointer */ +#define RFSYS ((RFSYS_Type *)RFSYS_BASE) +/** Array initializer of RFSYS peripheral base addresses */ +#define RFSYS_BASE_ADDRS { RFSYS_BASE } +/** Array initializer of RFSYS peripheral base pointers */ +#define RFSYS_BASE_PTRS { RFSYS } + +/*! + * @} + */ /* end of group RFSYS_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- RFVBAT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RFVBAT_Peripheral_Access_Layer RFVBAT Peripheral Access Layer + * @{ + */ + +/** RFVBAT - Register Layout Typedef */ +typedef struct { + __IO uint32_t REG[8]; /**< VBAT register file register, array offset: 0x0, array step: 0x4 */ +} RFVBAT_Type; + +/* ---------------------------------------------------------------------------- + -- RFVBAT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RFVBAT_Register_Masks RFVBAT Register Masks + * @{ + */ + +/*! @name REG - VBAT register file register */ +/*! @{ */ +#define RFVBAT_REG_LL_MASK (0xFFU) +#define RFVBAT_REG_LL_SHIFT (0U) +#define RFVBAT_REG_LL(x) (((uint32_t)(((uint32_t)(x)) << RFVBAT_REG_LL_SHIFT)) & RFVBAT_REG_LL_MASK) +#define RFVBAT_REG_LH_MASK (0xFF00U) +#define RFVBAT_REG_LH_SHIFT (8U) +#define RFVBAT_REG_LH(x) (((uint32_t)(((uint32_t)(x)) << RFVBAT_REG_LH_SHIFT)) & RFVBAT_REG_LH_MASK) +#define RFVBAT_REG_HL_MASK (0xFF0000U) +#define RFVBAT_REG_HL_SHIFT (16U) +#define RFVBAT_REG_HL(x) (((uint32_t)(((uint32_t)(x)) << RFVBAT_REG_HL_SHIFT)) & RFVBAT_REG_HL_MASK) +#define RFVBAT_REG_HH_MASK (0xFF000000U) +#define RFVBAT_REG_HH_SHIFT (24U) +#define RFVBAT_REG_HH(x) (((uint32_t)(((uint32_t)(x)) << RFVBAT_REG_HH_SHIFT)) & RFVBAT_REG_HH_MASK) +/*! @} */ + +/* The count of RFVBAT_REG */ +#define RFVBAT_REG_COUNT (8U) + + +/*! + * @} + */ /* end of group RFVBAT_Register_Masks */ + + +/* RFVBAT - Peripheral instance base addresses */ +/** Peripheral RFVBAT base address */ +#define RFVBAT_BASE (0x4003E000u) +/** Peripheral RFVBAT base pointer */ +#define RFVBAT ((RFVBAT_Type *)RFVBAT_BASE) +/** Array initializer of RFVBAT peripheral base addresses */ +#define RFVBAT_BASE_ADDRS { RFVBAT_BASE } +/** Array initializer of RFVBAT peripheral base pointers */ +#define RFVBAT_BASE_PTRS { RFVBAT } + +/*! + * @} + */ /* end of group RFVBAT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- RNG Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RNG_Peripheral_Access_Layer RNG Peripheral Access Layer + * @{ + */ + +/** RNG - Register Layout Typedef */ +typedef struct { + __IO uint32_t CR; /**< RNGA Control Register, offset: 0x0 */ + __I uint32_t SR; /**< RNGA Status Register, offset: 0x4 */ + __O uint32_t ER; /**< RNGA Entropy Register, offset: 0x8 */ + __I uint32_t OR; /**< RNGA Output Register, offset: 0xC */ +} RNG_Type; + +/* ---------------------------------------------------------------------------- + -- RNG Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RNG_Register_Masks RNG Register Masks + * @{ + */ + +/*! @name CR - RNGA Control Register */ +/*! @{ */ +#define RNG_CR_GO_MASK (0x1U) +#define RNG_CR_GO_SHIFT (0U) +/*! GO - Go + * 0b0..Disabled + * 0b1..Enabled + */ +#define RNG_CR_GO(x) (((uint32_t)(((uint32_t)(x)) << RNG_CR_GO_SHIFT)) & RNG_CR_GO_MASK) +#define RNG_CR_HA_MASK (0x2U) +#define RNG_CR_HA_SHIFT (1U) +/*! HA - High Assurance + * 0b0..Disabled + * 0b1..Enabled + */ +#define RNG_CR_HA(x) (((uint32_t)(((uint32_t)(x)) << RNG_CR_HA_SHIFT)) & RNG_CR_HA_MASK) +#define RNG_CR_INTM_MASK (0x4U) +#define RNG_CR_INTM_SHIFT (2U) +/*! INTM - Interrupt Mask + * 0b0..Not masked + * 0b1..Masked + */ +#define RNG_CR_INTM(x) (((uint32_t)(((uint32_t)(x)) << RNG_CR_INTM_SHIFT)) & RNG_CR_INTM_MASK) +#define RNG_CR_CLRI_MASK (0x8U) +#define RNG_CR_CLRI_SHIFT (3U) +/*! CLRI - Clear Interrupt + * 0b0..Do not clear the interrupt. + * 0b1..Clear the interrupt. When you write 1 to this field, RNGA then resets the error-interrupt indicator (SR[ERRI]). This bit always reads as 0. + */ +#define RNG_CR_CLRI(x) (((uint32_t)(((uint32_t)(x)) << RNG_CR_CLRI_SHIFT)) & RNG_CR_CLRI_MASK) +#define RNG_CR_SLP_MASK (0x10U) +#define RNG_CR_SLP_SHIFT (4U) +/*! SLP - Sleep + * 0b0..Normal mode + * 0b1..Sleep (low-power) mode + */ +#define RNG_CR_SLP(x) (((uint32_t)(((uint32_t)(x)) << RNG_CR_SLP_SHIFT)) & RNG_CR_SLP_MASK) +/*! @} */ + +/*! @name SR - RNGA Status Register */ +/*! @{ */ +#define RNG_SR_SECV_MASK (0x1U) +#define RNG_SR_SECV_SHIFT (0U) +/*! SECV - Security Violation + * 0b0..No security violation + * 0b1..Security violation + */ +#define RNG_SR_SECV(x) (((uint32_t)(((uint32_t)(x)) << RNG_SR_SECV_SHIFT)) & RNG_SR_SECV_MASK) +#define RNG_SR_LRS_MASK (0x2U) +#define RNG_SR_LRS_SHIFT (1U) +/*! LRS - Last Read Status + * 0b0..No underflow + * 0b1..Underflow + */ +#define RNG_SR_LRS(x) (((uint32_t)(((uint32_t)(x)) << RNG_SR_LRS_SHIFT)) & RNG_SR_LRS_MASK) +#define RNG_SR_ORU_MASK (0x4U) +#define RNG_SR_ORU_SHIFT (2U) +/*! ORU - Output Register Underflow + * 0b0..No underflow + * 0b1..Underflow + */ +#define RNG_SR_ORU(x) (((uint32_t)(((uint32_t)(x)) << RNG_SR_ORU_SHIFT)) & RNG_SR_ORU_MASK) +#define RNG_SR_ERRI_MASK (0x8U) +#define RNG_SR_ERRI_SHIFT (3U) +/*! ERRI - Error Interrupt + * 0b0..No underflow + * 0b1..Underflow + */ +#define RNG_SR_ERRI(x) (((uint32_t)(((uint32_t)(x)) << RNG_SR_ERRI_SHIFT)) & RNG_SR_ERRI_MASK) +#define RNG_SR_SLP_MASK (0x10U) +#define RNG_SR_SLP_SHIFT (4U) +/*! SLP - Sleep + * 0b0..Normal mode + * 0b1..Sleep (low-power) mode + */ +#define RNG_SR_SLP(x) (((uint32_t)(((uint32_t)(x)) << RNG_SR_SLP_SHIFT)) & RNG_SR_SLP_MASK) +#define RNG_SR_OREG_LVL_MASK (0xFF00U) +#define RNG_SR_OREG_LVL_SHIFT (8U) +/*! OREG_LVL - Output Register Level + * 0b00000000..No words (empty) + * 0b00000001..One word (valid) + */ +#define RNG_SR_OREG_LVL(x) (((uint32_t)(((uint32_t)(x)) << RNG_SR_OREG_LVL_SHIFT)) & RNG_SR_OREG_LVL_MASK) +#define RNG_SR_OREG_SIZE_MASK (0xFF0000U) +#define RNG_SR_OREG_SIZE_SHIFT (16U) +/*! OREG_SIZE - Output Register Size + * 0b00000001..One word (this value is fixed) + */ +#define RNG_SR_OREG_SIZE(x) (((uint32_t)(((uint32_t)(x)) << RNG_SR_OREG_SIZE_SHIFT)) & RNG_SR_OREG_SIZE_MASK) +/*! @} */ + +/*! @name ER - RNGA Entropy Register */ +/*! @{ */ +#define RNG_ER_EXT_ENT_MASK (0xFFFFFFFFU) +#define RNG_ER_EXT_ENT_SHIFT (0U) +#define RNG_ER_EXT_ENT(x) (((uint32_t)(((uint32_t)(x)) << RNG_ER_EXT_ENT_SHIFT)) & RNG_ER_EXT_ENT_MASK) +/*! @} */ + +/*! @name OR - RNGA Output Register */ +/*! @{ */ +#define RNG_OR_RANDOUT_MASK (0xFFFFFFFFU) +#define RNG_OR_RANDOUT_SHIFT (0U) +/*! RANDOUT - Random Output + * 0b00000000000000000000000000000000..Invalid data (if you read this field when it is 0 and SR[OREG_LVL] is 0, RNGA then writes 1 to SR[ERRI], SR[ORU], and SR[LRS]; when the error interrupt is not masked (CR[INTM]=0), RNGA also asserts an error interrupt request to the interrupt controller). + */ +#define RNG_OR_RANDOUT(x) (((uint32_t)(((uint32_t)(x)) << RNG_OR_RANDOUT_SHIFT)) & RNG_OR_RANDOUT_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group RNG_Register_Masks */ + + +/* RNG - Peripheral instance base addresses */ +/** Peripheral RNG base address */ +#define RNG_BASE (0x40029000u) +/** Peripheral RNG base pointer */ +#define RNG ((RNG_Type *)RNG_BASE) +/** Array initializer of RNG peripheral base addresses */ +#define RNG_BASE_ADDRS { RNG_BASE } +/** Array initializer of RNG peripheral base pointers */ +#define RNG_BASE_PTRS { RNG } +/** Interrupt vectors for the RNG peripheral type */ +#define RNG_IRQS { RNG_IRQn } + +/*! + * @} + */ /* end of group RNG_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- RTC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RTC_Peripheral_Access_Layer RTC Peripheral Access Layer + * @{ + */ + +/** RTC - Register Layout Typedef */ +typedef struct { + __IO uint32_t TSR; /**< RTC Time Seconds Register, offset: 0x0 */ + __IO uint32_t TPR; /**< RTC Time Prescaler Register, offset: 0x4 */ + __IO uint32_t TAR; /**< RTC Time Alarm Register, offset: 0x8 */ + __IO uint32_t TCR; /**< RTC Time Compensation Register, offset: 0xC */ + __IO uint32_t CR; /**< RTC Control Register, offset: 0x10 */ + __IO uint32_t SR; /**< RTC Status Register, offset: 0x14 */ + __IO uint32_t LR; /**< RTC Lock Register, offset: 0x18 */ + __IO uint32_t IER; /**< RTC Interrupt Enable Register, offset: 0x1C */ + uint8_t RESERVED_0[2016]; + __IO uint32_t WAR; /**< RTC Write Access Register, offset: 0x800 */ + __IO uint32_t RAR; /**< RTC Read Access Register, offset: 0x804 */ +} RTC_Type; + +/* ---------------------------------------------------------------------------- + -- RTC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RTC_Register_Masks RTC Register Masks + * @{ + */ + +/*! @name TSR - RTC Time Seconds Register */ +/*! @{ */ +#define RTC_TSR_TSR_MASK (0xFFFFFFFFU) +#define RTC_TSR_TSR_SHIFT (0U) +#define RTC_TSR_TSR(x) (((uint32_t)(((uint32_t)(x)) << RTC_TSR_TSR_SHIFT)) & RTC_TSR_TSR_MASK) +/*! @} */ + +/*! @name TPR - RTC Time Prescaler Register */ +/*! @{ */ +#define RTC_TPR_TPR_MASK (0xFFFFU) +#define RTC_TPR_TPR_SHIFT (0U) +#define RTC_TPR_TPR(x) (((uint32_t)(((uint32_t)(x)) << RTC_TPR_TPR_SHIFT)) & RTC_TPR_TPR_MASK) +/*! @} */ + +/*! @name TAR - RTC Time Alarm Register */ +/*! @{ */ +#define RTC_TAR_TAR_MASK (0xFFFFFFFFU) +#define RTC_TAR_TAR_SHIFT (0U) +#define RTC_TAR_TAR(x) (((uint32_t)(((uint32_t)(x)) << RTC_TAR_TAR_SHIFT)) & RTC_TAR_TAR_MASK) +/*! @} */ + +/*! @name TCR - RTC Time Compensation Register */ +/*! @{ */ +#define RTC_TCR_TCR_MASK (0xFFU) +#define RTC_TCR_TCR_SHIFT (0U) +/*! TCR - Time Compensation Register + * 0b10000000..Time Prescaler Register overflows every 32896 clock cycles. + * 0b11111111..Time Prescaler Register overflows every 32769 clock cycles. + * 0b00000000..Time Prescaler Register overflows every 32768 clock cycles. + * 0b00000001..Time Prescaler Register overflows every 32767 clock cycles. + * 0b01111111..Time Prescaler Register overflows every 32641 clock cycles. + */ +#define RTC_TCR_TCR(x) (((uint32_t)(((uint32_t)(x)) << RTC_TCR_TCR_SHIFT)) & RTC_TCR_TCR_MASK) +#define RTC_TCR_CIR_MASK (0xFF00U) +#define RTC_TCR_CIR_SHIFT (8U) +#define RTC_TCR_CIR(x) (((uint32_t)(((uint32_t)(x)) << RTC_TCR_CIR_SHIFT)) & RTC_TCR_CIR_MASK) +#define RTC_TCR_TCV_MASK (0xFF0000U) +#define RTC_TCR_TCV_SHIFT (16U) +#define RTC_TCR_TCV(x) (((uint32_t)(((uint32_t)(x)) << RTC_TCR_TCV_SHIFT)) & RTC_TCR_TCV_MASK) +#define RTC_TCR_CIC_MASK (0xFF000000U) +#define RTC_TCR_CIC_SHIFT (24U) +#define RTC_TCR_CIC(x) (((uint32_t)(((uint32_t)(x)) << RTC_TCR_CIC_SHIFT)) & RTC_TCR_CIC_MASK) +/*! @} */ + +/*! @name CR - RTC Control Register */ +/*! @{ */ +#define RTC_CR_SWR_MASK (0x1U) +#define RTC_CR_SWR_SHIFT (0U) +/*! SWR - Software Reset + * 0b0..No effect. + * 0b1..Resets all RTC registers except for the SWR bit and the RTC_WAR and RTC_RAR registers . The SWR bit is cleared by VBAT POR and by software explicitly clearing it. + */ +#define RTC_CR_SWR(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SWR_SHIFT)) & RTC_CR_SWR_MASK) +#define RTC_CR_WPE_MASK (0x2U) +#define RTC_CR_WPE_SHIFT (1U) +/*! WPE - Wakeup Pin Enable + * 0b0..Wakeup pin is disabled. + * 0b1..Wakeup pin is enabled and wakeup pin asserts if the RTC interrupt asserts or the wakeup pin is turned on. + */ +#define RTC_CR_WPE(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_WPE_SHIFT)) & RTC_CR_WPE_MASK) +#define RTC_CR_SUP_MASK (0x4U) +#define RTC_CR_SUP_SHIFT (2U) +/*! SUP - Supervisor Access + * 0b0..Non-supervisor mode write accesses are not supported and generate a bus error. + * 0b1..Non-supervisor mode write accesses are supported. + */ +#define RTC_CR_SUP(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SUP_SHIFT)) & RTC_CR_SUP_MASK) +#define RTC_CR_UM_MASK (0x8U) +#define RTC_CR_UM_SHIFT (3U) +/*! UM - Update Mode + * 0b0..Registers cannot be written when locked. + * 0b1..Registers can be written when locked under limited conditions. + */ +#define RTC_CR_UM(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_UM_SHIFT)) & RTC_CR_UM_MASK) +#define RTC_CR_WPS_MASK (0x10U) +#define RTC_CR_WPS_SHIFT (4U) +/*! WPS - Wakeup Pin Select + * 0b0..Wakeup pin asserts (active low, open drain) if the RTC interrupt asserts or the wakeup pin is turned on. + * 0b1..Wakeup pin instead outputs the RTC 32kHz clock, provided the wakeup pin is turned on and the 32kHz clock is output to other peripherals. + */ +#define RTC_CR_WPS(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_WPS_SHIFT)) & RTC_CR_WPS_MASK) +#define RTC_CR_OSCE_MASK (0x100U) +#define RTC_CR_OSCE_SHIFT (8U) +/*! OSCE - Oscillator Enable + * 0b0..32.768 kHz oscillator is disabled. + * 0b1..32.768 kHz oscillator is enabled. After setting this bit, wait the oscillator startup time before enabling the time counter to allow the 32.768 kHz clock time to stabilize. + */ +#define RTC_CR_OSCE(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_OSCE_SHIFT)) & RTC_CR_OSCE_MASK) +#define RTC_CR_CLKO_MASK (0x200U) +#define RTC_CR_CLKO_SHIFT (9U) +/*! CLKO - Clock Output + * 0b0..The 32 kHz clock is output to other peripherals. + * 0b1..The 32 kHz clock is not output to other peripherals. + */ +#define RTC_CR_CLKO(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_CLKO_SHIFT)) & RTC_CR_CLKO_MASK) +#define RTC_CR_SC16P_MASK (0x400U) +#define RTC_CR_SC16P_SHIFT (10U) +/*! SC16P - Oscillator 16pF Load Configure + * 0b0..Disable the load. + * 0b1..Enable the additional load. + */ +#define RTC_CR_SC16P(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SC16P_SHIFT)) & RTC_CR_SC16P_MASK) +#define RTC_CR_SC8P_MASK (0x800U) +#define RTC_CR_SC8P_SHIFT (11U) +/*! SC8P - Oscillator 8pF Load Configure + * 0b0..Disable the load. + * 0b1..Enable the additional load. + */ +#define RTC_CR_SC8P(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SC8P_SHIFT)) & RTC_CR_SC8P_MASK) +#define RTC_CR_SC4P_MASK (0x1000U) +#define RTC_CR_SC4P_SHIFT (12U) +/*! SC4P - Oscillator 4pF Load Configure + * 0b0..Disable the load. + * 0b1..Enable the additional load. + */ +#define RTC_CR_SC4P(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SC4P_SHIFT)) & RTC_CR_SC4P_MASK) +#define RTC_CR_SC2P_MASK (0x2000U) +#define RTC_CR_SC2P_SHIFT (13U) +/*! SC2P - Oscillator 2pF Load Configure + * 0b0..Disable the load. + * 0b1..Enable the additional load. + */ +#define RTC_CR_SC2P(x) (((uint32_t)(((uint32_t)(x)) << RTC_CR_SC2P_SHIFT)) & RTC_CR_SC2P_MASK) +/*! @} */ + +/*! @name SR - RTC Status Register */ +/*! @{ */ +#define RTC_SR_TIF_MASK (0x1U) +#define RTC_SR_TIF_SHIFT (0U) +/*! TIF - Time Invalid Flag + * 0b0..Time is valid. + * 0b1..Time is invalid and time counter is read as zero. + */ +#define RTC_SR_TIF(x) (((uint32_t)(((uint32_t)(x)) << RTC_SR_TIF_SHIFT)) & RTC_SR_TIF_MASK) +#define RTC_SR_TOF_MASK (0x2U) +#define RTC_SR_TOF_SHIFT (1U) +/*! TOF - Time Overflow Flag + * 0b0..Time overflow has not occurred. + * 0b1..Time overflow has occurred and time counter is read as zero. + */ +#define RTC_SR_TOF(x) (((uint32_t)(((uint32_t)(x)) << RTC_SR_TOF_SHIFT)) & RTC_SR_TOF_MASK) +#define RTC_SR_TAF_MASK (0x4U) +#define RTC_SR_TAF_SHIFT (2U) +/*! TAF - Time Alarm Flag + * 0b0..Time alarm has not occurred. + * 0b1..Time alarm has occurred. + */ +#define RTC_SR_TAF(x) (((uint32_t)(((uint32_t)(x)) << RTC_SR_TAF_SHIFT)) & RTC_SR_TAF_MASK) +#define RTC_SR_TCE_MASK (0x10U) +#define RTC_SR_TCE_SHIFT (4U) +/*! TCE - Time Counter Enable + * 0b0..Time counter is disabled. + * 0b1..Time counter is enabled. + */ +#define RTC_SR_TCE(x) (((uint32_t)(((uint32_t)(x)) << RTC_SR_TCE_SHIFT)) & RTC_SR_TCE_MASK) +/*! @} */ + +/*! @name LR - RTC Lock Register */ +/*! @{ */ +#define RTC_LR_TCL_MASK (0x8U) +#define RTC_LR_TCL_SHIFT (3U) +/*! TCL - Time Compensation Lock + * 0b0..Time Compensation Register is locked and writes are ignored. + * 0b1..Time Compensation Register is not locked and writes complete as normal. + */ +#define RTC_LR_TCL(x) (((uint32_t)(((uint32_t)(x)) << RTC_LR_TCL_SHIFT)) & RTC_LR_TCL_MASK) +#define RTC_LR_CRL_MASK (0x10U) +#define RTC_LR_CRL_SHIFT (4U) +/*! CRL - Control Register Lock + * 0b0..Control Register is locked and writes are ignored. + * 0b1..Control Register is not locked and writes complete as normal. + */ +#define RTC_LR_CRL(x) (((uint32_t)(((uint32_t)(x)) << RTC_LR_CRL_SHIFT)) & RTC_LR_CRL_MASK) +#define RTC_LR_SRL_MASK (0x20U) +#define RTC_LR_SRL_SHIFT (5U) +/*! SRL - Status Register Lock + * 0b0..Status Register is locked and writes are ignored. + * 0b1..Status Register is not locked and writes complete as normal. + */ +#define RTC_LR_SRL(x) (((uint32_t)(((uint32_t)(x)) << RTC_LR_SRL_SHIFT)) & RTC_LR_SRL_MASK) +#define RTC_LR_LRL_MASK (0x40U) +#define RTC_LR_LRL_SHIFT (6U) +/*! LRL - Lock Register Lock + * 0b0..Lock Register is locked and writes are ignored. + * 0b1..Lock Register is not locked and writes complete as normal. + */ +#define RTC_LR_LRL(x) (((uint32_t)(((uint32_t)(x)) << RTC_LR_LRL_SHIFT)) & RTC_LR_LRL_MASK) +/*! @} */ + +/*! @name IER - RTC Interrupt Enable Register */ +/*! @{ */ +#define RTC_IER_TIIE_MASK (0x1U) +#define RTC_IER_TIIE_SHIFT (0U) +/*! TIIE - Time Invalid Interrupt Enable + * 0b0..Time invalid flag does not generate an interrupt. + * 0b1..Time invalid flag does generate an interrupt. + */ +#define RTC_IER_TIIE(x) (((uint32_t)(((uint32_t)(x)) << RTC_IER_TIIE_SHIFT)) & RTC_IER_TIIE_MASK) +#define RTC_IER_TOIE_MASK (0x2U) +#define RTC_IER_TOIE_SHIFT (1U) +/*! TOIE - Time Overflow Interrupt Enable + * 0b0..Time overflow flag does not generate an interrupt. + * 0b1..Time overflow flag does generate an interrupt. + */ +#define RTC_IER_TOIE(x) (((uint32_t)(((uint32_t)(x)) << RTC_IER_TOIE_SHIFT)) & RTC_IER_TOIE_MASK) +#define RTC_IER_TAIE_MASK (0x4U) +#define RTC_IER_TAIE_SHIFT (2U) +/*! TAIE - Time Alarm Interrupt Enable + * 0b0..Time alarm flag does not generate an interrupt. + * 0b1..Time alarm flag does generate an interrupt. + */ +#define RTC_IER_TAIE(x) (((uint32_t)(((uint32_t)(x)) << RTC_IER_TAIE_SHIFT)) & RTC_IER_TAIE_MASK) +#define RTC_IER_TSIE_MASK (0x10U) +#define RTC_IER_TSIE_SHIFT (4U) +/*! TSIE - Time Seconds Interrupt Enable + * 0b0..Seconds interrupt is disabled. + * 0b1..Seconds interrupt is enabled. + */ +#define RTC_IER_TSIE(x) (((uint32_t)(((uint32_t)(x)) << RTC_IER_TSIE_SHIFT)) & RTC_IER_TSIE_MASK) +#define RTC_IER_WPON_MASK (0x80U) +#define RTC_IER_WPON_SHIFT (7U) +/*! WPON - Wakeup Pin On + * 0b0..No effect. + * 0b1..If the wakeup pin is enabled, then the wakeup pin will assert. + */ +#define RTC_IER_WPON(x) (((uint32_t)(((uint32_t)(x)) << RTC_IER_WPON_SHIFT)) & RTC_IER_WPON_MASK) +/*! @} */ + +/*! @name WAR - RTC Write Access Register */ +/*! @{ */ +#define RTC_WAR_TSRW_MASK (0x1U) +#define RTC_WAR_TSRW_SHIFT (0U) +/*! TSRW - Time Seconds Register Write + * 0b0..Writes to the Time Seconds Register are ignored. + * 0b1..Writes to the Time Seconds Register complete as normal. + */ +#define RTC_WAR_TSRW(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAR_TSRW_SHIFT)) & RTC_WAR_TSRW_MASK) +#define RTC_WAR_TPRW_MASK (0x2U) +#define RTC_WAR_TPRW_SHIFT (1U) +/*! TPRW - Time Prescaler Register Write + * 0b0..Writes to the Time Prescaler Register are ignored. + * 0b1..Writes to the Time Prescaler Register complete as normal. + */ +#define RTC_WAR_TPRW(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAR_TPRW_SHIFT)) & RTC_WAR_TPRW_MASK) +#define RTC_WAR_TARW_MASK (0x4U) +#define RTC_WAR_TARW_SHIFT (2U) +/*! TARW - Time Alarm Register Write + * 0b0..Writes to the Time Alarm Register are ignored. + * 0b1..Writes to the Time Alarm Register complete as normal. + */ +#define RTC_WAR_TARW(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAR_TARW_SHIFT)) & RTC_WAR_TARW_MASK) +#define RTC_WAR_TCRW_MASK (0x8U) +#define RTC_WAR_TCRW_SHIFT (3U) +/*! TCRW - Time Compensation Register Write + * 0b0..Writes to the Time Compensation Register are ignored. + * 0b1..Writes to the Time Compensation Register complete as normal. + */ +#define RTC_WAR_TCRW(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAR_TCRW_SHIFT)) & RTC_WAR_TCRW_MASK) +#define RTC_WAR_CRW_MASK (0x10U) +#define RTC_WAR_CRW_SHIFT (4U) +/*! CRW - Control Register Write + * 0b0..Writes to the Control Register are ignored. + * 0b1..Writes to the Control Register complete as normal. + */ +#define RTC_WAR_CRW(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAR_CRW_SHIFT)) & RTC_WAR_CRW_MASK) +#define RTC_WAR_SRW_MASK (0x20U) +#define RTC_WAR_SRW_SHIFT (5U) +/*! SRW - Status Register Write + * 0b0..Writes to the Status Register are ignored. + * 0b1..Writes to the Status Register complete as normal. + */ +#define RTC_WAR_SRW(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAR_SRW_SHIFT)) & RTC_WAR_SRW_MASK) +#define RTC_WAR_LRW_MASK (0x40U) +#define RTC_WAR_LRW_SHIFT (6U) +/*! LRW - Lock Register Write + * 0b0..Writes to the Lock Register are ignored. + * 0b1..Writes to the Lock Register complete as normal. + */ +#define RTC_WAR_LRW(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAR_LRW_SHIFT)) & RTC_WAR_LRW_MASK) +#define RTC_WAR_IERW_MASK (0x80U) +#define RTC_WAR_IERW_SHIFT (7U) +/*! IERW - Interrupt Enable Register Write + * 0b0..Writes to the Interupt Enable Register are ignored. + * 0b1..Writes to the Interrupt Enable Register complete as normal. + */ +#define RTC_WAR_IERW(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAR_IERW_SHIFT)) & RTC_WAR_IERW_MASK) +/*! @} */ + +/*! @name RAR - RTC Read Access Register */ +/*! @{ */ +#define RTC_RAR_TSRR_MASK (0x1U) +#define RTC_RAR_TSRR_SHIFT (0U) +/*! TSRR - Time Seconds Register Read + * 0b0..Reads to the Time Seconds Register are ignored. + * 0b1..Reads to the Time Seconds Register complete as normal. + */ +#define RTC_RAR_TSRR(x) (((uint32_t)(((uint32_t)(x)) << RTC_RAR_TSRR_SHIFT)) & RTC_RAR_TSRR_MASK) +#define RTC_RAR_TPRR_MASK (0x2U) +#define RTC_RAR_TPRR_SHIFT (1U) +/*! TPRR - Time Prescaler Register Read + * 0b0..Reads to the Time Pprescaler Register are ignored. + * 0b1..Reads to the Time Prescaler Register complete as normal. + */ +#define RTC_RAR_TPRR(x) (((uint32_t)(((uint32_t)(x)) << RTC_RAR_TPRR_SHIFT)) & RTC_RAR_TPRR_MASK) +#define RTC_RAR_TARR_MASK (0x4U) +#define RTC_RAR_TARR_SHIFT (2U) +/*! TARR - Time Alarm Register Read + * 0b0..Reads to the Time Alarm Register are ignored. + * 0b1..Reads to the Time Alarm Register complete as normal. + */ +#define RTC_RAR_TARR(x) (((uint32_t)(((uint32_t)(x)) << RTC_RAR_TARR_SHIFT)) & RTC_RAR_TARR_MASK) +#define RTC_RAR_TCRR_MASK (0x8U) +#define RTC_RAR_TCRR_SHIFT (3U) +/*! TCRR - Time Compensation Register Read + * 0b0..Reads to the Time Compensation Register are ignored. + * 0b1..Reads to the Time Compensation Register complete as normal. + */ +#define RTC_RAR_TCRR(x) (((uint32_t)(((uint32_t)(x)) << RTC_RAR_TCRR_SHIFT)) & RTC_RAR_TCRR_MASK) +#define RTC_RAR_CRR_MASK (0x10U) +#define RTC_RAR_CRR_SHIFT (4U) +/*! CRR - Control Register Read + * 0b0..Reads to the Control Register are ignored. + * 0b1..Reads to the Control Register complete as normal. + */ +#define RTC_RAR_CRR(x) (((uint32_t)(((uint32_t)(x)) << RTC_RAR_CRR_SHIFT)) & RTC_RAR_CRR_MASK) +#define RTC_RAR_SRR_MASK (0x20U) +#define RTC_RAR_SRR_SHIFT (5U) +/*! SRR - Status Register Read + * 0b0..Reads to the Status Register are ignored. + * 0b1..Reads to the Status Register complete as normal. + */ +#define RTC_RAR_SRR(x) (((uint32_t)(((uint32_t)(x)) << RTC_RAR_SRR_SHIFT)) & RTC_RAR_SRR_MASK) +#define RTC_RAR_LRR_MASK (0x40U) +#define RTC_RAR_LRR_SHIFT (6U) +/*! LRR - Lock Register Read + * 0b0..Reads to the Lock Register are ignored. + * 0b1..Reads to the Lock Register complete as normal. + */ +#define RTC_RAR_LRR(x) (((uint32_t)(((uint32_t)(x)) << RTC_RAR_LRR_SHIFT)) & RTC_RAR_LRR_MASK) +#define RTC_RAR_IERR_MASK (0x80U) +#define RTC_RAR_IERR_SHIFT (7U) +/*! IERR - Interrupt Enable Register Read + * 0b0..Reads to the Interrupt Enable Register are ignored. + * 0b1..Reads to the Interrupt Enable Register complete as normal. + */ +#define RTC_RAR_IERR(x) (((uint32_t)(((uint32_t)(x)) << RTC_RAR_IERR_SHIFT)) & RTC_RAR_IERR_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group RTC_Register_Masks */ + + +/* RTC - Peripheral instance base addresses */ +/** Peripheral RTC base address */ +#define RTC_BASE (0x4003D000u) +/** Peripheral RTC base pointer */ +#define RTC ((RTC_Type *)RTC_BASE) +/** Array initializer of RTC peripheral base addresses */ +#define RTC_BASE_ADDRS { RTC_BASE } +/** Array initializer of RTC peripheral base pointers */ +#define RTC_BASE_PTRS { RTC } +/** Interrupt vectors for the RTC peripheral type */ +#define RTC_IRQS { RTC_IRQn } +#define RTC_SECONDS_IRQS { RTC_Seconds_IRQn } + +/*! + * @} + */ /* end of group RTC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SDHC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SDHC_Peripheral_Access_Layer SDHC Peripheral Access Layer + * @{ + */ + +/** SDHC - Register Layout Typedef */ +typedef struct { + __IO uint32_t DSADDR; /**< DMA System Address register, offset: 0x0 */ + __IO uint32_t BLKATTR; /**< Block Attributes register, offset: 0x4 */ + __IO uint32_t CMDARG; /**< Command Argument register, offset: 0x8 */ + __IO uint32_t XFERTYP; /**< Transfer Type register, offset: 0xC */ + __I uint32_t CMDRSP[4]; /**< Command Response 0..Command Response 3, array offset: 0x10, array step: 0x4 */ + __IO uint32_t DATPORT; /**< Buffer Data Port register, offset: 0x20 */ + __I uint32_t PRSSTAT; /**< Present State register, offset: 0x24 */ + __IO uint32_t PROCTL; /**< Protocol Control register, offset: 0x28 */ + __IO uint32_t SYSCTL; /**< System Control register, offset: 0x2C */ + __IO uint32_t IRQSTAT; /**< Interrupt Status register, offset: 0x30 */ + __IO uint32_t IRQSTATEN; /**< Interrupt Status Enable register, offset: 0x34 */ + __IO uint32_t IRQSIGEN; /**< Interrupt Signal Enable register, offset: 0x38 */ + __I uint32_t AC12ERR; /**< Auto CMD12 Error Status Register, offset: 0x3C */ + __I uint32_t HTCAPBLT; /**< Host Controller Capabilities, offset: 0x40 */ + __IO uint32_t WML; /**< Watermark Level Register, offset: 0x44 */ + uint8_t RESERVED_0[8]; + __O uint32_t FEVT; /**< Force Event register, offset: 0x50 */ + __I uint32_t ADMAES; /**< ADMA Error Status register, offset: 0x54 */ + __IO uint32_t ADSADDR; /**< ADMA System Addressregister, offset: 0x58 */ + uint8_t RESERVED_1[100]; + __IO uint32_t VENDOR; /**< Vendor Specific register, offset: 0xC0 */ + __IO uint32_t MMCBOOT; /**< MMC Boot register, offset: 0xC4 */ + uint8_t RESERVED_2[52]; + __I uint32_t HOSTVER; /**< Host Controller Version, offset: 0xFC */ +} SDHC_Type; + +/* ---------------------------------------------------------------------------- + -- SDHC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SDHC_Register_Masks SDHC Register Masks + * @{ + */ + +/*! @name DSADDR - DMA System Address register */ +/*! @{ */ +#define SDHC_DSADDR_DSADDR_MASK (0xFFFFFFFCU) +#define SDHC_DSADDR_DSADDR_SHIFT (2U) +#define SDHC_DSADDR_DSADDR(x) (((uint32_t)(((uint32_t)(x)) << SDHC_DSADDR_DSADDR_SHIFT)) & SDHC_DSADDR_DSADDR_MASK) +/*! @} */ + +/*! @name BLKATTR - Block Attributes register */ +/*! @{ */ +#define SDHC_BLKATTR_BLKSIZE_MASK (0x1FFFU) +#define SDHC_BLKATTR_BLKSIZE_SHIFT (0U) +/*! BLKSIZE - Transfer Block Size + * 0b0000000000000..No data transfer. + * 0b0000000000001..1 Byte + * 0b0000000000010..2 Bytes + * 0b0000000000011..3 Bytes + * 0b0000000000100..4 Bytes + * 0b0000111111111..511 Bytes + * 0b0001000000000..512 Bytes + * 0b0100000000000..2048 Bytes + * 0b1000000000000..4096 Bytes + */ +#define SDHC_BLKATTR_BLKSIZE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_BLKATTR_BLKSIZE_SHIFT)) & SDHC_BLKATTR_BLKSIZE_MASK) +#define SDHC_BLKATTR_BLKCNT_MASK (0xFFFF0000U) +#define SDHC_BLKATTR_BLKCNT_SHIFT (16U) +/*! BLKCNT - Blocks Count For Current Transfer + * 0b0000000000000000..Stop count. + * 0b0000000000000001..1 block + * 0b0000000000000010..2 blocks + * 0b1111111111111111..65535 blocks + */ +#define SDHC_BLKATTR_BLKCNT(x) (((uint32_t)(((uint32_t)(x)) << SDHC_BLKATTR_BLKCNT_SHIFT)) & SDHC_BLKATTR_BLKCNT_MASK) +/*! @} */ + +/*! @name CMDARG - Command Argument register */ +/*! @{ */ +#define SDHC_CMDARG_CMDARG_MASK (0xFFFFFFFFU) +#define SDHC_CMDARG_CMDARG_SHIFT (0U) +#define SDHC_CMDARG_CMDARG(x) (((uint32_t)(((uint32_t)(x)) << SDHC_CMDARG_CMDARG_SHIFT)) & SDHC_CMDARG_CMDARG_MASK) +/*! @} */ + +/*! @name XFERTYP - Transfer Type register */ +/*! @{ */ +#define SDHC_XFERTYP_DMAEN_MASK (0x1U) +#define SDHC_XFERTYP_DMAEN_SHIFT (0U) +/*! DMAEN - DMA Enable + * 0b0..Disable + * 0b1..Enable + */ +#define SDHC_XFERTYP_DMAEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_DMAEN_SHIFT)) & SDHC_XFERTYP_DMAEN_MASK) +#define SDHC_XFERTYP_BCEN_MASK (0x2U) +#define SDHC_XFERTYP_BCEN_SHIFT (1U) +/*! BCEN - Block Count Enable + * 0b0..Disable + * 0b1..Enable + */ +#define SDHC_XFERTYP_BCEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_BCEN_SHIFT)) & SDHC_XFERTYP_BCEN_MASK) +#define SDHC_XFERTYP_AC12EN_MASK (0x4U) +#define SDHC_XFERTYP_AC12EN_SHIFT (2U) +/*! AC12EN - Auto CMD12 Enable + * 0b0..Disable + * 0b1..Enable + */ +#define SDHC_XFERTYP_AC12EN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_AC12EN_SHIFT)) & SDHC_XFERTYP_AC12EN_MASK) +#define SDHC_XFERTYP_DTDSEL_MASK (0x10U) +#define SDHC_XFERTYP_DTDSEL_SHIFT (4U) +/*! DTDSEL - Data Transfer Direction Select + * 0b0..Write host to card. + * 0b1..Read card to host. + */ +#define SDHC_XFERTYP_DTDSEL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_DTDSEL_SHIFT)) & SDHC_XFERTYP_DTDSEL_MASK) +#define SDHC_XFERTYP_MSBSEL_MASK (0x20U) +#define SDHC_XFERTYP_MSBSEL_SHIFT (5U) +/*! MSBSEL - Multi/Single Block Select + * 0b0..Single block. + * 0b1..Multiple blocks. + */ +#define SDHC_XFERTYP_MSBSEL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_MSBSEL_SHIFT)) & SDHC_XFERTYP_MSBSEL_MASK) +#define SDHC_XFERTYP_RSPTYP_MASK (0x30000U) +#define SDHC_XFERTYP_RSPTYP_SHIFT (16U) +/*! RSPTYP - Response Type Select + * 0b00..No response. + * 0b01..Response length 136. + * 0b10..Response length 48. + * 0b11..Response length 48, check busy after response. + */ +#define SDHC_XFERTYP_RSPTYP(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_RSPTYP_SHIFT)) & SDHC_XFERTYP_RSPTYP_MASK) +#define SDHC_XFERTYP_CCCEN_MASK (0x80000U) +#define SDHC_XFERTYP_CCCEN_SHIFT (19U) +/*! CCCEN - Command CRC Check Enable + * 0b0..Disable + * 0b1..Enable + */ +#define SDHC_XFERTYP_CCCEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_CCCEN_SHIFT)) & SDHC_XFERTYP_CCCEN_MASK) +#define SDHC_XFERTYP_CICEN_MASK (0x100000U) +#define SDHC_XFERTYP_CICEN_SHIFT (20U) +/*! CICEN - Command Index Check Enable + * 0b0..Disable + * 0b1..Enable + */ +#define SDHC_XFERTYP_CICEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_CICEN_SHIFT)) & SDHC_XFERTYP_CICEN_MASK) +#define SDHC_XFERTYP_DPSEL_MASK (0x200000U) +#define SDHC_XFERTYP_DPSEL_SHIFT (21U) +/*! DPSEL - Data Present Select + * 0b0..No data present. + * 0b1..Data present. + */ +#define SDHC_XFERTYP_DPSEL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_DPSEL_SHIFT)) & SDHC_XFERTYP_DPSEL_MASK) +#define SDHC_XFERTYP_CMDTYP_MASK (0xC00000U) +#define SDHC_XFERTYP_CMDTYP_SHIFT (22U) +/*! CMDTYP - Command Type + * 0b00..Normal other commands. + * 0b01..Suspend CMD52 for writing bus suspend in CCCR. + * 0b10..Resume CMD52 for writing function select in CCCR. + * 0b11..Abort CMD12, CMD52 for writing I/O abort in CCCR. + */ +#define SDHC_XFERTYP_CMDTYP(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_CMDTYP_SHIFT)) & SDHC_XFERTYP_CMDTYP_MASK) +#define SDHC_XFERTYP_CMDINX_MASK (0x3F000000U) +#define SDHC_XFERTYP_CMDINX_SHIFT (24U) +#define SDHC_XFERTYP_CMDINX(x) (((uint32_t)(((uint32_t)(x)) << SDHC_XFERTYP_CMDINX_SHIFT)) & SDHC_XFERTYP_CMDINX_MASK) +/*! @} */ + +/*! @name CMDRSP - Command Response 0..Command Response 3 */ +/*! @{ */ +#define SDHC_CMDRSP_CMDRSP0_MASK (0xFFFFFFFFU) +#define SDHC_CMDRSP_CMDRSP0_SHIFT (0U) +#define SDHC_CMDRSP_CMDRSP0(x) (((uint32_t)(((uint32_t)(x)) << SDHC_CMDRSP_CMDRSP0_SHIFT)) & SDHC_CMDRSP_CMDRSP0_MASK) +#define SDHC_CMDRSP_CMDRSP1_MASK (0xFFFFFFFFU) +#define SDHC_CMDRSP_CMDRSP1_SHIFT (0U) +#define SDHC_CMDRSP_CMDRSP1(x) (((uint32_t)(((uint32_t)(x)) << SDHC_CMDRSP_CMDRSP1_SHIFT)) & SDHC_CMDRSP_CMDRSP1_MASK) +#define SDHC_CMDRSP_CMDRSP2_MASK (0xFFFFFFFFU) +#define SDHC_CMDRSP_CMDRSP2_SHIFT (0U) +#define SDHC_CMDRSP_CMDRSP2(x) (((uint32_t)(((uint32_t)(x)) << SDHC_CMDRSP_CMDRSP2_SHIFT)) & SDHC_CMDRSP_CMDRSP2_MASK) +#define SDHC_CMDRSP_CMDRSP3_MASK (0xFFFFFFFFU) +#define SDHC_CMDRSP_CMDRSP3_SHIFT (0U) +#define SDHC_CMDRSP_CMDRSP3(x) (((uint32_t)(((uint32_t)(x)) << SDHC_CMDRSP_CMDRSP3_SHIFT)) & SDHC_CMDRSP_CMDRSP3_MASK) +/*! @} */ + +/* The count of SDHC_CMDRSP */ +#define SDHC_CMDRSP_COUNT (4U) + +/*! @name DATPORT - Buffer Data Port register */ +/*! @{ */ +#define SDHC_DATPORT_DATCONT_MASK (0xFFFFFFFFU) +#define SDHC_DATPORT_DATCONT_SHIFT (0U) +#define SDHC_DATPORT_DATCONT(x) (((uint32_t)(((uint32_t)(x)) << SDHC_DATPORT_DATCONT_SHIFT)) & SDHC_DATPORT_DATCONT_MASK) +/*! @} */ + +/*! @name PRSSTAT - Present State register */ +/*! @{ */ +#define SDHC_PRSSTAT_CIHB_MASK (0x1U) +#define SDHC_PRSSTAT_CIHB_SHIFT (0U) +/*! CIHB - Command Inhibit (CMD) + * 0b0..Can issue command using only CMD line. + * 0b1..Cannot issue command. + */ +#define SDHC_PRSSTAT_CIHB(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_CIHB_SHIFT)) & SDHC_PRSSTAT_CIHB_MASK) +#define SDHC_PRSSTAT_CDIHB_MASK (0x2U) +#define SDHC_PRSSTAT_CDIHB_SHIFT (1U) +/*! CDIHB - Command Inhibit (DAT) + * 0b0..Can issue command which uses the DAT line. + * 0b1..Cannot issue command which uses the DAT line. + */ +#define SDHC_PRSSTAT_CDIHB(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_CDIHB_SHIFT)) & SDHC_PRSSTAT_CDIHB_MASK) +#define SDHC_PRSSTAT_DLA_MASK (0x4U) +#define SDHC_PRSSTAT_DLA_SHIFT (2U) +/*! DLA - Data Line Active + * 0b0..DAT line inactive. + * 0b1..DAT line active. + */ +#define SDHC_PRSSTAT_DLA(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_DLA_SHIFT)) & SDHC_PRSSTAT_DLA_MASK) +#define SDHC_PRSSTAT_SDSTB_MASK (0x8U) +#define SDHC_PRSSTAT_SDSTB_SHIFT (3U) +/*! SDSTB - SD Clock Stable + * 0b0..Clock is changing frequency and not stable. + * 0b1..Clock is stable. + */ +#define SDHC_PRSSTAT_SDSTB(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_SDSTB_SHIFT)) & SDHC_PRSSTAT_SDSTB_MASK) +#define SDHC_PRSSTAT_IPGOFF_MASK (0x10U) +#define SDHC_PRSSTAT_IPGOFF_SHIFT (4U) +/*! IPGOFF - Bus Clock Gated Off Internally + * 0b0..Bus clock is active. + * 0b1..Bus clock is gated off. + */ +#define SDHC_PRSSTAT_IPGOFF(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_IPGOFF_SHIFT)) & SDHC_PRSSTAT_IPGOFF_MASK) +#define SDHC_PRSSTAT_HCKOFF_MASK (0x20U) +#define SDHC_PRSSTAT_HCKOFF_SHIFT (5U) +/*! HCKOFF - System Clock Gated Off Internally + * 0b0..System clock is active. + * 0b1..System clock is gated off. + */ +#define SDHC_PRSSTAT_HCKOFF(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_HCKOFF_SHIFT)) & SDHC_PRSSTAT_HCKOFF_MASK) +#define SDHC_PRSSTAT_PEROFF_MASK (0x40U) +#define SDHC_PRSSTAT_PEROFF_SHIFT (6U) +/*! PEROFF - SDHC clock Gated Off Internally + * 0b0..SDHC clock is active. + * 0b1..SDHC clock is gated off. + */ +#define SDHC_PRSSTAT_PEROFF(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_PEROFF_SHIFT)) & SDHC_PRSSTAT_PEROFF_MASK) +#define SDHC_PRSSTAT_SDOFF_MASK (0x80U) +#define SDHC_PRSSTAT_SDOFF_SHIFT (7U) +/*! SDOFF - SD Clock Gated Off Internally + * 0b0..SD clock is active. + * 0b1..SD clock is gated off. + */ +#define SDHC_PRSSTAT_SDOFF(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_SDOFF_SHIFT)) & SDHC_PRSSTAT_SDOFF_MASK) +#define SDHC_PRSSTAT_WTA_MASK (0x100U) +#define SDHC_PRSSTAT_WTA_SHIFT (8U) +/*! WTA - Write Transfer Active + * 0b0..No valid data. + * 0b1..Transferring data. + */ +#define SDHC_PRSSTAT_WTA(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_WTA_SHIFT)) & SDHC_PRSSTAT_WTA_MASK) +#define SDHC_PRSSTAT_RTA_MASK (0x200U) +#define SDHC_PRSSTAT_RTA_SHIFT (9U) +/*! RTA - Read Transfer Active + * 0b0..No valid data. + * 0b1..Transferring data. + */ +#define SDHC_PRSSTAT_RTA(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_RTA_SHIFT)) & SDHC_PRSSTAT_RTA_MASK) +#define SDHC_PRSSTAT_BWEN_MASK (0x400U) +#define SDHC_PRSSTAT_BWEN_SHIFT (10U) +/*! BWEN - Buffer Write Enable + * 0b0..Write disable, the buffer can hold valid data less than the write watermark level. + * 0b1..Write enable, the buffer can hold valid data greater than the write watermark level. + */ +#define SDHC_PRSSTAT_BWEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_BWEN_SHIFT)) & SDHC_PRSSTAT_BWEN_MASK) +#define SDHC_PRSSTAT_BREN_MASK (0x800U) +#define SDHC_PRSSTAT_BREN_SHIFT (11U) +/*! BREN - Buffer Read Enable + * 0b0..Read disable, valid data less than the watermark level exist in the buffer. + * 0b1..Read enable, valid data greater than the watermark level exist in the buffer. + */ +#define SDHC_PRSSTAT_BREN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_BREN_SHIFT)) & SDHC_PRSSTAT_BREN_MASK) +#define SDHC_PRSSTAT_CINS_MASK (0x10000U) +#define SDHC_PRSSTAT_CINS_SHIFT (16U) +/*! CINS - Card Inserted + * 0b0..Power on reset or no card. + * 0b1..Card inserted. + */ +#define SDHC_PRSSTAT_CINS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_CINS_SHIFT)) & SDHC_PRSSTAT_CINS_MASK) +#define SDHC_PRSSTAT_CLSL_MASK (0x800000U) +#define SDHC_PRSSTAT_CLSL_SHIFT (23U) +#define SDHC_PRSSTAT_CLSL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_CLSL_SHIFT)) & SDHC_PRSSTAT_CLSL_MASK) +#define SDHC_PRSSTAT_DLSL_MASK (0xFF000000U) +#define SDHC_PRSSTAT_DLSL_SHIFT (24U) +#define SDHC_PRSSTAT_DLSL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PRSSTAT_DLSL_SHIFT)) & SDHC_PRSSTAT_DLSL_MASK) +/*! @} */ + +/*! @name PROCTL - Protocol Control register */ +/*! @{ */ +#define SDHC_PROCTL_LCTL_MASK (0x1U) +#define SDHC_PROCTL_LCTL_SHIFT (0U) +/*! LCTL - LED Control + * 0b0..LED off. + * 0b1..LED on. + */ +#define SDHC_PROCTL_LCTL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_LCTL_SHIFT)) & SDHC_PROCTL_LCTL_MASK) +#define SDHC_PROCTL_DTW_MASK (0x6U) +#define SDHC_PROCTL_DTW_SHIFT (1U) +/*! DTW - Data Transfer Width + * 0b00..1-bit mode + * 0b01..4-bit mode + * 0b10..8-bit mode + * 0b11..Reserved + */ +#define SDHC_PROCTL_DTW(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_DTW_SHIFT)) & SDHC_PROCTL_DTW_MASK) +#define SDHC_PROCTL_D3CD_MASK (0x8U) +#define SDHC_PROCTL_D3CD_SHIFT (3U) +/*! D3CD - DAT3 As Card Detection Pin + * 0b0..DAT3 does not monitor card Insertion. + * 0b1..DAT3 as card detection pin. + */ +#define SDHC_PROCTL_D3CD(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_D3CD_SHIFT)) & SDHC_PROCTL_D3CD_MASK) +#define SDHC_PROCTL_EMODE_MASK (0x30U) +#define SDHC_PROCTL_EMODE_SHIFT (4U) +/*! EMODE - Endian Mode + * 0b00..Big endian mode + * 0b01..Half word big endian mode + * 0b10..Little endian mode + * 0b11..Reserved + */ +#define SDHC_PROCTL_EMODE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_EMODE_SHIFT)) & SDHC_PROCTL_EMODE_MASK) +#define SDHC_PROCTL_CDTL_MASK (0x40U) +#define SDHC_PROCTL_CDTL_SHIFT (6U) +/*! CDTL - Card Detect Test Level + * 0b0..Card detect test level is 0, no card inserted. + * 0b1..Card detect test level is 1, card inserted. + */ +#define SDHC_PROCTL_CDTL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_CDTL_SHIFT)) & SDHC_PROCTL_CDTL_MASK) +#define SDHC_PROCTL_CDSS_MASK (0x80U) +#define SDHC_PROCTL_CDSS_SHIFT (7U) +/*! CDSS - Card Detect Signal Selection + * 0b0..Card detection level is selected for normal purpose. + * 0b1..Card detection test level is selected for test purpose. + */ +#define SDHC_PROCTL_CDSS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_CDSS_SHIFT)) & SDHC_PROCTL_CDSS_MASK) +#define SDHC_PROCTL_DMAS_MASK (0x300U) +#define SDHC_PROCTL_DMAS_SHIFT (8U) +/*! DMAS - DMA Select + * 0b00..No DMA or simple DMA is selected. + * 0b01..ADMA1 is selected. + * 0b10..ADMA2 is selected. + * 0b11..Reserved + */ +#define SDHC_PROCTL_DMAS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_DMAS_SHIFT)) & SDHC_PROCTL_DMAS_MASK) +#define SDHC_PROCTL_SABGREQ_MASK (0x10000U) +#define SDHC_PROCTL_SABGREQ_SHIFT (16U) +/*! SABGREQ - Stop At Block Gap Request + * 0b0..Transfer + * 0b1..Stop + */ +#define SDHC_PROCTL_SABGREQ(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_SABGREQ_SHIFT)) & SDHC_PROCTL_SABGREQ_MASK) +#define SDHC_PROCTL_CREQ_MASK (0x20000U) +#define SDHC_PROCTL_CREQ_SHIFT (17U) +/*! CREQ - Continue Request + * 0b0..No effect. + * 0b1..Restart + */ +#define SDHC_PROCTL_CREQ(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_CREQ_SHIFT)) & SDHC_PROCTL_CREQ_MASK) +#define SDHC_PROCTL_RWCTL_MASK (0x40000U) +#define SDHC_PROCTL_RWCTL_SHIFT (18U) +/*! RWCTL - Read Wait Control + * 0b0..Disable read wait control, and stop SD clock at block gap when SABGREQ is set. + * 0b1..Enable read wait control, and assert read wait without stopping SD clock at block gap when SABGREQ bit is set. + */ +#define SDHC_PROCTL_RWCTL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_RWCTL_SHIFT)) & SDHC_PROCTL_RWCTL_MASK) +#define SDHC_PROCTL_IABG_MASK (0x80000U) +#define SDHC_PROCTL_IABG_SHIFT (19U) +/*! IABG - Interrupt At Block Gap + * 0b0..Disabled + * 0b1..Enabled + */ +#define SDHC_PROCTL_IABG(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_IABG_SHIFT)) & SDHC_PROCTL_IABG_MASK) +#define SDHC_PROCTL_WECINT_MASK (0x1000000U) +#define SDHC_PROCTL_WECINT_SHIFT (24U) +/*! WECINT - Wakeup Event Enable On Card Interrupt + * 0b0..Disabled + * 0b1..Enabled + */ +#define SDHC_PROCTL_WECINT(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_WECINT_SHIFT)) & SDHC_PROCTL_WECINT_MASK) +#define SDHC_PROCTL_WECINS_MASK (0x2000000U) +#define SDHC_PROCTL_WECINS_SHIFT (25U) +/*! WECINS - Wakeup Event Enable On SD Card Insertion + * 0b0..Disabled + * 0b1..Enabled + */ +#define SDHC_PROCTL_WECINS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_WECINS_SHIFT)) & SDHC_PROCTL_WECINS_MASK) +#define SDHC_PROCTL_WECRM_MASK (0x4000000U) +#define SDHC_PROCTL_WECRM_SHIFT (26U) +/*! WECRM - Wakeup Event Enable On SD Card Removal + * 0b0..Disabled + * 0b1..Enabled + */ +#define SDHC_PROCTL_WECRM(x) (((uint32_t)(((uint32_t)(x)) << SDHC_PROCTL_WECRM_SHIFT)) & SDHC_PROCTL_WECRM_MASK) +/*! @} */ + +/*! @name SYSCTL - System Control register */ +/*! @{ */ +#define SDHC_SYSCTL_IPGEN_MASK (0x1U) +#define SDHC_SYSCTL_IPGEN_SHIFT (0U) +/*! IPGEN - IPG Clock Enable + * 0b0..Bus clock will be internally gated off. + * 0b1..Bus clock will not be automatically gated off. + */ +#define SDHC_SYSCTL_IPGEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_IPGEN_SHIFT)) & SDHC_SYSCTL_IPGEN_MASK) +#define SDHC_SYSCTL_HCKEN_MASK (0x2U) +#define SDHC_SYSCTL_HCKEN_SHIFT (1U) +/*! HCKEN - System Clock Enable + * 0b0..System clock will be internally gated off. + * 0b1..System clock will not be automatically gated off. + */ +#define SDHC_SYSCTL_HCKEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_HCKEN_SHIFT)) & SDHC_SYSCTL_HCKEN_MASK) +#define SDHC_SYSCTL_PEREN_MASK (0x4U) +#define SDHC_SYSCTL_PEREN_SHIFT (2U) +/*! PEREN - Peripheral Clock Enable + * 0b0..SDHC clock will be internally gated off. + * 0b1..SDHC clock will not be automatically gated off. + */ +#define SDHC_SYSCTL_PEREN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_PEREN_SHIFT)) & SDHC_SYSCTL_PEREN_MASK) +#define SDHC_SYSCTL_SDCLKEN_MASK (0x8U) +#define SDHC_SYSCTL_SDCLKEN_SHIFT (3U) +#define SDHC_SYSCTL_SDCLKEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_SDCLKEN_SHIFT)) & SDHC_SYSCTL_SDCLKEN_MASK) +#define SDHC_SYSCTL_DVS_MASK (0xF0U) +#define SDHC_SYSCTL_DVS_SHIFT (4U) +/*! DVS - Divisor + * 0b0000..Divisor by 1. + * 0b0001..Divisor by 2. + * 0b1110..Divisor by 15. + * 0b1111..Divisor by 16. + */ +#define SDHC_SYSCTL_DVS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_DVS_SHIFT)) & SDHC_SYSCTL_DVS_MASK) +#define SDHC_SYSCTL_SDCLKFS_MASK (0xFF00U) +#define SDHC_SYSCTL_SDCLKFS_SHIFT (8U) +/*! SDCLKFS - SDCLK Frequency Select + * 0b00000001..Base clock divided by 2. + * 0b00000010..Base clock divided by 4. + * 0b00000100..Base clock divided by 8. + * 0b00001000..Base clock divided by 16. + * 0b00010000..Base clock divided by 32. + * 0b00100000..Base clock divided by 64. + * 0b01000000..Base clock divided by 128. + * 0b10000000..Base clock divided by 256. + */ +#define SDHC_SYSCTL_SDCLKFS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_SDCLKFS_SHIFT)) & SDHC_SYSCTL_SDCLKFS_MASK) +#define SDHC_SYSCTL_DTOCV_MASK (0xF0000U) +#define SDHC_SYSCTL_DTOCV_SHIFT (16U) +/*! DTOCV - Data Timeout Counter Value + * 0b0000..SDCLK x 2 13 + * 0b0001..SDCLK x 2 14 + * 0b1110..SDCLK x 2 27 + * 0b1111..Reserved + */ +#define SDHC_SYSCTL_DTOCV(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_DTOCV_SHIFT)) & SDHC_SYSCTL_DTOCV_MASK) +#define SDHC_SYSCTL_RSTA_MASK (0x1000000U) +#define SDHC_SYSCTL_RSTA_SHIFT (24U) +/*! RSTA - Software Reset For ALL + * 0b0..No reset. + * 0b1..Reset. + */ +#define SDHC_SYSCTL_RSTA(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_RSTA_SHIFT)) & SDHC_SYSCTL_RSTA_MASK) +#define SDHC_SYSCTL_RSTC_MASK (0x2000000U) +#define SDHC_SYSCTL_RSTC_SHIFT (25U) +/*! RSTC - Software Reset For CMD Line + * 0b0..No reset. + * 0b1..Reset. + */ +#define SDHC_SYSCTL_RSTC(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_RSTC_SHIFT)) & SDHC_SYSCTL_RSTC_MASK) +#define SDHC_SYSCTL_RSTD_MASK (0x4000000U) +#define SDHC_SYSCTL_RSTD_SHIFT (26U) +/*! RSTD - Software Reset For DAT Line + * 0b0..No reset. + * 0b1..Reset. + */ +#define SDHC_SYSCTL_RSTD(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_RSTD_SHIFT)) & SDHC_SYSCTL_RSTD_MASK) +#define SDHC_SYSCTL_INITA_MASK (0x8000000U) +#define SDHC_SYSCTL_INITA_SHIFT (27U) +#define SDHC_SYSCTL_INITA(x) (((uint32_t)(((uint32_t)(x)) << SDHC_SYSCTL_INITA_SHIFT)) & SDHC_SYSCTL_INITA_MASK) +/*! @} */ + +/*! @name IRQSTAT - Interrupt Status register */ +/*! @{ */ +#define SDHC_IRQSTAT_CC_MASK (0x1U) +#define SDHC_IRQSTAT_CC_SHIFT (0U) +/*! CC - Command Complete + * 0b0..Command not complete. + * 0b1..Command complete. + */ +#define SDHC_IRQSTAT_CC(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_CC_SHIFT)) & SDHC_IRQSTAT_CC_MASK) +#define SDHC_IRQSTAT_TC_MASK (0x2U) +#define SDHC_IRQSTAT_TC_SHIFT (1U) +/*! TC - Transfer Complete + * 0b0..Transfer not complete. + * 0b1..Transfer complete. + */ +#define SDHC_IRQSTAT_TC(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_TC_SHIFT)) & SDHC_IRQSTAT_TC_MASK) +#define SDHC_IRQSTAT_BGE_MASK (0x4U) +#define SDHC_IRQSTAT_BGE_SHIFT (2U) +/*! BGE - Block Gap Event + * 0b0..No block gap event. + * 0b1..Transaction stopped at block gap. + */ +#define SDHC_IRQSTAT_BGE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_BGE_SHIFT)) & SDHC_IRQSTAT_BGE_MASK) +#define SDHC_IRQSTAT_DINT_MASK (0x8U) +#define SDHC_IRQSTAT_DINT_SHIFT (3U) +/*! DINT - DMA Interrupt + * 0b0..No DMA Interrupt. + * 0b1..DMA Interrupt is generated. + */ +#define SDHC_IRQSTAT_DINT(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_DINT_SHIFT)) & SDHC_IRQSTAT_DINT_MASK) +#define SDHC_IRQSTAT_BWR_MASK (0x10U) +#define SDHC_IRQSTAT_BWR_SHIFT (4U) +/*! BWR - Buffer Write Ready + * 0b0..Not ready to write buffer. + * 0b1..Ready to write buffer. + */ +#define SDHC_IRQSTAT_BWR(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_BWR_SHIFT)) & SDHC_IRQSTAT_BWR_MASK) +#define SDHC_IRQSTAT_BRR_MASK (0x20U) +#define SDHC_IRQSTAT_BRR_SHIFT (5U) +/*! BRR - Buffer Read Ready + * 0b0..Not ready to read buffer. + * 0b1..Ready to read buffer. + */ +#define SDHC_IRQSTAT_BRR(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_BRR_SHIFT)) & SDHC_IRQSTAT_BRR_MASK) +#define SDHC_IRQSTAT_CINS_MASK (0x40U) +#define SDHC_IRQSTAT_CINS_SHIFT (6U) +/*! CINS - Card Insertion + * 0b0..Card state unstable or removed. + * 0b1..Card inserted. + */ +#define SDHC_IRQSTAT_CINS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_CINS_SHIFT)) & SDHC_IRQSTAT_CINS_MASK) +#define SDHC_IRQSTAT_CRM_MASK (0x80U) +#define SDHC_IRQSTAT_CRM_SHIFT (7U) +/*! CRM - Card Removal + * 0b0..Card state unstable or inserted. + * 0b1..Card removed. + */ +#define SDHC_IRQSTAT_CRM(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_CRM_SHIFT)) & SDHC_IRQSTAT_CRM_MASK) +#define SDHC_IRQSTAT_CINT_MASK (0x100U) +#define SDHC_IRQSTAT_CINT_SHIFT (8U) +/*! CINT - Card Interrupt + * 0b0..No Card Interrupt. + * 0b1..Generate Card Interrupt. + */ +#define SDHC_IRQSTAT_CINT(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_CINT_SHIFT)) & SDHC_IRQSTAT_CINT_MASK) +#define SDHC_IRQSTAT_CTOE_MASK (0x10000U) +#define SDHC_IRQSTAT_CTOE_SHIFT (16U) +/*! CTOE - Command Timeout Error + * 0b0..No error. + * 0b1..Time out. + */ +#define SDHC_IRQSTAT_CTOE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_CTOE_SHIFT)) & SDHC_IRQSTAT_CTOE_MASK) +#define SDHC_IRQSTAT_CCE_MASK (0x20000U) +#define SDHC_IRQSTAT_CCE_SHIFT (17U) +/*! CCE - Command CRC Error + * 0b0..No error. + * 0b1..CRC Error generated. + */ +#define SDHC_IRQSTAT_CCE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_CCE_SHIFT)) & SDHC_IRQSTAT_CCE_MASK) +#define SDHC_IRQSTAT_CEBE_MASK (0x40000U) +#define SDHC_IRQSTAT_CEBE_SHIFT (18U) +/*! CEBE - Command End Bit Error + * 0b0..No error. + * 0b1..End Bit Error generated. + */ +#define SDHC_IRQSTAT_CEBE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_CEBE_SHIFT)) & SDHC_IRQSTAT_CEBE_MASK) +#define SDHC_IRQSTAT_CIE_MASK (0x80000U) +#define SDHC_IRQSTAT_CIE_SHIFT (19U) +/*! CIE - Command Index Error + * 0b0..No error. + * 0b1..Error. + */ +#define SDHC_IRQSTAT_CIE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_CIE_SHIFT)) & SDHC_IRQSTAT_CIE_MASK) +#define SDHC_IRQSTAT_DTOE_MASK (0x100000U) +#define SDHC_IRQSTAT_DTOE_SHIFT (20U) +/*! DTOE - Data Timeout Error + * 0b0..No error. + * 0b1..Time out. + */ +#define SDHC_IRQSTAT_DTOE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_DTOE_SHIFT)) & SDHC_IRQSTAT_DTOE_MASK) +#define SDHC_IRQSTAT_DCE_MASK (0x200000U) +#define SDHC_IRQSTAT_DCE_SHIFT (21U) +/*! DCE - Data CRC Error + * 0b0..No error. + * 0b1..Error. + */ +#define SDHC_IRQSTAT_DCE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_DCE_SHIFT)) & SDHC_IRQSTAT_DCE_MASK) +#define SDHC_IRQSTAT_DEBE_MASK (0x400000U) +#define SDHC_IRQSTAT_DEBE_SHIFT (22U) +/*! DEBE - Data End Bit Error + * 0b0..No error. + * 0b1..Error. + */ +#define SDHC_IRQSTAT_DEBE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_DEBE_SHIFT)) & SDHC_IRQSTAT_DEBE_MASK) +#define SDHC_IRQSTAT_AC12E_MASK (0x1000000U) +#define SDHC_IRQSTAT_AC12E_SHIFT (24U) +/*! AC12E - Auto CMD12 Error + * 0b0..No error. + * 0b1..Error. + */ +#define SDHC_IRQSTAT_AC12E(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_AC12E_SHIFT)) & SDHC_IRQSTAT_AC12E_MASK) +#define SDHC_IRQSTAT_DMAE_MASK (0x10000000U) +#define SDHC_IRQSTAT_DMAE_SHIFT (28U) +/*! DMAE - DMA Error + * 0b0..No error. + * 0b1..Error. + */ +#define SDHC_IRQSTAT_DMAE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTAT_DMAE_SHIFT)) & SDHC_IRQSTAT_DMAE_MASK) +/*! @} */ + +/*! @name IRQSTATEN - Interrupt Status Enable register */ +/*! @{ */ +#define SDHC_IRQSTATEN_CCSEN_MASK (0x1U) +#define SDHC_IRQSTATEN_CCSEN_SHIFT (0U) +/*! CCSEN - Command Complete Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_CCSEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_CCSEN_SHIFT)) & SDHC_IRQSTATEN_CCSEN_MASK) +#define SDHC_IRQSTATEN_TCSEN_MASK (0x2U) +#define SDHC_IRQSTATEN_TCSEN_SHIFT (1U) +/*! TCSEN - Transfer Complete Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_TCSEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_TCSEN_SHIFT)) & SDHC_IRQSTATEN_TCSEN_MASK) +#define SDHC_IRQSTATEN_BGESEN_MASK (0x4U) +#define SDHC_IRQSTATEN_BGESEN_SHIFT (2U) +/*! BGESEN - Block Gap Event Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_BGESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_BGESEN_SHIFT)) & SDHC_IRQSTATEN_BGESEN_MASK) +#define SDHC_IRQSTATEN_DINTSEN_MASK (0x8U) +#define SDHC_IRQSTATEN_DINTSEN_SHIFT (3U) +/*! DINTSEN - DMA Interrupt Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_DINTSEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_DINTSEN_SHIFT)) & SDHC_IRQSTATEN_DINTSEN_MASK) +#define SDHC_IRQSTATEN_BWRSEN_MASK (0x10U) +#define SDHC_IRQSTATEN_BWRSEN_SHIFT (4U) +/*! BWRSEN - Buffer Write Ready Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_BWRSEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_BWRSEN_SHIFT)) & SDHC_IRQSTATEN_BWRSEN_MASK) +#define SDHC_IRQSTATEN_BRRSEN_MASK (0x20U) +#define SDHC_IRQSTATEN_BRRSEN_SHIFT (5U) +/*! BRRSEN - Buffer Read Ready Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_BRRSEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_BRRSEN_SHIFT)) & SDHC_IRQSTATEN_BRRSEN_MASK) +#define SDHC_IRQSTATEN_CINSEN_MASK (0x40U) +#define SDHC_IRQSTATEN_CINSEN_SHIFT (6U) +/*! CINSEN - Card Insertion Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_CINSEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_CINSEN_SHIFT)) & SDHC_IRQSTATEN_CINSEN_MASK) +#define SDHC_IRQSTATEN_CRMSEN_MASK (0x80U) +#define SDHC_IRQSTATEN_CRMSEN_SHIFT (7U) +/*! CRMSEN - Card Removal Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_CRMSEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_CRMSEN_SHIFT)) & SDHC_IRQSTATEN_CRMSEN_MASK) +#define SDHC_IRQSTATEN_CINTSEN_MASK (0x100U) +#define SDHC_IRQSTATEN_CINTSEN_SHIFT (8U) +/*! CINTSEN - Card Interrupt Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_CINTSEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_CINTSEN_SHIFT)) & SDHC_IRQSTATEN_CINTSEN_MASK) +#define SDHC_IRQSTATEN_CTOESEN_MASK (0x10000U) +#define SDHC_IRQSTATEN_CTOESEN_SHIFT (16U) +/*! CTOESEN - Command Timeout Error Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_CTOESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_CTOESEN_SHIFT)) & SDHC_IRQSTATEN_CTOESEN_MASK) +#define SDHC_IRQSTATEN_CCESEN_MASK (0x20000U) +#define SDHC_IRQSTATEN_CCESEN_SHIFT (17U) +/*! CCESEN - Command CRC Error Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_CCESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_CCESEN_SHIFT)) & SDHC_IRQSTATEN_CCESEN_MASK) +#define SDHC_IRQSTATEN_CEBESEN_MASK (0x40000U) +#define SDHC_IRQSTATEN_CEBESEN_SHIFT (18U) +/*! CEBESEN - Command End Bit Error Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_CEBESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_CEBESEN_SHIFT)) & SDHC_IRQSTATEN_CEBESEN_MASK) +#define SDHC_IRQSTATEN_CIESEN_MASK (0x80000U) +#define SDHC_IRQSTATEN_CIESEN_SHIFT (19U) +/*! CIESEN - Command Index Error Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_CIESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_CIESEN_SHIFT)) & SDHC_IRQSTATEN_CIESEN_MASK) +#define SDHC_IRQSTATEN_DTOESEN_MASK (0x100000U) +#define SDHC_IRQSTATEN_DTOESEN_SHIFT (20U) +/*! DTOESEN - Data Timeout Error Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_DTOESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_DTOESEN_SHIFT)) & SDHC_IRQSTATEN_DTOESEN_MASK) +#define SDHC_IRQSTATEN_DCESEN_MASK (0x200000U) +#define SDHC_IRQSTATEN_DCESEN_SHIFT (21U) +/*! DCESEN - Data CRC Error Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_DCESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_DCESEN_SHIFT)) & SDHC_IRQSTATEN_DCESEN_MASK) +#define SDHC_IRQSTATEN_DEBESEN_MASK (0x400000U) +#define SDHC_IRQSTATEN_DEBESEN_SHIFT (22U) +/*! DEBESEN - Data End Bit Error Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_DEBESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_DEBESEN_SHIFT)) & SDHC_IRQSTATEN_DEBESEN_MASK) +#define SDHC_IRQSTATEN_AC12ESEN_MASK (0x1000000U) +#define SDHC_IRQSTATEN_AC12ESEN_SHIFT (24U) +/*! AC12ESEN - Auto CMD12 Error Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_AC12ESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_AC12ESEN_SHIFT)) & SDHC_IRQSTATEN_AC12ESEN_MASK) +#define SDHC_IRQSTATEN_DMAESEN_MASK (0x10000000U) +#define SDHC_IRQSTATEN_DMAESEN_SHIFT (28U) +/*! DMAESEN - DMA Error Status Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSTATEN_DMAESEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSTATEN_DMAESEN_SHIFT)) & SDHC_IRQSTATEN_DMAESEN_MASK) +/*! @} */ + +/*! @name IRQSIGEN - Interrupt Signal Enable register */ +/*! @{ */ +#define SDHC_IRQSIGEN_CCIEN_MASK (0x1U) +#define SDHC_IRQSIGEN_CCIEN_SHIFT (0U) +/*! CCIEN - Command Complete Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_CCIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_CCIEN_SHIFT)) & SDHC_IRQSIGEN_CCIEN_MASK) +#define SDHC_IRQSIGEN_TCIEN_MASK (0x2U) +#define SDHC_IRQSIGEN_TCIEN_SHIFT (1U) +/*! TCIEN - Transfer Complete Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_TCIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_TCIEN_SHIFT)) & SDHC_IRQSIGEN_TCIEN_MASK) +#define SDHC_IRQSIGEN_BGEIEN_MASK (0x4U) +#define SDHC_IRQSIGEN_BGEIEN_SHIFT (2U) +/*! BGEIEN - Block Gap Event Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_BGEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_BGEIEN_SHIFT)) & SDHC_IRQSIGEN_BGEIEN_MASK) +#define SDHC_IRQSIGEN_DINTIEN_MASK (0x8U) +#define SDHC_IRQSIGEN_DINTIEN_SHIFT (3U) +/*! DINTIEN - DMA Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_DINTIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_DINTIEN_SHIFT)) & SDHC_IRQSIGEN_DINTIEN_MASK) +#define SDHC_IRQSIGEN_BWRIEN_MASK (0x10U) +#define SDHC_IRQSIGEN_BWRIEN_SHIFT (4U) +/*! BWRIEN - Buffer Write Ready Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_BWRIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_BWRIEN_SHIFT)) & SDHC_IRQSIGEN_BWRIEN_MASK) +#define SDHC_IRQSIGEN_BRRIEN_MASK (0x20U) +#define SDHC_IRQSIGEN_BRRIEN_SHIFT (5U) +/*! BRRIEN - Buffer Read Ready Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_BRRIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_BRRIEN_SHIFT)) & SDHC_IRQSIGEN_BRRIEN_MASK) +#define SDHC_IRQSIGEN_CINSIEN_MASK (0x40U) +#define SDHC_IRQSIGEN_CINSIEN_SHIFT (6U) +/*! CINSIEN - Card Insertion Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_CINSIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_CINSIEN_SHIFT)) & SDHC_IRQSIGEN_CINSIEN_MASK) +#define SDHC_IRQSIGEN_CRMIEN_MASK (0x80U) +#define SDHC_IRQSIGEN_CRMIEN_SHIFT (7U) +/*! CRMIEN - Card Removal Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_CRMIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_CRMIEN_SHIFT)) & SDHC_IRQSIGEN_CRMIEN_MASK) +#define SDHC_IRQSIGEN_CINTIEN_MASK (0x100U) +#define SDHC_IRQSIGEN_CINTIEN_SHIFT (8U) +/*! CINTIEN - Card Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_CINTIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_CINTIEN_SHIFT)) & SDHC_IRQSIGEN_CINTIEN_MASK) +#define SDHC_IRQSIGEN_CTOEIEN_MASK (0x10000U) +#define SDHC_IRQSIGEN_CTOEIEN_SHIFT (16U) +/*! CTOEIEN - Command Timeout Error Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_CTOEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_CTOEIEN_SHIFT)) & SDHC_IRQSIGEN_CTOEIEN_MASK) +#define SDHC_IRQSIGEN_CCEIEN_MASK (0x20000U) +#define SDHC_IRQSIGEN_CCEIEN_SHIFT (17U) +/*! CCEIEN - Command CRC Error Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_CCEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_CCEIEN_SHIFT)) & SDHC_IRQSIGEN_CCEIEN_MASK) +#define SDHC_IRQSIGEN_CEBEIEN_MASK (0x40000U) +#define SDHC_IRQSIGEN_CEBEIEN_SHIFT (18U) +/*! CEBEIEN - Command End Bit Error Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_CEBEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_CEBEIEN_SHIFT)) & SDHC_IRQSIGEN_CEBEIEN_MASK) +#define SDHC_IRQSIGEN_CIEIEN_MASK (0x80000U) +#define SDHC_IRQSIGEN_CIEIEN_SHIFT (19U) +/*! CIEIEN - Command Index Error Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_CIEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_CIEIEN_SHIFT)) & SDHC_IRQSIGEN_CIEIEN_MASK) +#define SDHC_IRQSIGEN_DTOEIEN_MASK (0x100000U) +#define SDHC_IRQSIGEN_DTOEIEN_SHIFT (20U) +/*! DTOEIEN - Data Timeout Error Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_DTOEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_DTOEIEN_SHIFT)) & SDHC_IRQSIGEN_DTOEIEN_MASK) +#define SDHC_IRQSIGEN_DCEIEN_MASK (0x200000U) +#define SDHC_IRQSIGEN_DCEIEN_SHIFT (21U) +/*! DCEIEN - Data CRC Error Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_DCEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_DCEIEN_SHIFT)) & SDHC_IRQSIGEN_DCEIEN_MASK) +#define SDHC_IRQSIGEN_DEBEIEN_MASK (0x400000U) +#define SDHC_IRQSIGEN_DEBEIEN_SHIFT (22U) +/*! DEBEIEN - Data End Bit Error Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_DEBEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_DEBEIEN_SHIFT)) & SDHC_IRQSIGEN_DEBEIEN_MASK) +#define SDHC_IRQSIGEN_AC12EIEN_MASK (0x1000000U) +#define SDHC_IRQSIGEN_AC12EIEN_SHIFT (24U) +/*! AC12EIEN - Auto CMD12 Error Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_AC12EIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_AC12EIEN_SHIFT)) & SDHC_IRQSIGEN_AC12EIEN_MASK) +#define SDHC_IRQSIGEN_DMAEIEN_MASK (0x10000000U) +#define SDHC_IRQSIGEN_DMAEIEN_SHIFT (28U) +/*! DMAEIEN - DMA Error Interrupt Enable + * 0b0..Masked + * 0b1..Enabled + */ +#define SDHC_IRQSIGEN_DMAEIEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_IRQSIGEN_DMAEIEN_SHIFT)) & SDHC_IRQSIGEN_DMAEIEN_MASK) +/*! @} */ + +/*! @name AC12ERR - Auto CMD12 Error Status Register */ +/*! @{ */ +#define SDHC_AC12ERR_AC12NE_MASK (0x1U) +#define SDHC_AC12ERR_AC12NE_SHIFT (0U) +/*! AC12NE - Auto CMD12 Not Executed + * 0b0..Executed. + * 0b1..Not executed. + */ +#define SDHC_AC12ERR_AC12NE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_AC12ERR_AC12NE_SHIFT)) & SDHC_AC12ERR_AC12NE_MASK) +#define SDHC_AC12ERR_AC12TOE_MASK (0x2U) +#define SDHC_AC12ERR_AC12TOE_SHIFT (1U) +/*! AC12TOE - Auto CMD12 Timeout Error + * 0b0..No error. + * 0b1..Time out. + */ +#define SDHC_AC12ERR_AC12TOE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_AC12ERR_AC12TOE_SHIFT)) & SDHC_AC12ERR_AC12TOE_MASK) +#define SDHC_AC12ERR_AC12EBE_MASK (0x4U) +#define SDHC_AC12ERR_AC12EBE_SHIFT (2U) +/*! AC12EBE - Auto CMD12 End Bit Error + * 0b0..No error. + * 0b1..End bit error generated. + */ +#define SDHC_AC12ERR_AC12EBE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_AC12ERR_AC12EBE_SHIFT)) & SDHC_AC12ERR_AC12EBE_MASK) +#define SDHC_AC12ERR_AC12CE_MASK (0x8U) +#define SDHC_AC12ERR_AC12CE_SHIFT (3U) +/*! AC12CE - Auto CMD12 CRC Error + * 0b0..No CRC error. + * 0b1..CRC error met in Auto CMD12 response. + */ +#define SDHC_AC12ERR_AC12CE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_AC12ERR_AC12CE_SHIFT)) & SDHC_AC12ERR_AC12CE_MASK) +#define SDHC_AC12ERR_AC12IE_MASK (0x10U) +#define SDHC_AC12ERR_AC12IE_SHIFT (4U) +/*! AC12IE - Auto CMD12 Index Error + * 0b0..No error. + * 0b1..Error, the CMD index in response is not CMD12. + */ +#define SDHC_AC12ERR_AC12IE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_AC12ERR_AC12IE_SHIFT)) & SDHC_AC12ERR_AC12IE_MASK) +#define SDHC_AC12ERR_CNIBAC12E_MASK (0x80U) +#define SDHC_AC12ERR_CNIBAC12E_SHIFT (7U) +/*! CNIBAC12E - Command Not Issued By Auto CMD12 Error + * 0b0..No error. + * 0b1..Not issued. + */ +#define SDHC_AC12ERR_CNIBAC12E(x) (((uint32_t)(((uint32_t)(x)) << SDHC_AC12ERR_CNIBAC12E_SHIFT)) & SDHC_AC12ERR_CNIBAC12E_MASK) +/*! @} */ + +/*! @name HTCAPBLT - Host Controller Capabilities */ +/*! @{ */ +#define SDHC_HTCAPBLT_MBL_MASK (0x70000U) +#define SDHC_HTCAPBLT_MBL_SHIFT (16U) +/*! MBL - Max Block Length + * 0b000..512 bytes + * 0b001..1024 bytes + * 0b010..2048 bytes + * 0b011..4096 bytes + */ +#define SDHC_HTCAPBLT_MBL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_HTCAPBLT_MBL_SHIFT)) & SDHC_HTCAPBLT_MBL_MASK) +#define SDHC_HTCAPBLT_ADMAS_MASK (0x100000U) +#define SDHC_HTCAPBLT_ADMAS_SHIFT (20U) +/*! ADMAS - ADMA Support + * 0b0..Advanced DMA not supported. + * 0b1..Advanced DMA supported. + */ +#define SDHC_HTCAPBLT_ADMAS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_HTCAPBLT_ADMAS_SHIFT)) & SDHC_HTCAPBLT_ADMAS_MASK) +#define SDHC_HTCAPBLT_HSS_MASK (0x200000U) +#define SDHC_HTCAPBLT_HSS_SHIFT (21U) +/*! HSS - High Speed Support + * 0b0..High speed not supported. + * 0b1..High speed supported. + */ +#define SDHC_HTCAPBLT_HSS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_HTCAPBLT_HSS_SHIFT)) & SDHC_HTCAPBLT_HSS_MASK) +#define SDHC_HTCAPBLT_DMAS_MASK (0x400000U) +#define SDHC_HTCAPBLT_DMAS_SHIFT (22U) +/*! DMAS - DMA Support + * 0b0..DMA not supported. + * 0b1..DMA supported. + */ +#define SDHC_HTCAPBLT_DMAS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_HTCAPBLT_DMAS_SHIFT)) & SDHC_HTCAPBLT_DMAS_MASK) +#define SDHC_HTCAPBLT_SRS_MASK (0x800000U) +#define SDHC_HTCAPBLT_SRS_SHIFT (23U) +/*! SRS - Suspend/Resume Support + * 0b0..Not supported. + * 0b1..Supported. + */ +#define SDHC_HTCAPBLT_SRS(x) (((uint32_t)(((uint32_t)(x)) << SDHC_HTCAPBLT_SRS_SHIFT)) & SDHC_HTCAPBLT_SRS_MASK) +#define SDHC_HTCAPBLT_VS33_MASK (0x1000000U) +#define SDHC_HTCAPBLT_VS33_SHIFT (24U) +/*! VS33 - Voltage Support 3.3 V + * 0b0..3.3 V not supported. + * 0b1..3.3 V supported. + */ +#define SDHC_HTCAPBLT_VS33(x) (((uint32_t)(((uint32_t)(x)) << SDHC_HTCAPBLT_VS33_SHIFT)) & SDHC_HTCAPBLT_VS33_MASK) +/*! @} */ + +/*! @name WML - Watermark Level Register */ +/*! @{ */ +#define SDHC_WML_RDWML_MASK (0xFFU) +#define SDHC_WML_RDWML_SHIFT (0U) +#define SDHC_WML_RDWML(x) (((uint32_t)(((uint32_t)(x)) << SDHC_WML_RDWML_SHIFT)) & SDHC_WML_RDWML_MASK) +#define SDHC_WML_WRWML_MASK (0xFF0000U) +#define SDHC_WML_WRWML_SHIFT (16U) +#define SDHC_WML_WRWML(x) (((uint32_t)(((uint32_t)(x)) << SDHC_WML_WRWML_SHIFT)) & SDHC_WML_WRWML_MASK) +/*! @} */ + +/*! @name FEVT - Force Event register */ +/*! @{ */ +#define SDHC_FEVT_AC12NE_MASK (0x1U) +#define SDHC_FEVT_AC12NE_SHIFT (0U) +#define SDHC_FEVT_AC12NE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_AC12NE_SHIFT)) & SDHC_FEVT_AC12NE_MASK) +#define SDHC_FEVT_AC12TOE_MASK (0x2U) +#define SDHC_FEVT_AC12TOE_SHIFT (1U) +#define SDHC_FEVT_AC12TOE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_AC12TOE_SHIFT)) & SDHC_FEVT_AC12TOE_MASK) +#define SDHC_FEVT_AC12CE_MASK (0x4U) +#define SDHC_FEVT_AC12CE_SHIFT (2U) +#define SDHC_FEVT_AC12CE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_AC12CE_SHIFT)) & SDHC_FEVT_AC12CE_MASK) +#define SDHC_FEVT_AC12EBE_MASK (0x8U) +#define SDHC_FEVT_AC12EBE_SHIFT (3U) +#define SDHC_FEVT_AC12EBE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_AC12EBE_SHIFT)) & SDHC_FEVT_AC12EBE_MASK) +#define SDHC_FEVT_AC12IE_MASK (0x10U) +#define SDHC_FEVT_AC12IE_SHIFT (4U) +#define SDHC_FEVT_AC12IE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_AC12IE_SHIFT)) & SDHC_FEVT_AC12IE_MASK) +#define SDHC_FEVT_CNIBAC12E_MASK (0x80U) +#define SDHC_FEVT_CNIBAC12E_SHIFT (7U) +#define SDHC_FEVT_CNIBAC12E(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_CNIBAC12E_SHIFT)) & SDHC_FEVT_CNIBAC12E_MASK) +#define SDHC_FEVT_CTOE_MASK (0x10000U) +#define SDHC_FEVT_CTOE_SHIFT (16U) +#define SDHC_FEVT_CTOE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_CTOE_SHIFT)) & SDHC_FEVT_CTOE_MASK) +#define SDHC_FEVT_CCE_MASK (0x20000U) +#define SDHC_FEVT_CCE_SHIFT (17U) +#define SDHC_FEVT_CCE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_CCE_SHIFT)) & SDHC_FEVT_CCE_MASK) +#define SDHC_FEVT_CEBE_MASK (0x40000U) +#define SDHC_FEVT_CEBE_SHIFT (18U) +#define SDHC_FEVT_CEBE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_CEBE_SHIFT)) & SDHC_FEVT_CEBE_MASK) +#define SDHC_FEVT_CIE_MASK (0x80000U) +#define SDHC_FEVT_CIE_SHIFT (19U) +#define SDHC_FEVT_CIE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_CIE_SHIFT)) & SDHC_FEVT_CIE_MASK) +#define SDHC_FEVT_DTOE_MASK (0x100000U) +#define SDHC_FEVT_DTOE_SHIFT (20U) +#define SDHC_FEVT_DTOE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_DTOE_SHIFT)) & SDHC_FEVT_DTOE_MASK) +#define SDHC_FEVT_DCE_MASK (0x200000U) +#define SDHC_FEVT_DCE_SHIFT (21U) +#define SDHC_FEVT_DCE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_DCE_SHIFT)) & SDHC_FEVT_DCE_MASK) +#define SDHC_FEVT_DEBE_MASK (0x400000U) +#define SDHC_FEVT_DEBE_SHIFT (22U) +#define SDHC_FEVT_DEBE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_DEBE_SHIFT)) & SDHC_FEVT_DEBE_MASK) +#define SDHC_FEVT_AC12E_MASK (0x1000000U) +#define SDHC_FEVT_AC12E_SHIFT (24U) +#define SDHC_FEVT_AC12E(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_AC12E_SHIFT)) & SDHC_FEVT_AC12E_MASK) +#define SDHC_FEVT_DMAE_MASK (0x10000000U) +#define SDHC_FEVT_DMAE_SHIFT (28U) +#define SDHC_FEVT_DMAE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_DMAE_SHIFT)) & SDHC_FEVT_DMAE_MASK) +#define SDHC_FEVT_CINT_MASK (0x80000000U) +#define SDHC_FEVT_CINT_SHIFT (31U) +#define SDHC_FEVT_CINT(x) (((uint32_t)(((uint32_t)(x)) << SDHC_FEVT_CINT_SHIFT)) & SDHC_FEVT_CINT_MASK) +/*! @} */ + +/*! @name ADMAES - ADMA Error Status register */ +/*! @{ */ +#define SDHC_ADMAES_ADMAES_MASK (0x3U) +#define SDHC_ADMAES_ADMAES_SHIFT (0U) +#define SDHC_ADMAES_ADMAES(x) (((uint32_t)(((uint32_t)(x)) << SDHC_ADMAES_ADMAES_SHIFT)) & SDHC_ADMAES_ADMAES_MASK) +#define SDHC_ADMAES_ADMALME_MASK (0x4U) +#define SDHC_ADMAES_ADMALME_SHIFT (2U) +/*! ADMALME - ADMA Length Mismatch Error + * 0b0..No error. + * 0b1..Error. + */ +#define SDHC_ADMAES_ADMALME(x) (((uint32_t)(((uint32_t)(x)) << SDHC_ADMAES_ADMALME_SHIFT)) & SDHC_ADMAES_ADMALME_MASK) +#define SDHC_ADMAES_ADMADCE_MASK (0x8U) +#define SDHC_ADMAES_ADMADCE_SHIFT (3U) +/*! ADMADCE - ADMA Descriptor Error + * 0b0..No error. + * 0b1..Error. + */ +#define SDHC_ADMAES_ADMADCE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_ADMAES_ADMADCE_SHIFT)) & SDHC_ADMAES_ADMADCE_MASK) +/*! @} */ + +/*! @name ADSADDR - ADMA System Addressregister */ +/*! @{ */ +#define SDHC_ADSADDR_ADSADDR_MASK (0xFFFFFFFCU) +#define SDHC_ADSADDR_ADSADDR_SHIFT (2U) +#define SDHC_ADSADDR_ADSADDR(x) (((uint32_t)(((uint32_t)(x)) << SDHC_ADSADDR_ADSADDR_SHIFT)) & SDHC_ADSADDR_ADSADDR_MASK) +/*! @} */ + +/*! @name VENDOR - Vendor Specific register */ +/*! @{ */ +#define SDHC_VENDOR_EXTDMAEN_MASK (0x1U) +#define SDHC_VENDOR_EXTDMAEN_SHIFT (0U) +/*! EXTDMAEN - External DMA Request Enable + * 0b0..In any scenario, SDHC does not send out the external DMA request. + * 0b1..When internal DMA is not active, the external DMA request will be sent out. + */ +#define SDHC_VENDOR_EXTDMAEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_VENDOR_EXTDMAEN_SHIFT)) & SDHC_VENDOR_EXTDMAEN_MASK) +#define SDHC_VENDOR_EXBLKNU_MASK (0x2U) +#define SDHC_VENDOR_EXBLKNU_SHIFT (1U) +/*! EXBLKNU - Exact Block Number Block Read Enable For SDIO CMD53 + * 0b0..None exact block read. + * 0b1..Exact block read for SDIO CMD53. + */ +#define SDHC_VENDOR_EXBLKNU(x) (((uint32_t)(((uint32_t)(x)) << SDHC_VENDOR_EXBLKNU_SHIFT)) & SDHC_VENDOR_EXBLKNU_MASK) +#define SDHC_VENDOR_INTSTVAL_MASK (0xFF0000U) +#define SDHC_VENDOR_INTSTVAL_SHIFT (16U) +#define SDHC_VENDOR_INTSTVAL(x) (((uint32_t)(((uint32_t)(x)) << SDHC_VENDOR_INTSTVAL_SHIFT)) & SDHC_VENDOR_INTSTVAL_MASK) +/*! @} */ + +/*! @name MMCBOOT - MMC Boot register */ +/*! @{ */ +#define SDHC_MMCBOOT_DTOCVACK_MASK (0xFU) +#define SDHC_MMCBOOT_DTOCVACK_SHIFT (0U) +/*! DTOCVACK - Boot ACK Time Out Counter Value + * 0b0000..SDCLK x 2^8 + * 0b0001..SDCLK x 2^9 + * 0b0010..SDCLK x 2^10 + * 0b0011..SDCLK x 2^11 + * 0b0100..SDCLK x 2^12 + * 0b0101..SDCLK x 2^13 + * 0b0110..SDCLK x 2^14 + * 0b0111..SDCLK x 2^15 + * 0b1110..SDCLK x 2^22 + * 0b1111..Reserved + */ +#define SDHC_MMCBOOT_DTOCVACK(x) (((uint32_t)(((uint32_t)(x)) << SDHC_MMCBOOT_DTOCVACK_SHIFT)) & SDHC_MMCBOOT_DTOCVACK_MASK) +#define SDHC_MMCBOOT_BOOTACK_MASK (0x10U) +#define SDHC_MMCBOOT_BOOTACK_SHIFT (4U) +/*! BOOTACK - Boot Ack Mode Select + * 0b0..No ack. + * 0b1..Ack. + */ +#define SDHC_MMCBOOT_BOOTACK(x) (((uint32_t)(((uint32_t)(x)) << SDHC_MMCBOOT_BOOTACK_SHIFT)) & SDHC_MMCBOOT_BOOTACK_MASK) +#define SDHC_MMCBOOT_BOOTMODE_MASK (0x20U) +#define SDHC_MMCBOOT_BOOTMODE_SHIFT (5U) +/*! BOOTMODE - Boot Mode Select + * 0b0..Normal boot. + * 0b1..Alternative boot. + */ +#define SDHC_MMCBOOT_BOOTMODE(x) (((uint32_t)(((uint32_t)(x)) << SDHC_MMCBOOT_BOOTMODE_SHIFT)) & SDHC_MMCBOOT_BOOTMODE_MASK) +#define SDHC_MMCBOOT_BOOTEN_MASK (0x40U) +#define SDHC_MMCBOOT_BOOTEN_SHIFT (6U) +/*! BOOTEN - Boot Mode Enable + * 0b0..Fast boot disable. + * 0b1..Fast boot enable. + */ +#define SDHC_MMCBOOT_BOOTEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_MMCBOOT_BOOTEN_SHIFT)) & SDHC_MMCBOOT_BOOTEN_MASK) +#define SDHC_MMCBOOT_AUTOSABGEN_MASK (0x80U) +#define SDHC_MMCBOOT_AUTOSABGEN_SHIFT (7U) +#define SDHC_MMCBOOT_AUTOSABGEN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_MMCBOOT_AUTOSABGEN_SHIFT)) & SDHC_MMCBOOT_AUTOSABGEN_MASK) +#define SDHC_MMCBOOT_BOOTBLKCNT_MASK (0xFFFF0000U) +#define SDHC_MMCBOOT_BOOTBLKCNT_SHIFT (16U) +#define SDHC_MMCBOOT_BOOTBLKCNT(x) (((uint32_t)(((uint32_t)(x)) << SDHC_MMCBOOT_BOOTBLKCNT_SHIFT)) & SDHC_MMCBOOT_BOOTBLKCNT_MASK) +/*! @} */ + +/*! @name HOSTVER - Host Controller Version */ +/*! @{ */ +#define SDHC_HOSTVER_SVN_MASK (0xFFU) +#define SDHC_HOSTVER_SVN_SHIFT (0U) +/*! SVN - Specification Version Number + * 0b00000001..SD host specification version 2.0, supports test event register and ADMA. + */ +#define SDHC_HOSTVER_SVN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_HOSTVER_SVN_SHIFT)) & SDHC_HOSTVER_SVN_MASK) +#define SDHC_HOSTVER_VVN_MASK (0xFF00U) +#define SDHC_HOSTVER_VVN_SHIFT (8U) +/*! VVN - Vendor Version Number + * 0b00000000..Freescale SDHC version 1.0 + * 0b00010000..Freescale SDHC version 2.0 + * 0b00010001..Freescale SDHC version 2.1 + * 0b00010010..Freescale SDHC version 2.2 + */ +#define SDHC_HOSTVER_VVN(x) (((uint32_t)(((uint32_t)(x)) << SDHC_HOSTVER_VVN_SHIFT)) & SDHC_HOSTVER_VVN_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group SDHC_Register_Masks */ + + +/* SDHC - Peripheral instance base addresses */ +/** Peripheral SDHC base address */ +#define SDHC_BASE (0x400B1000u) +/** Peripheral SDHC base pointer */ +#define SDHC ((SDHC_Type *)SDHC_BASE) +/** Array initializer of SDHC peripheral base addresses */ +#define SDHC_BASE_ADDRS { SDHC_BASE } +/** Array initializer of SDHC peripheral base pointers */ +#define SDHC_BASE_PTRS { SDHC } +/** Interrupt vectors for the SDHC peripheral type */ +#define SDHC_IRQS { SDHC_IRQn } + +/*! + * @} + */ /* end of group SDHC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SIM Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SIM_Peripheral_Access_Layer SIM Peripheral Access Layer + * @{ + */ + +/** SIM - Register Layout Typedef */ +typedef struct { + __IO uint32_t SOPT1; /**< System Options Register 1, offset: 0x0 */ + __IO uint32_t SOPT1CFG; /**< SOPT1 Configuration Register, offset: 0x4 */ + uint8_t RESERVED_0[4092]; + __IO uint32_t SOPT2; /**< System Options Register 2, offset: 0x1004 */ + uint8_t RESERVED_1[4]; + __IO uint32_t SOPT4; /**< System Options Register 4, offset: 0x100C */ + __IO uint32_t SOPT5; /**< System Options Register 5, offset: 0x1010 */ + uint8_t RESERVED_2[4]; + __IO uint32_t SOPT7; /**< System Options Register 7, offset: 0x1018 */ + uint8_t RESERVED_3[8]; + __I uint32_t SDID; /**< System Device Identification Register, offset: 0x1024 */ + __IO uint32_t SCGC1; /**< System Clock Gating Control Register 1, offset: 0x1028 */ + __IO uint32_t SCGC2; /**< System Clock Gating Control Register 2, offset: 0x102C */ + __IO uint32_t SCGC3; /**< System Clock Gating Control Register 3, offset: 0x1030 */ + __IO uint32_t SCGC4; /**< System Clock Gating Control Register 4, offset: 0x1034 */ + __IO uint32_t SCGC5; /**< System Clock Gating Control Register 5, offset: 0x1038 */ + __IO uint32_t SCGC6; /**< System Clock Gating Control Register 6, offset: 0x103C */ + __IO uint32_t SCGC7; /**< System Clock Gating Control Register 7, offset: 0x1040 */ + __IO uint32_t CLKDIV1; /**< System Clock Divider Register 1, offset: 0x1044 */ + __IO uint32_t CLKDIV2; /**< System Clock Divider Register 2, offset: 0x1048 */ + __IO uint32_t FCFG1; /**< Flash Configuration Register 1, offset: 0x104C */ + __I uint32_t FCFG2; /**< Flash Configuration Register 2, offset: 0x1050 */ + __I uint32_t UIDH; /**< Unique Identification Register High, offset: 0x1054 */ + __I uint32_t UIDMH; /**< Unique Identification Register Mid-High, offset: 0x1058 */ + __I uint32_t UIDML; /**< Unique Identification Register Mid Low, offset: 0x105C */ + __I uint32_t UIDL; /**< Unique Identification Register Low, offset: 0x1060 */ +} SIM_Type; + +/* ---------------------------------------------------------------------------- + -- SIM Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SIM_Register_Masks SIM Register Masks + * @{ + */ + +/*! @name SOPT1 - System Options Register 1 */ +/*! @{ */ +#define SIM_SOPT1_RAMSIZE_MASK (0xF000U) +#define SIM_SOPT1_RAMSIZE_SHIFT (12U) +/*! RAMSIZE - RAM size + * 0b0001..8 KB + * 0b0011..16 KB + * 0b0100..24 KB + * 0b0101..32 KB + * 0b0110..48 KB + * 0b0111..64 KB + * 0b1000..96 KB + * 0b1001..128 KB + * 0b1011..256 KB + */ +#define SIM_SOPT1_RAMSIZE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1_RAMSIZE_SHIFT)) & SIM_SOPT1_RAMSIZE_MASK) +#define SIM_SOPT1_OSC32KSEL_MASK (0xC0000U) +#define SIM_SOPT1_OSC32KSEL_SHIFT (18U) +/*! OSC32KSEL - 32K oscillator clock select + * 0b00..System oscillator (OSC32KCLK) + * 0b01..Reserved + * 0b10..RTC 32.768kHz oscillator + * 0b11..LPO 1 kHz + */ +#define SIM_SOPT1_OSC32KSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1_OSC32KSEL_SHIFT)) & SIM_SOPT1_OSC32KSEL_MASK) +#define SIM_SOPT1_USBVSTBY_MASK (0x20000000U) +#define SIM_SOPT1_USBVSTBY_SHIFT (29U) +/*! USBVSTBY - USB voltage regulator in standby mode during VLPR and VLPW modes + * 0b0..USB voltage regulator not in standby during VLPR and VLPW modes. + * 0b1..USB voltage regulator in standby during VLPR and VLPW modes. + */ +#define SIM_SOPT1_USBVSTBY(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1_USBVSTBY_SHIFT)) & SIM_SOPT1_USBVSTBY_MASK) +#define SIM_SOPT1_USBSSTBY_MASK (0x40000000U) +#define SIM_SOPT1_USBSSTBY_SHIFT (30U) +/*! USBSSTBY - USB voltage regulator in standby mode during Stop, VLPS, LLS and VLLS modes. + * 0b0..USB voltage regulator not in standby during Stop, VLPS, LLS and VLLS modes. + * 0b1..USB voltage regulator in standby during Stop, VLPS, LLS and VLLS modes. + */ +#define SIM_SOPT1_USBSSTBY(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1_USBSSTBY_SHIFT)) & SIM_SOPT1_USBSSTBY_MASK) +#define SIM_SOPT1_USBREGEN_MASK (0x80000000U) +#define SIM_SOPT1_USBREGEN_SHIFT (31U) +/*! USBREGEN - USB voltage regulator enable + * 0b0..USB voltage regulator is disabled. + * 0b1..USB voltage regulator is enabled. + */ +#define SIM_SOPT1_USBREGEN(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1_USBREGEN_SHIFT)) & SIM_SOPT1_USBREGEN_MASK) +/*! @} */ + +/*! @name SOPT1CFG - SOPT1 Configuration Register */ +/*! @{ */ +#define SIM_SOPT1CFG_URWE_MASK (0x1000000U) +#define SIM_SOPT1CFG_URWE_SHIFT (24U) +/*! URWE - USB voltage regulator enable write enable + * 0b0..SOPT1 USBREGEN cannot be written. + * 0b1..SOPT1 USBREGEN can be written. + */ +#define SIM_SOPT1CFG_URWE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1CFG_URWE_SHIFT)) & SIM_SOPT1CFG_URWE_MASK) +#define SIM_SOPT1CFG_UVSWE_MASK (0x2000000U) +#define SIM_SOPT1CFG_UVSWE_SHIFT (25U) +/*! UVSWE - USB voltage regulator VLP standby write enable + * 0b0..SOPT1 USBVSTBY cannot be written. + * 0b1..SOPT1 USBVSTBY can be written. + */ +#define SIM_SOPT1CFG_UVSWE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1CFG_UVSWE_SHIFT)) & SIM_SOPT1CFG_UVSWE_MASK) +#define SIM_SOPT1CFG_USSWE_MASK (0x4000000U) +#define SIM_SOPT1CFG_USSWE_SHIFT (26U) +/*! USSWE - USB voltage regulator stop standby write enable + * 0b0..SOPT1 USBSSTBY cannot be written. + * 0b1..SOPT1 USBSSTBY can be written. + */ +#define SIM_SOPT1CFG_USSWE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT1CFG_USSWE_SHIFT)) & SIM_SOPT1CFG_USSWE_MASK) +/*! @} */ + +/*! @name SOPT2 - System Options Register 2 */ +/*! @{ */ +#define SIM_SOPT2_RTCCLKOUTSEL_MASK (0x10U) +#define SIM_SOPT2_RTCCLKOUTSEL_SHIFT (4U) +/*! RTCCLKOUTSEL - RTC clock out select + * 0b0..RTC 1 Hz clock is output on the RTC_CLKOUT pin. + * 0b1..RTC 32.768kHz clock is output on the RTC_CLKOUT pin. + */ +#define SIM_SOPT2_RTCCLKOUTSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_RTCCLKOUTSEL_SHIFT)) & SIM_SOPT2_RTCCLKOUTSEL_MASK) +#define SIM_SOPT2_CLKOUTSEL_MASK (0xE0U) +#define SIM_SOPT2_CLKOUTSEL_SHIFT (5U) +/*! CLKOUTSEL - CLKOUT select + * 0b000..FlexBus CLKOUT + * 0b001..Reserved + * 0b010..Flash clock + * 0b011..LPO clock (1 kHz) + * 0b100..MCGIRCLK + * 0b101..RTC 32.768kHz clock + * 0b110..OSCERCLK0 + * 0b111..IRC 48 MHz clock + */ +#define SIM_SOPT2_CLKOUTSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_CLKOUTSEL_SHIFT)) & SIM_SOPT2_CLKOUTSEL_MASK) +#define SIM_SOPT2_FBSL_MASK (0x300U) +#define SIM_SOPT2_FBSL_SHIFT (8U) +/*! FBSL - FlexBus security level + * 0b00..All off-chip accesses (instruction and data) via the FlexBus are disallowed. + * 0b01..All off-chip accesses (instruction and data) via the FlexBus are disallowed. + * 0b10..Off-chip instruction accesses are disallowed. Data accesses are allowed. + * 0b11..Off-chip instruction accesses and data accesses are allowed. + */ +#define SIM_SOPT2_FBSL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_FBSL_SHIFT)) & SIM_SOPT2_FBSL_MASK) +#define SIM_SOPT2_PTD7PAD_MASK (0x800U) +#define SIM_SOPT2_PTD7PAD_SHIFT (11U) +/*! PTD7PAD - PTD7 pad drive strength + * 0b0..Single-pad drive strength for PTD7. + * 0b1..Double pad drive strength for PTD7. + */ +#define SIM_SOPT2_PTD7PAD(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_PTD7PAD_SHIFT)) & SIM_SOPT2_PTD7PAD_MASK) +#define SIM_SOPT2_TRACECLKSEL_MASK (0x1000U) +#define SIM_SOPT2_TRACECLKSEL_SHIFT (12U) +/*! TRACECLKSEL - Debug trace clock select + * 0b0..MCGOUTCLK + * 0b1..Core/system clock + */ +#define SIM_SOPT2_TRACECLKSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_TRACECLKSEL_SHIFT)) & SIM_SOPT2_TRACECLKSEL_MASK) +#define SIM_SOPT2_PLLFLLSEL_MASK (0x30000U) +#define SIM_SOPT2_PLLFLLSEL_SHIFT (16U) +/*! PLLFLLSEL - PLL/FLL clock select + * 0b00..MCGFLLCLK clock + * 0b01..MCGPLLCLK clock + * 0b10..Reserved + * 0b11..IRC48 MHz clock + */ +#define SIM_SOPT2_PLLFLLSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_PLLFLLSEL_SHIFT)) & SIM_SOPT2_PLLFLLSEL_MASK) +#define SIM_SOPT2_USBSRC_MASK (0x40000U) +#define SIM_SOPT2_USBSRC_SHIFT (18U) +/*! USBSRC - USB clock source select + * 0b0..External bypass clock (USB_CLKIN). + * 0b1..MCGFLLCLK , or MCGPLLCLK , or IRC48M clock as selected by SOPT2[PLLFLLSEL], and then divided by the USB fractional divider as configured by SIM_CLKDIV2[USBFRAC, USBDIV]. + */ +#define SIM_SOPT2_USBSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_USBSRC_SHIFT)) & SIM_SOPT2_USBSRC_MASK) +#define SIM_SOPT2_RMIISRC_MASK (0x80000U) +#define SIM_SOPT2_RMIISRC_SHIFT (19U) +/*! RMIISRC - RMII clock source select + * 0b0..EXTAL clock + * 0b1..External bypass clock (ENET_1588_CLKIN). + */ +#define SIM_SOPT2_RMIISRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_RMIISRC_SHIFT)) & SIM_SOPT2_RMIISRC_MASK) +#define SIM_SOPT2_TIMESRC_MASK (0x300000U) +#define SIM_SOPT2_TIMESRC_SHIFT (20U) +/*! TIMESRC - IEEE 1588 timestamp clock source select + * 0b00..Core/system clock. + * 0b01..MCGFLLCLK , or MCGPLLCLK , or IRC48M clock as selected by SOPT2[PLLFLLSEL]. + * 0b10..OSCERCLK clock + * 0b11..External bypass clock (ENET_1588_CLKIN). + */ +#define SIM_SOPT2_TIMESRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_TIMESRC_SHIFT)) & SIM_SOPT2_TIMESRC_MASK) +#define SIM_SOPT2_SDHCSRC_MASK (0x30000000U) +#define SIM_SOPT2_SDHCSRC_SHIFT (28U) +/*! SDHCSRC - SDHC clock source select + * 0b00..Core/system clock. + * 0b01..MCGFLLCLK, or MCGPLLCLK , or IRC48M clock as selected by SOPT2[PLLFLLSEL]. + * 0b10..OSCERCLK clock + * 0b11..External bypass clock (SDHC0_CLKIN) + */ +#define SIM_SOPT2_SDHCSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT2_SDHCSRC_SHIFT)) & SIM_SOPT2_SDHCSRC_MASK) +/*! @} */ + +/*! @name SOPT4 - System Options Register 4 */ +/*! @{ */ +#define SIM_SOPT4_FTM0FLT0_MASK (0x1U) +#define SIM_SOPT4_FTM0FLT0_SHIFT (0U) +/*! FTM0FLT0 - FTM0 Fault 0 Select + * 0b0..FTM0_FLT0 pin + * 0b1..CMP0 out + */ +#define SIM_SOPT4_FTM0FLT0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM0FLT0_SHIFT)) & SIM_SOPT4_FTM0FLT0_MASK) +#define SIM_SOPT4_FTM0FLT1_MASK (0x2U) +#define SIM_SOPT4_FTM0FLT1_SHIFT (1U) +/*! FTM0FLT1 - FTM0 Fault 1 Select + * 0b0..FTM0_FLT1 pin + * 0b1..CMP1 out + */ +#define SIM_SOPT4_FTM0FLT1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM0FLT1_SHIFT)) & SIM_SOPT4_FTM0FLT1_MASK) +#define SIM_SOPT4_FTM0FLT2_MASK (0x4U) +#define SIM_SOPT4_FTM0FLT2_SHIFT (2U) +/*! FTM0FLT2 - FTM0 Fault 2 Select + * 0b0..FTM0_FLT2 pin + * 0b1..CMP2 out + */ +#define SIM_SOPT4_FTM0FLT2(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM0FLT2_SHIFT)) & SIM_SOPT4_FTM0FLT2_MASK) +#define SIM_SOPT4_FTM1FLT0_MASK (0x10U) +#define SIM_SOPT4_FTM1FLT0_SHIFT (4U) +/*! FTM1FLT0 - FTM1 Fault 0 Select + * 0b0..FTM1_FLT0 pin + * 0b1..CMP0 out + */ +#define SIM_SOPT4_FTM1FLT0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM1FLT0_SHIFT)) & SIM_SOPT4_FTM1FLT0_MASK) +#define SIM_SOPT4_FTM2FLT0_MASK (0x100U) +#define SIM_SOPT4_FTM2FLT0_SHIFT (8U) +/*! FTM2FLT0 - FTM2 Fault 0 Select + * 0b0..FTM2_FLT0 pin + * 0b1..CMP0 out + */ +#define SIM_SOPT4_FTM2FLT0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM2FLT0_SHIFT)) & SIM_SOPT4_FTM2FLT0_MASK) +#define SIM_SOPT4_FTM3FLT0_MASK (0x1000U) +#define SIM_SOPT4_FTM3FLT0_SHIFT (12U) +/*! FTM3FLT0 - FTM3 Fault 0 Select + * 0b0..FTM3_FLT0 pin + * 0b1..CMP0 out + */ +#define SIM_SOPT4_FTM3FLT0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM3FLT0_SHIFT)) & SIM_SOPT4_FTM3FLT0_MASK) +#define SIM_SOPT4_FTM1CH0SRC_MASK (0xC0000U) +#define SIM_SOPT4_FTM1CH0SRC_SHIFT (18U) +/*! FTM1CH0SRC - FTM1 channel 0 input capture source select + * 0b00..FTM1_CH0 signal + * 0b01..CMP0 output + * 0b10..CMP1 output + * 0b11..USB start of frame pulse + */ +#define SIM_SOPT4_FTM1CH0SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM1CH0SRC_SHIFT)) & SIM_SOPT4_FTM1CH0SRC_MASK) +#define SIM_SOPT4_FTM2CH0SRC_MASK (0x300000U) +#define SIM_SOPT4_FTM2CH0SRC_SHIFT (20U) +/*! FTM2CH0SRC - FTM2 channel 0 input capture source select + * 0b00..FTM2_CH0 signal + * 0b01..CMP0 output + * 0b10..CMP1 output + * 0b11..Reserved + */ +#define SIM_SOPT4_FTM2CH0SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM2CH0SRC_SHIFT)) & SIM_SOPT4_FTM2CH0SRC_MASK) +#define SIM_SOPT4_FTM0CLKSEL_MASK (0x1000000U) +#define SIM_SOPT4_FTM0CLKSEL_SHIFT (24U) +/*! FTM0CLKSEL - FlexTimer 0 External Clock Pin Select + * 0b0..FTM_CLK0 pin + * 0b1..FTM_CLK1 pin + */ +#define SIM_SOPT4_FTM0CLKSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM0CLKSEL_SHIFT)) & SIM_SOPT4_FTM0CLKSEL_MASK) +#define SIM_SOPT4_FTM1CLKSEL_MASK (0x2000000U) +#define SIM_SOPT4_FTM1CLKSEL_SHIFT (25U) +/*! FTM1CLKSEL - FTM1 External Clock Pin Select + * 0b0..FTM_CLK0 pin + * 0b1..FTM_CLK1 pin + */ +#define SIM_SOPT4_FTM1CLKSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM1CLKSEL_SHIFT)) & SIM_SOPT4_FTM1CLKSEL_MASK) +#define SIM_SOPT4_FTM2CLKSEL_MASK (0x4000000U) +#define SIM_SOPT4_FTM2CLKSEL_SHIFT (26U) +/*! FTM2CLKSEL - FlexTimer 2 External Clock Pin Select + * 0b0..FTM2 external clock driven by FTM_CLK0 pin. + * 0b1..FTM2 external clock driven by FTM_CLK1 pin. + */ +#define SIM_SOPT4_FTM2CLKSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM2CLKSEL_SHIFT)) & SIM_SOPT4_FTM2CLKSEL_MASK) +#define SIM_SOPT4_FTM3CLKSEL_MASK (0x8000000U) +#define SIM_SOPT4_FTM3CLKSEL_SHIFT (27U) +/*! FTM3CLKSEL - FlexTimer 3 External Clock Pin Select + * 0b0..FTM3 external clock driven by FTM_CLK0 pin. + * 0b1..FTM3 external clock driven by FTM_CLK1 pin. + */ +#define SIM_SOPT4_FTM3CLKSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM3CLKSEL_SHIFT)) & SIM_SOPT4_FTM3CLKSEL_MASK) +#define SIM_SOPT4_FTM0TRG0SRC_MASK (0x10000000U) +#define SIM_SOPT4_FTM0TRG0SRC_SHIFT (28U) +/*! FTM0TRG0SRC - FlexTimer 0 Hardware Trigger 0 Source Select + * 0b0..HSCMP0 output drives FTM0 hardware trigger 0 + * 0b1..FTM1 channel match drives FTM0 hardware trigger 0 + */ +#define SIM_SOPT4_FTM0TRG0SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM0TRG0SRC_SHIFT)) & SIM_SOPT4_FTM0TRG0SRC_MASK) +#define SIM_SOPT4_FTM0TRG1SRC_MASK (0x20000000U) +#define SIM_SOPT4_FTM0TRG1SRC_SHIFT (29U) +/*! FTM0TRG1SRC - FlexTimer 0 Hardware Trigger 1 Source Select + * 0b0..PDB output trigger 1 drives FTM0 hardware trigger 1 + * 0b1..FTM2 channel match drives FTM0 hardware trigger 1 + */ +#define SIM_SOPT4_FTM0TRG1SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM0TRG1SRC_SHIFT)) & SIM_SOPT4_FTM0TRG1SRC_MASK) +#define SIM_SOPT4_FTM3TRG0SRC_MASK (0x40000000U) +#define SIM_SOPT4_FTM3TRG0SRC_SHIFT (30U) +/*! FTM3TRG0SRC - FlexTimer 3 Hardware Trigger 0 Source Select + * 0b0..Reserved + * 0b1..FTM1 channel match drives FTM3 hardware trigger 0 + */ +#define SIM_SOPT4_FTM3TRG0SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM3TRG0SRC_SHIFT)) & SIM_SOPT4_FTM3TRG0SRC_MASK) +#define SIM_SOPT4_FTM3TRG1SRC_MASK (0x80000000U) +#define SIM_SOPT4_FTM3TRG1SRC_SHIFT (31U) +/*! FTM3TRG1SRC - FlexTimer 3 Hardware Trigger 1 Source Select + * 0b0..Reserved + * 0b1..FTM2 channel match drives FTM3 hardware trigger 1 + */ +#define SIM_SOPT4_FTM3TRG1SRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT4_FTM3TRG1SRC_SHIFT)) & SIM_SOPT4_FTM3TRG1SRC_MASK) +/*! @} */ + +/*! @name SOPT5 - System Options Register 5 */ +/*! @{ */ +#define SIM_SOPT5_UART0TXSRC_MASK (0x3U) +#define SIM_SOPT5_UART0TXSRC_SHIFT (0U) +/*! UART0TXSRC - UART 0 transmit data source select + * 0b00..UART0_TX pin + * 0b01..UART0_TX pin modulated with FTM1 channel 0 output + * 0b10..UART0_TX pin modulated with FTM2 channel 0 output + * 0b11..Reserved + */ +#define SIM_SOPT5_UART0TXSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT5_UART0TXSRC_SHIFT)) & SIM_SOPT5_UART0TXSRC_MASK) +#define SIM_SOPT5_UART0RXSRC_MASK (0xCU) +#define SIM_SOPT5_UART0RXSRC_SHIFT (2U) +/*! UART0RXSRC - UART 0 receive data source select + * 0b00..UART0_RX pin + * 0b01..CMP0 + * 0b10..CMP1 + * 0b11..Reserved + */ +#define SIM_SOPT5_UART0RXSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT5_UART0RXSRC_SHIFT)) & SIM_SOPT5_UART0RXSRC_MASK) +#define SIM_SOPT5_UART1TXSRC_MASK (0x30U) +#define SIM_SOPT5_UART1TXSRC_SHIFT (4U) +/*! UART1TXSRC - UART 1 transmit data source select + * 0b00..UART1_TX pin + * 0b01..UART1_TX pin modulated with FTM1 channel 0 output + * 0b10..UART1_TX pin modulated with FTM2 channel 0 output + * 0b11..Reserved + */ +#define SIM_SOPT5_UART1TXSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT5_UART1TXSRC_SHIFT)) & SIM_SOPT5_UART1TXSRC_MASK) +#define SIM_SOPT5_UART1RXSRC_MASK (0xC0U) +#define SIM_SOPT5_UART1RXSRC_SHIFT (6U) +/*! UART1RXSRC - UART 1 receive data source select + * 0b00..UART1_RX pin + * 0b01..CMP0 + * 0b10..CMP1 + * 0b11..Reserved + */ +#define SIM_SOPT5_UART1RXSRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT5_UART1RXSRC_SHIFT)) & SIM_SOPT5_UART1RXSRC_MASK) +/*! @} */ + +/*! @name SOPT7 - System Options Register 7 */ +/*! @{ */ +#define SIM_SOPT7_ADC0TRGSEL_MASK (0xFU) +#define SIM_SOPT7_ADC0TRGSEL_SHIFT (0U) +/*! ADC0TRGSEL - ADC0 trigger select + * 0b0000..PDB external trigger pin input (PDB0_EXTRG) + * 0b0001..High speed comparator 0 output + * 0b0010..High speed comparator 1 output + * 0b0011..High speed comparator 2 output + * 0b0100..PIT trigger 0 + * 0b0101..PIT trigger 1 + * 0b0110..PIT trigger 2 + * 0b0111..PIT trigger 3 + * 0b1000..FTM0 trigger + * 0b1001..FTM1 trigger + * 0b1010..FTM2 trigger + * 0b1011..FTM3 trigger + * 0b1100..RTC alarm + * 0b1101..RTC seconds + * 0b1110..Low-power timer (LPTMR) trigger + * 0b1111..Reserved + */ +#define SIM_SOPT7_ADC0TRGSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT7_ADC0TRGSEL_SHIFT)) & SIM_SOPT7_ADC0TRGSEL_MASK) +#define SIM_SOPT7_ADC0PRETRGSEL_MASK (0x10U) +#define SIM_SOPT7_ADC0PRETRGSEL_SHIFT (4U) +/*! ADC0PRETRGSEL - ADC0 pretrigger select + * 0b0..Pre-trigger A + * 0b1..Pre-trigger B + */ +#define SIM_SOPT7_ADC0PRETRGSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT7_ADC0PRETRGSEL_SHIFT)) & SIM_SOPT7_ADC0PRETRGSEL_MASK) +#define SIM_SOPT7_ADC0ALTTRGEN_MASK (0x80U) +#define SIM_SOPT7_ADC0ALTTRGEN_SHIFT (7U) +/*! ADC0ALTTRGEN - ADC0 alternate trigger enable + * 0b0..PDB trigger selected for ADC0. + * 0b1..Alternate trigger selected for ADC0. + */ +#define SIM_SOPT7_ADC0ALTTRGEN(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT7_ADC0ALTTRGEN_SHIFT)) & SIM_SOPT7_ADC0ALTTRGEN_MASK) +#define SIM_SOPT7_ADC1TRGSEL_MASK (0xF00U) +#define SIM_SOPT7_ADC1TRGSEL_SHIFT (8U) +/*! ADC1TRGSEL - ADC1 trigger select + * 0b0000..PDB external trigger pin input (PDB0_EXTRG) + * 0b0001..High speed comparator 0 output + * 0b0010..High speed comparator 1 output + * 0b0011..High speed comparator 2 output + * 0b0100..PIT trigger 0 + * 0b0101..PIT trigger 1 + * 0b0110..PIT trigger 2 + * 0b0111..PIT trigger 3 + * 0b1000..FTM0 trigger + * 0b1001..FTM1 trigger + * 0b1010..FTM2 trigger + * 0b1011..FTM3 trigger + * 0b1100..RTC alarm + * 0b1101..RTC seconds + * 0b1110..Low-power timer (LPTMR) trigger + * 0b1111..Reserved + */ +#define SIM_SOPT7_ADC1TRGSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT7_ADC1TRGSEL_SHIFT)) & SIM_SOPT7_ADC1TRGSEL_MASK) +#define SIM_SOPT7_ADC1PRETRGSEL_MASK (0x1000U) +#define SIM_SOPT7_ADC1PRETRGSEL_SHIFT (12U) +/*! ADC1PRETRGSEL - ADC1 pre-trigger select + * 0b0..Pre-trigger A selected for ADC1. + * 0b1..Pre-trigger B selected for ADC1. + */ +#define SIM_SOPT7_ADC1PRETRGSEL(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT7_ADC1PRETRGSEL_SHIFT)) & SIM_SOPT7_ADC1PRETRGSEL_MASK) +#define SIM_SOPT7_ADC1ALTTRGEN_MASK (0x8000U) +#define SIM_SOPT7_ADC1ALTTRGEN_SHIFT (15U) +/*! ADC1ALTTRGEN - ADC1 alternate trigger enable + * 0b0..PDB trigger selected for ADC1 + * 0b1..Alternate trigger selected for ADC1 as defined by ADC1TRGSEL. + */ +#define SIM_SOPT7_ADC1ALTTRGEN(x) (((uint32_t)(((uint32_t)(x)) << SIM_SOPT7_ADC1ALTTRGEN_SHIFT)) & SIM_SOPT7_ADC1ALTTRGEN_MASK) +/*! @} */ + +/*! @name SDID - System Device Identification Register */ +/*! @{ */ +#define SIM_SDID_PINID_MASK (0xFU) +#define SIM_SDID_PINID_SHIFT (0U) +/*! PINID - Pincount identification + * 0b0000..Reserved + * 0b0001..Reserved + * 0b0010..32-pin + * 0b0011..Reserved + * 0b0100..48-pin + * 0b0101..64-pin + * 0b0110..80-pin + * 0b0111..81-pin or 121-pin + * 0b1000..100-pin + * 0b1001..121-pin + * 0b1010..144-pin + * 0b1011..Custom pinout (WLCSP) + * 0b1100..169-pin + * 0b1101..Reserved + * 0b1110..256-pin + * 0b1111..Reserved + */ +#define SIM_SDID_PINID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_PINID_SHIFT)) & SIM_SDID_PINID_MASK) +#define SIM_SDID_FAMID_MASK (0x70U) +#define SIM_SDID_FAMID_SHIFT (4U) +/*! FAMID - Kinetis family identification + * 0b000..K1x Family (without tamper) + * 0b001..K2x Family (without tamper) + * 0b010..K3x Family or K1x/K6x Family (with tamper) + * 0b011..K4x Family or K2x Family (with tamper) + * 0b100..K6x Family (without tamper) + * 0b101..K7x Family + * 0b110..Reserved + * 0b111..Reserved + */ +#define SIM_SDID_FAMID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_FAMID_SHIFT)) & SIM_SDID_FAMID_MASK) +#define SIM_SDID_DIEID_MASK (0xF80U) +#define SIM_SDID_DIEID_SHIFT (7U) +#define SIM_SDID_DIEID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_DIEID_SHIFT)) & SIM_SDID_DIEID_MASK) +#define SIM_SDID_REVID_MASK (0xF000U) +#define SIM_SDID_REVID_SHIFT (12U) +#define SIM_SDID_REVID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_REVID_SHIFT)) & SIM_SDID_REVID_MASK) +#define SIM_SDID_SERIESID_MASK (0xF00000U) +#define SIM_SDID_SERIESID_SHIFT (20U) +/*! SERIESID - Kinetis Series ID + * 0b0000..Kinetis K series + * 0b0001..Kinetis L series + * 0b0101..Kinetis W series + * 0b0110..Kinetis V series + */ +#define SIM_SDID_SERIESID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_SERIESID_SHIFT)) & SIM_SDID_SERIESID_MASK) +#define SIM_SDID_SUBFAMID_MASK (0xF000000U) +#define SIM_SDID_SUBFAMID_SHIFT (24U) +/*! SUBFAMID - Kinetis Sub-Family ID + * 0b0000..Kx0 Subfamily + * 0b0001..Kx1 Subfamily (tamper detect) + * 0b0010..Kx2 Subfamily + * 0b0011..Kx3 Subfamily (tamper detect) + * 0b0100..Kx4 Subfamily + * 0b0101..Kx5 Subfamily (tamper detect) + * 0b0110..Kx6 Subfamily + */ +#define SIM_SDID_SUBFAMID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_SUBFAMID_SHIFT)) & SIM_SDID_SUBFAMID_MASK) +#define SIM_SDID_FAMILYID_MASK (0xF0000000U) +#define SIM_SDID_FAMILYID_SHIFT (28U) +/*! FAMILYID - Kinetis Family ID + * 0b0001..K1x Family + * 0b0010..K2x Family + * 0b0011..K3x Family + * 0b0100..K4x Family + * 0b0110..K6x Family + * 0b0111..K7x Family + */ +#define SIM_SDID_FAMILYID(x) (((uint32_t)(((uint32_t)(x)) << SIM_SDID_FAMILYID_SHIFT)) & SIM_SDID_FAMILYID_MASK) +/*! @} */ + +/*! @name SCGC1 - System Clock Gating Control Register 1 */ +/*! @{ */ +#define SIM_SCGC1_I2C2_MASK (0x40U) +#define SIM_SCGC1_I2C2_SHIFT (6U) +/*! I2C2 - I2C2 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC1_I2C2(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC1_I2C2_SHIFT)) & SIM_SCGC1_I2C2_MASK) +#define SIM_SCGC1_UART4_MASK (0x400U) +#define SIM_SCGC1_UART4_SHIFT (10U) +/*! UART4 - UART4 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC1_UART4(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC1_UART4_SHIFT)) & SIM_SCGC1_UART4_MASK) +#define SIM_SCGC1_UART5_MASK (0x800U) +#define SIM_SCGC1_UART5_SHIFT (11U) +/*! UART5 - UART5 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC1_UART5(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC1_UART5_SHIFT)) & SIM_SCGC1_UART5_MASK) +/*! @} */ + +/*! @name SCGC2 - System Clock Gating Control Register 2 */ +/*! @{ */ +#define SIM_SCGC2_ENET_MASK (0x1U) +#define SIM_SCGC2_ENET_SHIFT (0U) +/*! ENET - ENET Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC2_ENET(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC2_ENET_SHIFT)) & SIM_SCGC2_ENET_MASK) +#define SIM_SCGC2_DAC0_MASK (0x1000U) +#define SIM_SCGC2_DAC0_SHIFT (12U) +/*! DAC0 - DAC0 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC2_DAC0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC2_DAC0_SHIFT)) & SIM_SCGC2_DAC0_MASK) +#define SIM_SCGC2_DAC1_MASK (0x2000U) +#define SIM_SCGC2_DAC1_SHIFT (13U) +/*! DAC1 - DAC1 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC2_DAC1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC2_DAC1_SHIFT)) & SIM_SCGC2_DAC1_MASK) +/*! @} */ + +/*! @name SCGC3 - System Clock Gating Control Register 3 */ +/*! @{ */ +#define SIM_SCGC3_RNGA_MASK (0x1U) +#define SIM_SCGC3_RNGA_SHIFT (0U) +/*! RNGA - RNGA Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC3_RNGA(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC3_RNGA_SHIFT)) & SIM_SCGC3_RNGA_MASK) +#define SIM_SCGC3_SPI2_MASK (0x1000U) +#define SIM_SCGC3_SPI2_SHIFT (12U) +/*! SPI2 - SPI2 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC3_SPI2(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC3_SPI2_SHIFT)) & SIM_SCGC3_SPI2_MASK) +#define SIM_SCGC3_SDHC_MASK (0x20000U) +#define SIM_SCGC3_SDHC_SHIFT (17U) +/*! SDHC - SDHC Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC3_SDHC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC3_SDHC_SHIFT)) & SIM_SCGC3_SDHC_MASK) +#define SIM_SCGC3_FTM2_MASK (0x1000000U) +#define SIM_SCGC3_FTM2_SHIFT (24U) +/*! FTM2 - FTM2 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC3_FTM2(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC3_FTM2_SHIFT)) & SIM_SCGC3_FTM2_MASK) +#define SIM_SCGC3_FTM3_MASK (0x2000000U) +#define SIM_SCGC3_FTM3_SHIFT (25U) +/*! FTM3 - FTM3 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC3_FTM3(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC3_FTM3_SHIFT)) & SIM_SCGC3_FTM3_MASK) +#define SIM_SCGC3_ADC1_MASK (0x8000000U) +#define SIM_SCGC3_ADC1_SHIFT (27U) +/*! ADC1 - ADC1 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC3_ADC1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC3_ADC1_SHIFT)) & SIM_SCGC3_ADC1_MASK) +/*! @} */ + +/*! @name SCGC4 - System Clock Gating Control Register 4 */ +/*! @{ */ +#define SIM_SCGC4_EWM_MASK (0x2U) +#define SIM_SCGC4_EWM_SHIFT (1U) +/*! EWM - EWM Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC4_EWM(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_EWM_SHIFT)) & SIM_SCGC4_EWM_MASK) +#define SIM_SCGC4_CMT_MASK (0x4U) +#define SIM_SCGC4_CMT_SHIFT (2U) +/*! CMT - CMT Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC4_CMT(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_CMT_SHIFT)) & SIM_SCGC4_CMT_MASK) +#define SIM_SCGC4_I2C0_MASK (0x40U) +#define SIM_SCGC4_I2C0_SHIFT (6U) +/*! I2C0 - I2C0 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC4_I2C0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_I2C0_SHIFT)) & SIM_SCGC4_I2C0_MASK) +#define SIM_SCGC4_I2C1_MASK (0x80U) +#define SIM_SCGC4_I2C1_SHIFT (7U) +/*! I2C1 - I2C1 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC4_I2C1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_I2C1_SHIFT)) & SIM_SCGC4_I2C1_MASK) +#define SIM_SCGC4_UART0_MASK (0x400U) +#define SIM_SCGC4_UART0_SHIFT (10U) +/*! UART0 - UART0 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC4_UART0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_UART0_SHIFT)) & SIM_SCGC4_UART0_MASK) +#define SIM_SCGC4_UART1_MASK (0x800U) +#define SIM_SCGC4_UART1_SHIFT (11U) +/*! UART1 - UART1 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC4_UART1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_UART1_SHIFT)) & SIM_SCGC4_UART1_MASK) +#define SIM_SCGC4_UART2_MASK (0x1000U) +#define SIM_SCGC4_UART2_SHIFT (12U) +/*! UART2 - UART2 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC4_UART2(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_UART2_SHIFT)) & SIM_SCGC4_UART2_MASK) +#define SIM_SCGC4_UART3_MASK (0x2000U) +#define SIM_SCGC4_UART3_SHIFT (13U) +/*! UART3 - UART3 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC4_UART3(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_UART3_SHIFT)) & SIM_SCGC4_UART3_MASK) +#define SIM_SCGC4_USBOTG_MASK (0x40000U) +#define SIM_SCGC4_USBOTG_SHIFT (18U) +/*! USBOTG - USB Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC4_USBOTG(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_USBOTG_SHIFT)) & SIM_SCGC4_USBOTG_MASK) +#define SIM_SCGC4_CMP_MASK (0x80000U) +#define SIM_SCGC4_CMP_SHIFT (19U) +/*! CMP - Comparator Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC4_CMP(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_CMP_SHIFT)) & SIM_SCGC4_CMP_MASK) +#define SIM_SCGC4_VREF_MASK (0x100000U) +#define SIM_SCGC4_VREF_SHIFT (20U) +/*! VREF - VREF Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC4_VREF(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC4_VREF_SHIFT)) & SIM_SCGC4_VREF_MASK) +/*! @} */ + +/*! @name SCGC5 - System Clock Gating Control Register 5 */ +/*! @{ */ +#define SIM_SCGC5_LPTMR_MASK (0x1U) +#define SIM_SCGC5_LPTMR_SHIFT (0U) +/*! LPTMR - Low Power Timer Access Control + * 0b0..Access disabled + * 0b1..Access enabled + */ +#define SIM_SCGC5_LPTMR(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_LPTMR_SHIFT)) & SIM_SCGC5_LPTMR_MASK) +#define SIM_SCGC5_PORTA_MASK (0x200U) +#define SIM_SCGC5_PORTA_SHIFT (9U) +/*! PORTA - Port A Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC5_PORTA(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_PORTA_SHIFT)) & SIM_SCGC5_PORTA_MASK) +#define SIM_SCGC5_PORTB_MASK (0x400U) +#define SIM_SCGC5_PORTB_SHIFT (10U) +/*! PORTB - Port B Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC5_PORTB(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_PORTB_SHIFT)) & SIM_SCGC5_PORTB_MASK) +#define SIM_SCGC5_PORTC_MASK (0x800U) +#define SIM_SCGC5_PORTC_SHIFT (11U) +/*! PORTC - Port C Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC5_PORTC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_PORTC_SHIFT)) & SIM_SCGC5_PORTC_MASK) +#define SIM_SCGC5_PORTD_MASK (0x1000U) +#define SIM_SCGC5_PORTD_SHIFT (12U) +/*! PORTD - Port D Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC5_PORTD(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_PORTD_SHIFT)) & SIM_SCGC5_PORTD_MASK) +#define SIM_SCGC5_PORTE_MASK (0x2000U) +#define SIM_SCGC5_PORTE_SHIFT (13U) +/*! PORTE - Port E Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC5_PORTE(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC5_PORTE_SHIFT)) & SIM_SCGC5_PORTE_MASK) +/*! @} */ + +/*! @name SCGC6 - System Clock Gating Control Register 6 */ +/*! @{ */ +#define SIM_SCGC6_FTF_MASK (0x1U) +#define SIM_SCGC6_FTF_SHIFT (0U) +/*! FTF - Flash Memory Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC6_FTF(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_FTF_SHIFT)) & SIM_SCGC6_FTF_MASK) +#define SIM_SCGC6_DMAMUX_MASK (0x2U) +#define SIM_SCGC6_DMAMUX_SHIFT (1U) +/*! DMAMUX - DMA Mux Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC6_DMAMUX(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_DMAMUX_SHIFT)) & SIM_SCGC6_DMAMUX_MASK) +#define SIM_SCGC6_FLEXCAN0_MASK (0x10U) +#define SIM_SCGC6_FLEXCAN0_SHIFT (4U) +/*! FLEXCAN0 - FlexCAN0 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC6_FLEXCAN0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_FLEXCAN0_SHIFT)) & SIM_SCGC6_FLEXCAN0_MASK) +#define SIM_SCGC6_RNGA_MASK (0x200U) +#define SIM_SCGC6_RNGA_SHIFT (9U) +#define SIM_SCGC6_RNGA(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_RNGA_SHIFT)) & SIM_SCGC6_RNGA_MASK) +#define SIM_SCGC6_SPI0_MASK (0x1000U) +#define SIM_SCGC6_SPI0_SHIFT (12U) +/*! SPI0 - SPI0 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC6_SPI0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_SPI0_SHIFT)) & SIM_SCGC6_SPI0_MASK) +#define SIM_SCGC6_SPI1_MASK (0x2000U) +#define SIM_SCGC6_SPI1_SHIFT (13U) +/*! SPI1 - SPI1 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC6_SPI1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_SPI1_SHIFT)) & SIM_SCGC6_SPI1_MASK) +#define SIM_SCGC6_I2S_MASK (0x8000U) +#define SIM_SCGC6_I2S_SHIFT (15U) +/*! I2S - I2S Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC6_I2S(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_I2S_SHIFT)) & SIM_SCGC6_I2S_MASK) +#define SIM_SCGC6_CRC_MASK (0x40000U) +#define SIM_SCGC6_CRC_SHIFT (18U) +/*! CRC - CRC Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC6_CRC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_CRC_SHIFT)) & SIM_SCGC6_CRC_MASK) +#define SIM_SCGC6_USBDCD_MASK (0x200000U) +#define SIM_SCGC6_USBDCD_SHIFT (21U) +/*! USBDCD - USB DCD Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC6_USBDCD(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_USBDCD_SHIFT)) & SIM_SCGC6_USBDCD_MASK) +#define SIM_SCGC6_PDB_MASK (0x400000U) +#define SIM_SCGC6_PDB_SHIFT (22U) +/*! PDB - PDB Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC6_PDB(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_PDB_SHIFT)) & SIM_SCGC6_PDB_MASK) +#define SIM_SCGC6_PIT_MASK (0x800000U) +#define SIM_SCGC6_PIT_SHIFT (23U) +/*! PIT - PIT Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC6_PIT(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_PIT_SHIFT)) & SIM_SCGC6_PIT_MASK) +#define SIM_SCGC6_FTM0_MASK (0x1000000U) +#define SIM_SCGC6_FTM0_SHIFT (24U) +/*! FTM0 - FTM0 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC6_FTM0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_FTM0_SHIFT)) & SIM_SCGC6_FTM0_MASK) +#define SIM_SCGC6_FTM1_MASK (0x2000000U) +#define SIM_SCGC6_FTM1_SHIFT (25U) +/*! FTM1 - FTM1 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC6_FTM1(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_FTM1_SHIFT)) & SIM_SCGC6_FTM1_MASK) +#define SIM_SCGC6_FTM2_MASK (0x4000000U) +#define SIM_SCGC6_FTM2_SHIFT (26U) +/*! FTM2 - FTM2 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC6_FTM2(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_FTM2_SHIFT)) & SIM_SCGC6_FTM2_MASK) +#define SIM_SCGC6_ADC0_MASK (0x8000000U) +#define SIM_SCGC6_ADC0_SHIFT (27U) +/*! ADC0 - ADC0 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC6_ADC0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_ADC0_SHIFT)) & SIM_SCGC6_ADC0_MASK) +#define SIM_SCGC6_RTC_MASK (0x20000000U) +#define SIM_SCGC6_RTC_SHIFT (29U) +/*! RTC - RTC Access Control + * 0b0..Access and interrupts disabled + * 0b1..Access and interrupts enabled + */ +#define SIM_SCGC6_RTC(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_RTC_SHIFT)) & SIM_SCGC6_RTC_MASK) +#define SIM_SCGC6_DAC0_MASK (0x80000000U) +#define SIM_SCGC6_DAC0_SHIFT (31U) +/*! DAC0 - DAC0 Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC6_DAC0(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC6_DAC0_SHIFT)) & SIM_SCGC6_DAC0_MASK) +/*! @} */ + +/*! @name SCGC7 - System Clock Gating Control Register 7 */ +/*! @{ */ +#define SIM_SCGC7_FLEXBUS_MASK (0x1U) +#define SIM_SCGC7_FLEXBUS_SHIFT (0U) +/*! FLEXBUS - FlexBus Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC7_FLEXBUS(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC7_FLEXBUS_SHIFT)) & SIM_SCGC7_FLEXBUS_MASK) +#define SIM_SCGC7_DMA_MASK (0x2U) +#define SIM_SCGC7_DMA_SHIFT (1U) +/*! DMA - DMA Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC7_DMA(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC7_DMA_SHIFT)) & SIM_SCGC7_DMA_MASK) +#define SIM_SCGC7_MPU_MASK (0x4U) +#define SIM_SCGC7_MPU_SHIFT (2U) +/*! MPU - MPU Clock Gate Control + * 0b0..Clock disabled + * 0b1..Clock enabled + */ +#define SIM_SCGC7_MPU(x) (((uint32_t)(((uint32_t)(x)) << SIM_SCGC7_MPU_SHIFT)) & SIM_SCGC7_MPU_MASK) +/*! @} */ + +/*! @name CLKDIV1 - System Clock Divider Register 1 */ +/*! @{ */ +#define SIM_CLKDIV1_OUTDIV4_MASK (0xF0000U) +#define SIM_CLKDIV1_OUTDIV4_SHIFT (16U) +/*! OUTDIV4 - Clock 4 output divider value + * 0b0000..Divide-by-1. + * 0b0001..Divide-by-2. + * 0b0010..Divide-by-3. + * 0b0011..Divide-by-4. + * 0b0100..Divide-by-5. + * 0b0101..Divide-by-6. + * 0b0110..Divide-by-7. + * 0b0111..Divide-by-8. + * 0b1000..Divide-by-9. + * 0b1001..Divide-by-10. + * 0b1010..Divide-by-11. + * 0b1011..Divide-by-12. + * 0b1100..Divide-by-13. + * 0b1101..Divide-by-14. + * 0b1110..Divide-by-15. + * 0b1111..Divide-by-16. + */ +#define SIM_CLKDIV1_OUTDIV4(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV1_OUTDIV4_SHIFT)) & SIM_CLKDIV1_OUTDIV4_MASK) +#define SIM_CLKDIV1_OUTDIV3_MASK (0xF00000U) +#define SIM_CLKDIV1_OUTDIV3_SHIFT (20U) +/*! OUTDIV3 - Clock 3 output divider value + * 0b0000..Divide-by-1. + * 0b0001..Divide-by-2. + * 0b0010..Divide-by-3. + * 0b0011..Divide-by-4. + * 0b0100..Divide-by-5. + * 0b0101..Divide-by-6. + * 0b0110..Divide-by-7. + * 0b0111..Divide-by-8. + * 0b1000..Divide-by-9. + * 0b1001..Divide-by-10. + * 0b1010..Divide-by-11. + * 0b1011..Divide-by-12. + * 0b1100..Divide-by-13. + * 0b1101..Divide-by-14. + * 0b1110..Divide-by-15. + * 0b1111..Divide-by-16. + */ +#define SIM_CLKDIV1_OUTDIV3(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV1_OUTDIV3_SHIFT)) & SIM_CLKDIV1_OUTDIV3_MASK) +#define SIM_CLKDIV1_OUTDIV2_MASK (0xF000000U) +#define SIM_CLKDIV1_OUTDIV2_SHIFT (24U) +/*! OUTDIV2 - Clock 2 output divider value + * 0b0000..Divide-by-1. + * 0b0001..Divide-by-2. + * 0b0010..Divide-by-3. + * 0b0011..Divide-by-4. + * 0b0100..Divide-by-5. + * 0b0101..Divide-by-6. + * 0b0110..Divide-by-7. + * 0b0111..Divide-by-8. + * 0b1000..Divide-by-9. + * 0b1001..Divide-by-10. + * 0b1010..Divide-by-11. + * 0b1011..Divide-by-12. + * 0b1100..Divide-by-13. + * 0b1101..Divide-by-14. + * 0b1110..Divide-by-15. + * 0b1111..Divide-by-16. + */ +#define SIM_CLKDIV1_OUTDIV2(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV1_OUTDIV2_SHIFT)) & SIM_CLKDIV1_OUTDIV2_MASK) +#define SIM_CLKDIV1_OUTDIV1_MASK (0xF0000000U) +#define SIM_CLKDIV1_OUTDIV1_SHIFT (28U) +/*! OUTDIV1 - Clock 1 output divider value + * 0b0000..Divide-by-1. + * 0b0001..Divide-by-2. + * 0b0010..Divide-by-3. + * 0b0011..Divide-by-4. + * 0b0100..Divide-by-5. + * 0b0101..Divide-by-6. + * 0b0110..Divide-by-7. + * 0b0111..Divide-by-8. + * 0b1000..Divide-by-9. + * 0b1001..Divide-by-10. + * 0b1010..Divide-by-11. + * 0b1011..Divide-by-12. + * 0b1100..Divide-by-13. + * 0b1101..Divide-by-14. + * 0b1110..Divide-by-15. + * 0b1111..Divide-by-16. + */ +#define SIM_CLKDIV1_OUTDIV1(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV1_OUTDIV1_SHIFT)) & SIM_CLKDIV1_OUTDIV1_MASK) +/*! @} */ + +/*! @name CLKDIV2 - System Clock Divider Register 2 */ +/*! @{ */ +#define SIM_CLKDIV2_USBFRAC_MASK (0x1U) +#define SIM_CLKDIV2_USBFRAC_SHIFT (0U) +#define SIM_CLKDIV2_USBFRAC(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV2_USBFRAC_SHIFT)) & SIM_CLKDIV2_USBFRAC_MASK) +#define SIM_CLKDIV2_USBDIV_MASK (0xEU) +#define SIM_CLKDIV2_USBDIV_SHIFT (1U) +#define SIM_CLKDIV2_USBDIV(x) (((uint32_t)(((uint32_t)(x)) << SIM_CLKDIV2_USBDIV_SHIFT)) & SIM_CLKDIV2_USBDIV_MASK) +/*! @} */ + +/*! @name FCFG1 - Flash Configuration Register 1 */ +/*! @{ */ +#define SIM_FCFG1_FLASHDIS_MASK (0x1U) +#define SIM_FCFG1_FLASHDIS_SHIFT (0U) +/*! FLASHDIS - Flash Disable + * 0b0..Flash is enabled + * 0b1..Flash is disabled + */ +#define SIM_FCFG1_FLASHDIS(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG1_FLASHDIS_SHIFT)) & SIM_FCFG1_FLASHDIS_MASK) +#define SIM_FCFG1_FLASHDOZE_MASK (0x2U) +#define SIM_FCFG1_FLASHDOZE_SHIFT (1U) +/*! FLASHDOZE - Flash Doze + * 0b0..Flash remains enabled during Wait mode + * 0b1..Flash is disabled for the duration of Wait mode + */ +#define SIM_FCFG1_FLASHDOZE(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG1_FLASHDOZE_SHIFT)) & SIM_FCFG1_FLASHDOZE_MASK) +#define SIM_FCFG1_DEPART_MASK (0xF00U) +#define SIM_FCFG1_DEPART_SHIFT (8U) +#define SIM_FCFG1_DEPART(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG1_DEPART_SHIFT)) & SIM_FCFG1_DEPART_MASK) +#define SIM_FCFG1_EESIZE_MASK (0xF0000U) +#define SIM_FCFG1_EESIZE_SHIFT (16U) +/*! EESIZE - EEPROM size + * 0b0000..16 KB + * 0b0001..8 KB + * 0b0010..4 KB + * 0b0011..2 KB + * 0b0100..1 KB + * 0b0101..512 Bytes + * 0b0110..256 Bytes + * 0b0111..128 Bytes + * 0b1000..64 Bytes + * 0b1001..32 Bytes + * 0b1111..0 Bytes + */ +#define SIM_FCFG1_EESIZE(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG1_EESIZE_SHIFT)) & SIM_FCFG1_EESIZE_MASK) +#define SIM_FCFG1_PFSIZE_MASK (0xF000000U) +#define SIM_FCFG1_PFSIZE_SHIFT (24U) +/*! PFSIZE - Program flash size + * 0b0011..32 KB of program flash memory + * 0b0101..64 KB of program flash memory + * 0b0111..128 KB of program flash memory + * 0b1001..256 KB of program flash memory + * 0b1011..512 KB of program flash memory + * 0b1101..1024 KB of program flash memory + * 0b1111..1024 KB of program flash memory + */ +#define SIM_FCFG1_PFSIZE(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG1_PFSIZE_SHIFT)) & SIM_FCFG1_PFSIZE_MASK) +#define SIM_FCFG1_NVMSIZE_MASK (0xF0000000U) +#define SIM_FCFG1_NVMSIZE_SHIFT (28U) +/*! NVMSIZE - FlexNVM size + * 0b0000..0 KB of FlexNVM + * 0b0011..32 KB of FlexNVM + * 0b0101..64 KB of FlexNVM + * 0b0111..128 KB of FlexNVM + * 0b1001..256 KB of FlexNVM + * 0b1011..512 KB of FlexNVM + * 0b1111..512 KB of FlexNVM + */ +#define SIM_FCFG1_NVMSIZE(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG1_NVMSIZE_SHIFT)) & SIM_FCFG1_NVMSIZE_MASK) +/*! @} */ + +/*! @name FCFG2 - Flash Configuration Register 2 */ +/*! @{ */ +#define SIM_FCFG2_MAXADDR1_MASK (0x7F0000U) +#define SIM_FCFG2_MAXADDR1_SHIFT (16U) +#define SIM_FCFG2_MAXADDR1(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG2_MAXADDR1_SHIFT)) & SIM_FCFG2_MAXADDR1_MASK) +#define SIM_FCFG2_PFLSH_MASK (0x800000U) +#define SIM_FCFG2_PFLSH_SHIFT (23U) +/*! PFLSH - Program flash only + * 0b0..Device supports FlexNVM + * 0b1..Program Flash only, device does not support FlexNVM + */ +#define SIM_FCFG2_PFLSH(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG2_PFLSH_SHIFT)) & SIM_FCFG2_PFLSH_MASK) +#define SIM_FCFG2_MAXADDR0_MASK (0x7F000000U) +#define SIM_FCFG2_MAXADDR0_SHIFT (24U) +#define SIM_FCFG2_MAXADDR0(x) (((uint32_t)(((uint32_t)(x)) << SIM_FCFG2_MAXADDR0_SHIFT)) & SIM_FCFG2_MAXADDR0_MASK) +/*! @} */ + +/*! @name UIDH - Unique Identification Register High */ +/*! @{ */ +#define SIM_UIDH_UID_MASK (0xFFFFFFFFU) +#define SIM_UIDH_UID_SHIFT (0U) +#define SIM_UIDH_UID(x) (((uint32_t)(((uint32_t)(x)) << SIM_UIDH_UID_SHIFT)) & SIM_UIDH_UID_MASK) +/*! @} */ + +/*! @name UIDMH - Unique Identification Register Mid-High */ +/*! @{ */ +#define SIM_UIDMH_UID_MASK (0xFFFFFFFFU) +#define SIM_UIDMH_UID_SHIFT (0U) +#define SIM_UIDMH_UID(x) (((uint32_t)(((uint32_t)(x)) << SIM_UIDMH_UID_SHIFT)) & SIM_UIDMH_UID_MASK) +/*! @} */ + +/*! @name UIDML - Unique Identification Register Mid Low */ +/*! @{ */ +#define SIM_UIDML_UID_MASK (0xFFFFFFFFU) +#define SIM_UIDML_UID_SHIFT (0U) +#define SIM_UIDML_UID(x) (((uint32_t)(((uint32_t)(x)) << SIM_UIDML_UID_SHIFT)) & SIM_UIDML_UID_MASK) +/*! @} */ + +/*! @name UIDL - Unique Identification Register Low */ +/*! @{ */ +#define SIM_UIDL_UID_MASK (0xFFFFFFFFU) +#define SIM_UIDL_UID_SHIFT (0U) +#define SIM_UIDL_UID(x) (((uint32_t)(((uint32_t)(x)) << SIM_UIDL_UID_SHIFT)) & SIM_UIDL_UID_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group SIM_Register_Masks */ + + +/* SIM - Peripheral instance base addresses */ +/** Peripheral SIM base address */ +#define SIM_BASE (0x40047000u) +/** Peripheral SIM base pointer */ +#define SIM ((SIM_Type *)SIM_BASE) +/** Array initializer of SIM peripheral base addresses */ +#define SIM_BASE_ADDRS { SIM_BASE } +/** Array initializer of SIM peripheral base pointers */ +#define SIM_BASE_PTRS { SIM } + +/*! + * @} + */ /* end of group SIM_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SMC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SMC_Peripheral_Access_Layer SMC Peripheral Access Layer + * @{ + */ + +/** SMC - Register Layout Typedef */ +typedef struct { + __IO uint8_t PMPROT; /**< Power Mode Protection register, offset: 0x0 */ + __IO uint8_t PMCTRL; /**< Power Mode Control register, offset: 0x1 */ + __IO uint8_t VLLSCTRL; /**< VLLS Control register, offset: 0x2 */ + __I uint8_t PMSTAT; /**< Power Mode Status register, offset: 0x3 */ +} SMC_Type; + +/* ---------------------------------------------------------------------------- + -- SMC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SMC_Register_Masks SMC Register Masks + * @{ + */ + +/*! @name PMPROT - Power Mode Protection register */ +/*! @{ */ +#define SMC_PMPROT_AVLLS_MASK (0x2U) +#define SMC_PMPROT_AVLLS_SHIFT (1U) +/*! AVLLS - Allow Very-Low-Leakage Stop Mode + * 0b0..Any VLLSx mode is not allowed + * 0b1..Any VLLSx mode is allowed + */ +#define SMC_PMPROT_AVLLS(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMPROT_AVLLS_SHIFT)) & SMC_PMPROT_AVLLS_MASK) +#define SMC_PMPROT_ALLS_MASK (0x8U) +#define SMC_PMPROT_ALLS_SHIFT (3U) +/*! ALLS - Allow Low-Leakage Stop Mode + * 0b0..LLS is not allowed + * 0b1..LLS is allowed + */ +#define SMC_PMPROT_ALLS(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMPROT_ALLS_SHIFT)) & SMC_PMPROT_ALLS_MASK) +#define SMC_PMPROT_AVLP_MASK (0x20U) +#define SMC_PMPROT_AVLP_SHIFT (5U) +/*! AVLP - Allow Very-Low-Power Modes + * 0b0..VLPR, VLPW, and VLPS are not allowed. + * 0b1..VLPR, VLPW, and VLPS are allowed. + */ +#define SMC_PMPROT_AVLP(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMPROT_AVLP_SHIFT)) & SMC_PMPROT_AVLP_MASK) +/*! @} */ + +/*! @name PMCTRL - Power Mode Control register */ +/*! @{ */ +#define SMC_PMCTRL_STOPM_MASK (0x7U) +#define SMC_PMCTRL_STOPM_SHIFT (0U) +/*! STOPM - Stop Mode Control + * 0b000..Normal Stop (STOP) + * 0b001..Reserved + * 0b010..Very-Low-Power Stop (VLPS) + * 0b011..Low-Leakage Stop (LLS) + * 0b100..Very-Low-Leakage Stop (VLLSx) + * 0b101..Reserved + * 0b110..Reseved + * 0b111..Reserved + */ +#define SMC_PMCTRL_STOPM(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMCTRL_STOPM_SHIFT)) & SMC_PMCTRL_STOPM_MASK) +#define SMC_PMCTRL_STOPA_MASK (0x8U) +#define SMC_PMCTRL_STOPA_SHIFT (3U) +/*! STOPA - Stop Aborted + * 0b0..The previous stop mode entry was successsful. + * 0b1..The previous stop mode entry was aborted. + */ +#define SMC_PMCTRL_STOPA(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMCTRL_STOPA_SHIFT)) & SMC_PMCTRL_STOPA_MASK) +#define SMC_PMCTRL_RUNM_MASK (0x60U) +#define SMC_PMCTRL_RUNM_SHIFT (5U) +/*! RUNM - Run Mode Control + * 0b00..Normal Run mode (RUN) + * 0b01..Reserved + * 0b10..Very-Low-Power Run mode (VLPR) + * 0b11..Reserved + */ +#define SMC_PMCTRL_RUNM(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMCTRL_RUNM_SHIFT)) & SMC_PMCTRL_RUNM_MASK) +#define SMC_PMCTRL_LPWUI_MASK (0x80U) +#define SMC_PMCTRL_LPWUI_SHIFT (7U) +/*! LPWUI - Low-Power Wake Up On Interrupt + * 0b0..The system remains in a VLP mode on an interrupt + * 0b1..The system exits to Normal RUN mode on an interrupt + */ +#define SMC_PMCTRL_LPWUI(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMCTRL_LPWUI_SHIFT)) & SMC_PMCTRL_LPWUI_MASK) +/*! @} */ + +/*! @name VLLSCTRL - VLLS Control register */ +/*! @{ */ +#define SMC_VLLSCTRL_VLLSM_MASK (0x7U) +#define SMC_VLLSCTRL_VLLSM_SHIFT (0U) +/*! VLLSM - VLLS Mode Control + * 0b000..VLLS0 + * 0b001..VLLS1 + * 0b010..VLLS2 + * 0b011..VLLS3 + * 0b100..Reserved + * 0b101..Reserved + * 0b110..Reserved + * 0b111..Reserved + */ +#define SMC_VLLSCTRL_VLLSM(x) (((uint8_t)(((uint8_t)(x)) << SMC_VLLSCTRL_VLLSM_SHIFT)) & SMC_VLLSCTRL_VLLSM_MASK) +#define SMC_VLLSCTRL_PORPO_MASK (0x20U) +#define SMC_VLLSCTRL_PORPO_SHIFT (5U) +/*! PORPO - POR Power Option + * 0b0..POR detect circuit is enabled in VLLS0. + * 0b1..POR detect circuit is disabled in VLLS0. + */ +#define SMC_VLLSCTRL_PORPO(x) (((uint8_t)(((uint8_t)(x)) << SMC_VLLSCTRL_PORPO_SHIFT)) & SMC_VLLSCTRL_PORPO_MASK) +/*! @} */ + +/*! @name PMSTAT - Power Mode Status register */ +/*! @{ */ +#define SMC_PMSTAT_PMSTAT_MASK (0x7FU) +#define SMC_PMSTAT_PMSTAT_SHIFT (0U) +#define SMC_PMSTAT_PMSTAT(x) (((uint8_t)(((uint8_t)(x)) << SMC_PMSTAT_PMSTAT_SHIFT)) & SMC_PMSTAT_PMSTAT_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group SMC_Register_Masks */ + + +/* SMC - Peripheral instance base addresses */ +/** Peripheral SMC base address */ +#define SMC_BASE (0x4007E000u) +/** Peripheral SMC base pointer */ +#define SMC ((SMC_Type *)SMC_BASE) +/** Array initializer of SMC peripheral base addresses */ +#define SMC_BASE_ADDRS { SMC_BASE } +/** Array initializer of SMC peripheral base pointers */ +#define SMC_BASE_PTRS { SMC } + +/*! + * @} + */ /* end of group SMC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SPI Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SPI_Peripheral_Access_Layer SPI Peripheral Access Layer + * @{ + */ + +/** SPI - Register Layout Typedef */ +typedef struct { + __IO uint32_t MCR; /**< Module Configuration Register, offset: 0x0 */ + uint8_t RESERVED_0[4]; + __IO uint32_t TCR; /**< Transfer Count Register, offset: 0x8 */ + union { /* offset: 0xC */ + __IO uint32_t CTAR[2]; /**< Clock and Transfer Attributes Register (In Master Mode), array offset: 0xC, array step: 0x4 */ + __IO uint32_t CTAR_SLAVE[1]; /**< Clock and Transfer Attributes Register (In Slave Mode), array offset: 0xC, array step: 0x4 */ + }; + uint8_t RESERVED_1[24]; + __IO uint32_t SR; /**< Status Register, offset: 0x2C */ + __IO uint32_t RSER; /**< DMA/Interrupt Request Select and Enable Register, offset: 0x30 */ + union { /* offset: 0x34 */ + __IO uint32_t PUSHR; /**< PUSH TX FIFO Register In Master Mode, offset: 0x34 */ + __IO uint32_t PUSHR_SLAVE; /**< PUSH TX FIFO Register In Slave Mode, offset: 0x34 */ + }; + __I uint32_t POPR; /**< POP RX FIFO Register, offset: 0x38 */ + __I uint32_t TXFR0; /**< Transmit FIFO Registers, offset: 0x3C */ + __I uint32_t TXFR1; /**< Transmit FIFO Registers, offset: 0x40 */ + __I uint32_t TXFR2; /**< Transmit FIFO Registers, offset: 0x44 */ + __I uint32_t TXFR3; /**< Transmit FIFO Registers, offset: 0x48 */ + uint8_t RESERVED_2[48]; + __I uint32_t RXFR0; /**< Receive FIFO Registers, offset: 0x7C */ + __I uint32_t RXFR1; /**< Receive FIFO Registers, offset: 0x80 */ + __I uint32_t RXFR2; /**< Receive FIFO Registers, offset: 0x84 */ + __I uint32_t RXFR3; /**< Receive FIFO Registers, offset: 0x88 */ +} SPI_Type; + +/* ---------------------------------------------------------------------------- + -- SPI Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SPI_Register_Masks SPI Register Masks + * @{ + */ + +/*! @name MCR - Module Configuration Register */ +/*! @{ */ +#define SPI_MCR_HALT_MASK (0x1U) +#define SPI_MCR_HALT_SHIFT (0U) +/*! HALT - Halt + * 0b0..Start transfers. + * 0b1..Stop transfers. + */ +#define SPI_MCR_HALT(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_HALT_SHIFT)) & SPI_MCR_HALT_MASK) +#define SPI_MCR_SMPL_PT_MASK (0x300U) +#define SPI_MCR_SMPL_PT_SHIFT (8U) +/*! SMPL_PT - Sample Point + * 0b00..0 protocol clock cycles between SCK edge and SIN sample + * 0b01..1 protocol clock cycle between SCK edge and SIN sample + * 0b10..2 protocol clock cycles between SCK edge and SIN sample + * 0b11..Reserved + */ +#define SPI_MCR_SMPL_PT(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_SMPL_PT_SHIFT)) & SPI_MCR_SMPL_PT_MASK) +#define SPI_MCR_CLR_RXF_MASK (0x400U) +#define SPI_MCR_CLR_RXF_SHIFT (10U) +/*! CLR_RXF + * 0b0..Do not clear the RX FIFO counter. + * 0b1..Clear the RX FIFO counter. + */ +#define SPI_MCR_CLR_RXF(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_CLR_RXF_SHIFT)) & SPI_MCR_CLR_RXF_MASK) +#define SPI_MCR_CLR_TXF_MASK (0x800U) +#define SPI_MCR_CLR_TXF_SHIFT (11U) +/*! CLR_TXF - Clear TX FIFO + * 0b0..Do not clear the TX FIFO counter. + * 0b1..Clear the TX FIFO counter. + */ +#define SPI_MCR_CLR_TXF(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_CLR_TXF_SHIFT)) & SPI_MCR_CLR_TXF_MASK) +#define SPI_MCR_DIS_RXF_MASK (0x1000U) +#define SPI_MCR_DIS_RXF_SHIFT (12U) +/*! DIS_RXF - Disable Receive FIFO + * 0b0..RX FIFO is enabled. + * 0b1..RX FIFO is disabled. + */ +#define SPI_MCR_DIS_RXF(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_DIS_RXF_SHIFT)) & SPI_MCR_DIS_RXF_MASK) +#define SPI_MCR_DIS_TXF_MASK (0x2000U) +#define SPI_MCR_DIS_TXF_SHIFT (13U) +/*! DIS_TXF - Disable Transmit FIFO + * 0b0..TX FIFO is enabled. + * 0b1..TX FIFO is disabled. + */ +#define SPI_MCR_DIS_TXF(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_DIS_TXF_SHIFT)) & SPI_MCR_DIS_TXF_MASK) +#define SPI_MCR_MDIS_MASK (0x4000U) +#define SPI_MCR_MDIS_SHIFT (14U) +/*! MDIS - Module Disable + * 0b0..Enables the module clocks. + * 0b1..Allows external logic to disable the module clocks. + */ +#define SPI_MCR_MDIS(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_MDIS_SHIFT)) & SPI_MCR_MDIS_MASK) +#define SPI_MCR_DOZE_MASK (0x8000U) +#define SPI_MCR_DOZE_SHIFT (15U) +/*! DOZE - Doze Enable + * 0b0..Doze mode has no effect on the module. + * 0b1..Doze mode disables the module. + */ +#define SPI_MCR_DOZE(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_DOZE_SHIFT)) & SPI_MCR_DOZE_MASK) +#define SPI_MCR_PCSIS_MASK (0x3F0000U) +#define SPI_MCR_PCSIS_SHIFT (16U) +/*! PCSIS - Peripheral Chip Select x Inactive State + * 0b000000..The inactive state of PCSx is low. + * 0b000001..The inactive state of PCSx is high. + */ +#define SPI_MCR_PCSIS(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_PCSIS_SHIFT)) & SPI_MCR_PCSIS_MASK) +#define SPI_MCR_ROOE_MASK (0x1000000U) +#define SPI_MCR_ROOE_SHIFT (24U) +/*! ROOE - Receive FIFO Overflow Overwrite Enable + * 0b0..Incoming data is ignored. + * 0b1..Incoming data is shifted into the shift register. + */ +#define SPI_MCR_ROOE(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_ROOE_SHIFT)) & SPI_MCR_ROOE_MASK) +#define SPI_MCR_PCSSE_MASK (0x2000000U) +#define SPI_MCR_PCSSE_SHIFT (25U) +/*! PCSSE - Peripheral Chip Select Strobe Enable + * 0b0..PCS5/ PCSS is used as the Peripheral Chip Select[5] signal. + * 0b1..PCS5/ PCSS is used as an active-low PCS Strobe signal. + */ +#define SPI_MCR_PCSSE(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_PCSSE_SHIFT)) & SPI_MCR_PCSSE_MASK) +#define SPI_MCR_MTFE_MASK (0x4000000U) +#define SPI_MCR_MTFE_SHIFT (26U) +/*! MTFE - Modified Timing Format Enable + * 0b0..Modified SPI transfer format disabled. + * 0b1..Modified SPI transfer format enabled. + */ +#define SPI_MCR_MTFE(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_MTFE_SHIFT)) & SPI_MCR_MTFE_MASK) +#define SPI_MCR_FRZ_MASK (0x8000000U) +#define SPI_MCR_FRZ_SHIFT (27U) +/*! FRZ - Freeze + * 0b0..Do not halt serial transfers in Debug mode. + * 0b1..Halt serial transfers in Debug mode. + */ +#define SPI_MCR_FRZ(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_FRZ_SHIFT)) & SPI_MCR_FRZ_MASK) +#define SPI_MCR_DCONF_MASK (0x30000000U) +#define SPI_MCR_DCONF_SHIFT (28U) +/*! DCONF - SPI Configuration. + * 0b00..SPI + * 0b01..Reserved + * 0b10..Reserved + * 0b11..Reserved + */ +#define SPI_MCR_DCONF(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_DCONF_SHIFT)) & SPI_MCR_DCONF_MASK) +#define SPI_MCR_CONT_SCKE_MASK (0x40000000U) +#define SPI_MCR_CONT_SCKE_SHIFT (30U) +/*! CONT_SCKE - Continuous SCK Enable + * 0b0..Continuous SCK disabled. + * 0b1..Continuous SCK enabled. + */ +#define SPI_MCR_CONT_SCKE(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_CONT_SCKE_SHIFT)) & SPI_MCR_CONT_SCKE_MASK) +#define SPI_MCR_MSTR_MASK (0x80000000U) +#define SPI_MCR_MSTR_SHIFT (31U) +/*! MSTR - Master/Slave Mode Select + * 0b0..Enables Slave mode + * 0b1..Enables Master mode + */ +#define SPI_MCR_MSTR(x) (((uint32_t)(((uint32_t)(x)) << SPI_MCR_MSTR_SHIFT)) & SPI_MCR_MSTR_MASK) +/*! @} */ + +/*! @name TCR - Transfer Count Register */ +/*! @{ */ +#define SPI_TCR_SPI_TCNT_MASK (0xFFFF0000U) +#define SPI_TCR_SPI_TCNT_SHIFT (16U) +#define SPI_TCR_SPI_TCNT(x) (((uint32_t)(((uint32_t)(x)) << SPI_TCR_SPI_TCNT_SHIFT)) & SPI_TCR_SPI_TCNT_MASK) +/*! @} */ + +/*! @name CTAR - Clock and Transfer Attributes Register (In Master Mode) */ +/*! @{ */ +#define SPI_CTAR_BR_MASK (0xFU) +#define SPI_CTAR_BR_SHIFT (0U) +#define SPI_CTAR_BR(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_BR_SHIFT)) & SPI_CTAR_BR_MASK) +#define SPI_CTAR_DT_MASK (0xF0U) +#define SPI_CTAR_DT_SHIFT (4U) +#define SPI_CTAR_DT(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_DT_SHIFT)) & SPI_CTAR_DT_MASK) +#define SPI_CTAR_ASC_MASK (0xF00U) +#define SPI_CTAR_ASC_SHIFT (8U) +#define SPI_CTAR_ASC(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_ASC_SHIFT)) & SPI_CTAR_ASC_MASK) +#define SPI_CTAR_CSSCK_MASK (0xF000U) +#define SPI_CTAR_CSSCK_SHIFT (12U) +#define SPI_CTAR_CSSCK(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_CSSCK_SHIFT)) & SPI_CTAR_CSSCK_MASK) +#define SPI_CTAR_PBR_MASK (0x30000U) +#define SPI_CTAR_PBR_SHIFT (16U) +/*! PBR - Baud Rate Prescaler + * 0b00..Baud Rate Prescaler value is 2. + * 0b01..Baud Rate Prescaler value is 3. + * 0b10..Baud Rate Prescaler value is 5. + * 0b11..Baud Rate Prescaler value is 7. + */ +#define SPI_CTAR_PBR(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_PBR_SHIFT)) & SPI_CTAR_PBR_MASK) +#define SPI_CTAR_PDT_MASK (0xC0000U) +#define SPI_CTAR_PDT_SHIFT (18U) +/*! PDT - Delay after Transfer Prescaler + * 0b00..Delay after Transfer Prescaler value is 1. + * 0b01..Delay after Transfer Prescaler value is 3. + * 0b10..Delay after Transfer Prescaler value is 5. + * 0b11..Delay after Transfer Prescaler value is 7. + */ +#define SPI_CTAR_PDT(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_PDT_SHIFT)) & SPI_CTAR_PDT_MASK) +#define SPI_CTAR_PASC_MASK (0x300000U) +#define SPI_CTAR_PASC_SHIFT (20U) +/*! PASC - After SCK Delay Prescaler + * 0b00..Delay after Transfer Prescaler value is 1. + * 0b01..Delay after Transfer Prescaler value is 3. + * 0b10..Delay after Transfer Prescaler value is 5. + * 0b11..Delay after Transfer Prescaler value is 7. + */ +#define SPI_CTAR_PASC(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_PASC_SHIFT)) & SPI_CTAR_PASC_MASK) +#define SPI_CTAR_PCSSCK_MASK (0xC00000U) +#define SPI_CTAR_PCSSCK_SHIFT (22U) +/*! PCSSCK - PCS to SCK Delay Prescaler + * 0b00..PCS to SCK Prescaler value is 1. + * 0b01..PCS to SCK Prescaler value is 3. + * 0b10..PCS to SCK Prescaler value is 5. + * 0b11..PCS to SCK Prescaler value is 7. + */ +#define SPI_CTAR_PCSSCK(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_PCSSCK_SHIFT)) & SPI_CTAR_PCSSCK_MASK) +#define SPI_CTAR_LSBFE_MASK (0x1000000U) +#define SPI_CTAR_LSBFE_SHIFT (24U) +/*! LSBFE - LSB First + * 0b0..Data is transferred MSB first. + * 0b1..Data is transferred LSB first. + */ +#define SPI_CTAR_LSBFE(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_LSBFE_SHIFT)) & SPI_CTAR_LSBFE_MASK) +#define SPI_CTAR_CPHA_MASK (0x2000000U) +#define SPI_CTAR_CPHA_SHIFT (25U) +/*! CPHA - Clock Phase + * 0b0..Data is captured on the leading edge of SCK and changed on the following edge. + * 0b1..Data is changed on the leading edge of SCK and captured on the following edge. + */ +#define SPI_CTAR_CPHA(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_CPHA_SHIFT)) & SPI_CTAR_CPHA_MASK) +#define SPI_CTAR_CPOL_MASK (0x4000000U) +#define SPI_CTAR_CPOL_SHIFT (26U) +/*! CPOL - Clock Polarity + * 0b0..The inactive state value of SCK is low. + * 0b1..The inactive state value of SCK is high. + */ +#define SPI_CTAR_CPOL(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_CPOL_SHIFT)) & SPI_CTAR_CPOL_MASK) +#define SPI_CTAR_FMSZ_MASK (0x78000000U) +#define SPI_CTAR_FMSZ_SHIFT (27U) +#define SPI_CTAR_FMSZ(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_FMSZ_SHIFT)) & SPI_CTAR_FMSZ_MASK) +#define SPI_CTAR_DBR_MASK (0x80000000U) +#define SPI_CTAR_DBR_SHIFT (31U) +/*! DBR - Double Baud Rate + * 0b0..The baud rate is computed normally with a 50/50 duty cycle. + * 0b1..The baud rate is doubled with the duty cycle depending on the Baud Rate Prescaler. + */ +#define SPI_CTAR_DBR(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_DBR_SHIFT)) & SPI_CTAR_DBR_MASK) +/*! @} */ + +/* The count of SPI_CTAR */ +#define SPI_CTAR_COUNT (2U) + +/*! @name CTAR_SLAVE - Clock and Transfer Attributes Register (In Slave Mode) */ +/*! @{ */ +#define SPI_CTAR_SLAVE_CPHA_MASK (0x2000000U) +#define SPI_CTAR_SLAVE_CPHA_SHIFT (25U) +/*! CPHA - Clock Phase + * 0b0..Data is captured on the leading edge of SCK and changed on the following edge. + * 0b1..Data is changed on the leading edge of SCK and captured on the following edge. + */ +#define SPI_CTAR_SLAVE_CPHA(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_SLAVE_CPHA_SHIFT)) & SPI_CTAR_SLAVE_CPHA_MASK) +#define SPI_CTAR_SLAVE_CPOL_MASK (0x4000000U) +#define SPI_CTAR_SLAVE_CPOL_SHIFT (26U) +/*! CPOL - Clock Polarity + * 0b0..The inactive state value of SCK is low. + * 0b1..The inactive state value of SCK is high. + */ +#define SPI_CTAR_SLAVE_CPOL(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_SLAVE_CPOL_SHIFT)) & SPI_CTAR_SLAVE_CPOL_MASK) +#define SPI_CTAR_SLAVE_FMSZ_MASK (0xF8000000U) +#define SPI_CTAR_SLAVE_FMSZ_SHIFT (27U) +#define SPI_CTAR_SLAVE_FMSZ(x) (((uint32_t)(((uint32_t)(x)) << SPI_CTAR_SLAVE_FMSZ_SHIFT)) & SPI_CTAR_SLAVE_FMSZ_MASK) +/*! @} */ + +/* The count of SPI_CTAR_SLAVE */ +#define SPI_CTAR_SLAVE_COUNT (1U) + +/*! @name SR - Status Register */ +/*! @{ */ +#define SPI_SR_POPNXTPTR_MASK (0xFU) +#define SPI_SR_POPNXTPTR_SHIFT (0U) +#define SPI_SR_POPNXTPTR(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_POPNXTPTR_SHIFT)) & SPI_SR_POPNXTPTR_MASK) +#define SPI_SR_RXCTR_MASK (0xF0U) +#define SPI_SR_RXCTR_SHIFT (4U) +#define SPI_SR_RXCTR(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_RXCTR_SHIFT)) & SPI_SR_RXCTR_MASK) +#define SPI_SR_TXNXTPTR_MASK (0xF00U) +#define SPI_SR_TXNXTPTR_SHIFT (8U) +#define SPI_SR_TXNXTPTR(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_TXNXTPTR_SHIFT)) & SPI_SR_TXNXTPTR_MASK) +#define SPI_SR_TXCTR_MASK (0xF000U) +#define SPI_SR_TXCTR_SHIFT (12U) +#define SPI_SR_TXCTR(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_TXCTR_SHIFT)) & SPI_SR_TXCTR_MASK) +#define SPI_SR_RFDF_MASK (0x20000U) +#define SPI_SR_RFDF_SHIFT (17U) +/*! RFDF - Receive FIFO Drain Flag + * 0b0..RX FIFO is empty. + * 0b1..RX FIFO is not empty. + */ +#define SPI_SR_RFDF(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_RFDF_SHIFT)) & SPI_SR_RFDF_MASK) +#define SPI_SR_RFOF_MASK (0x80000U) +#define SPI_SR_RFOF_SHIFT (19U) +/*! RFOF - Receive FIFO Overflow Flag + * 0b0..No Rx FIFO overflow. + * 0b1..Rx FIFO overflow has occurred. + */ +#define SPI_SR_RFOF(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_RFOF_SHIFT)) & SPI_SR_RFOF_MASK) +#define SPI_SR_TFFF_MASK (0x2000000U) +#define SPI_SR_TFFF_SHIFT (25U) +/*! TFFF - Transmit FIFO Fill Flag + * 0b0..TX FIFO is full. + * 0b1..TX FIFO is not full. + */ +#define SPI_SR_TFFF(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_TFFF_SHIFT)) & SPI_SR_TFFF_MASK) +#define SPI_SR_TFUF_MASK (0x8000000U) +#define SPI_SR_TFUF_SHIFT (27U) +/*! TFUF - Transmit FIFO Underflow Flag + * 0b0..No TX FIFO underflow. + * 0b1..TX FIFO underflow has occurred. + */ +#define SPI_SR_TFUF(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_TFUF_SHIFT)) & SPI_SR_TFUF_MASK) +#define SPI_SR_EOQF_MASK (0x10000000U) +#define SPI_SR_EOQF_SHIFT (28U) +/*! EOQF - End of Queue Flag + * 0b0..EOQ is not set in the executing command. + * 0b1..EOQ is set in the executing SPI command. + */ +#define SPI_SR_EOQF(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_EOQF_SHIFT)) & SPI_SR_EOQF_MASK) +#define SPI_SR_TXRXS_MASK (0x40000000U) +#define SPI_SR_TXRXS_SHIFT (30U) +/*! TXRXS - TX and RX Status + * 0b0..Transmit and receive operations are disabled (The module is in Stopped state). + * 0b1..Transmit and receive operations are enabled (The module is in Running state). + */ +#define SPI_SR_TXRXS(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_TXRXS_SHIFT)) & SPI_SR_TXRXS_MASK) +#define SPI_SR_TCF_MASK (0x80000000U) +#define SPI_SR_TCF_SHIFT (31U) +/*! TCF - Transfer Complete Flag + * 0b0..Transfer not complete. + * 0b1..Transfer complete. + */ +#define SPI_SR_TCF(x) (((uint32_t)(((uint32_t)(x)) << SPI_SR_TCF_SHIFT)) & SPI_SR_TCF_MASK) +/*! @} */ + +/*! @name RSER - DMA/Interrupt Request Select and Enable Register */ +/*! @{ */ +#define SPI_RSER_RFDF_DIRS_MASK (0x10000U) +#define SPI_RSER_RFDF_DIRS_SHIFT (16U) +/*! RFDF_DIRS - Receive FIFO Drain DMA or Interrupt Request Select + * 0b0..Interrupt request. + * 0b1..DMA request. + */ +#define SPI_RSER_RFDF_DIRS(x) (((uint32_t)(((uint32_t)(x)) << SPI_RSER_RFDF_DIRS_SHIFT)) & SPI_RSER_RFDF_DIRS_MASK) +#define SPI_RSER_RFDF_RE_MASK (0x20000U) +#define SPI_RSER_RFDF_RE_SHIFT (17U) +/*! RFDF_RE - Receive FIFO Drain Request Enable + * 0b0..RFDF interrupt or DMA requests are disabled. + * 0b1..RFDF interrupt or DMA requests are enabled. + */ +#define SPI_RSER_RFDF_RE(x) (((uint32_t)(((uint32_t)(x)) << SPI_RSER_RFDF_RE_SHIFT)) & SPI_RSER_RFDF_RE_MASK) +#define SPI_RSER_RFOF_RE_MASK (0x80000U) +#define SPI_RSER_RFOF_RE_SHIFT (19U) +/*! RFOF_RE - Receive FIFO Overflow Request Enable + * 0b0..RFOF interrupt requests are disabled. + * 0b1..RFOF interrupt requests are enabled. + */ +#define SPI_RSER_RFOF_RE(x) (((uint32_t)(((uint32_t)(x)) << SPI_RSER_RFOF_RE_SHIFT)) & SPI_RSER_RFOF_RE_MASK) +#define SPI_RSER_TFFF_DIRS_MASK (0x1000000U) +#define SPI_RSER_TFFF_DIRS_SHIFT (24U) +/*! TFFF_DIRS - Transmit FIFO Fill DMA or Interrupt Request Select + * 0b0..TFFF flag generates interrupt requests. + * 0b1..TFFF flag generates DMA requests. + */ +#define SPI_RSER_TFFF_DIRS(x) (((uint32_t)(((uint32_t)(x)) << SPI_RSER_TFFF_DIRS_SHIFT)) & SPI_RSER_TFFF_DIRS_MASK) +#define SPI_RSER_TFFF_RE_MASK (0x2000000U) +#define SPI_RSER_TFFF_RE_SHIFT (25U) +/*! TFFF_RE - Transmit FIFO Fill Request Enable + * 0b0..TFFF interrupts or DMA requests are disabled. + * 0b1..TFFF interrupts or DMA requests are enabled. + */ +#define SPI_RSER_TFFF_RE(x) (((uint32_t)(((uint32_t)(x)) << SPI_RSER_TFFF_RE_SHIFT)) & SPI_RSER_TFFF_RE_MASK) +#define SPI_RSER_TFUF_RE_MASK (0x8000000U) +#define SPI_RSER_TFUF_RE_SHIFT (27U) +/*! TFUF_RE - Transmit FIFO Underflow Request Enable + * 0b0..TFUF interrupt requests are disabled. + * 0b1..TFUF interrupt requests are enabled. + */ +#define SPI_RSER_TFUF_RE(x) (((uint32_t)(((uint32_t)(x)) << SPI_RSER_TFUF_RE_SHIFT)) & SPI_RSER_TFUF_RE_MASK) +#define SPI_RSER_EOQF_RE_MASK (0x10000000U) +#define SPI_RSER_EOQF_RE_SHIFT (28U) +/*! EOQF_RE - Finished Request Enable + * 0b0..EOQF interrupt requests are disabled. + * 0b1..EOQF interrupt requests are enabled. + */ +#define SPI_RSER_EOQF_RE(x) (((uint32_t)(((uint32_t)(x)) << SPI_RSER_EOQF_RE_SHIFT)) & SPI_RSER_EOQF_RE_MASK) +#define SPI_RSER_TCF_RE_MASK (0x80000000U) +#define SPI_RSER_TCF_RE_SHIFT (31U) +/*! TCF_RE - Transmission Complete Request Enable + * 0b0..TCF interrupt requests are disabled. + * 0b1..TCF interrupt requests are enabled. + */ +#define SPI_RSER_TCF_RE(x) (((uint32_t)(((uint32_t)(x)) << SPI_RSER_TCF_RE_SHIFT)) & SPI_RSER_TCF_RE_MASK) +/*! @} */ + +/*! @name PUSHR - PUSH TX FIFO Register In Master Mode */ +/*! @{ */ +#define SPI_PUSHR_TXDATA_MASK (0xFFFFU) +#define SPI_PUSHR_TXDATA_SHIFT (0U) +#define SPI_PUSHR_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_PUSHR_TXDATA_SHIFT)) & SPI_PUSHR_TXDATA_MASK) +#define SPI_PUSHR_PCS_MASK (0x3F0000U) +#define SPI_PUSHR_PCS_SHIFT (16U) +/*! PCS + * 0b000000..Negate the PCS[x] signal. + * 0b000001..Assert the PCS[x] signal. + */ +#define SPI_PUSHR_PCS(x) (((uint32_t)(((uint32_t)(x)) << SPI_PUSHR_PCS_SHIFT)) & SPI_PUSHR_PCS_MASK) +#define SPI_PUSHR_CTCNT_MASK (0x4000000U) +#define SPI_PUSHR_CTCNT_SHIFT (26U) +/*! CTCNT - Clear Transfer Counter + * 0b0..Do not clear the TCR[TCNT] field. + * 0b1..Clear the TCR[TCNT] field. + */ +#define SPI_PUSHR_CTCNT(x) (((uint32_t)(((uint32_t)(x)) << SPI_PUSHR_CTCNT_SHIFT)) & SPI_PUSHR_CTCNT_MASK) +#define SPI_PUSHR_EOQ_MASK (0x8000000U) +#define SPI_PUSHR_EOQ_SHIFT (27U) +/*! EOQ - End Of Queue + * 0b0..The SPI data is not the last data to transfer. + * 0b1..The SPI data is the last data to transfer. + */ +#define SPI_PUSHR_EOQ(x) (((uint32_t)(((uint32_t)(x)) << SPI_PUSHR_EOQ_SHIFT)) & SPI_PUSHR_EOQ_MASK) +#define SPI_PUSHR_CTAS_MASK (0x70000000U) +#define SPI_PUSHR_CTAS_SHIFT (28U) +/*! CTAS - Clock and Transfer Attributes Select + * 0b000..CTAR0 + * 0b001..CTAR1 + * 0b010..Reserved + * 0b011..Reserved + * 0b100..Reserved + * 0b101..Reserved + * 0b110..Reserved + * 0b111..Reserved + */ +#define SPI_PUSHR_CTAS(x) (((uint32_t)(((uint32_t)(x)) << SPI_PUSHR_CTAS_SHIFT)) & SPI_PUSHR_CTAS_MASK) +#define SPI_PUSHR_CONT_MASK (0x80000000U) +#define SPI_PUSHR_CONT_SHIFT (31U) +/*! CONT - Continuous Peripheral Chip Select Enable + * 0b0..Return PCSn signals to their inactive state between transfers. + * 0b1..Keep PCSn signals asserted between transfers. + */ +#define SPI_PUSHR_CONT(x) (((uint32_t)(((uint32_t)(x)) << SPI_PUSHR_CONT_SHIFT)) & SPI_PUSHR_CONT_MASK) +/*! @} */ + +/*! @name PUSHR_SLAVE - PUSH TX FIFO Register In Slave Mode */ +/*! @{ */ +#define SPI_PUSHR_SLAVE_TXDATA_MASK (0xFFFFFFFFU) +#define SPI_PUSHR_SLAVE_TXDATA_SHIFT (0U) +#define SPI_PUSHR_SLAVE_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_PUSHR_SLAVE_TXDATA_SHIFT)) & SPI_PUSHR_SLAVE_TXDATA_MASK) +/*! @} */ + +/*! @name POPR - POP RX FIFO Register */ +/*! @{ */ +#define SPI_POPR_RXDATA_MASK (0xFFFFFFFFU) +#define SPI_POPR_RXDATA_SHIFT (0U) +#define SPI_POPR_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_POPR_RXDATA_SHIFT)) & SPI_POPR_RXDATA_MASK) +/*! @} */ + +/*! @name TXFR0 - Transmit FIFO Registers */ +/*! @{ */ +#define SPI_TXFR0_TXDATA_MASK (0xFFFFU) +#define SPI_TXFR0_TXDATA_SHIFT (0U) +#define SPI_TXFR0_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXFR0_TXDATA_SHIFT)) & SPI_TXFR0_TXDATA_MASK) +#define SPI_TXFR0_TXCMD_TXDATA_MASK (0xFFFF0000U) +#define SPI_TXFR0_TXCMD_TXDATA_SHIFT (16U) +#define SPI_TXFR0_TXCMD_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXFR0_TXCMD_TXDATA_SHIFT)) & SPI_TXFR0_TXCMD_TXDATA_MASK) +/*! @} */ + +/*! @name TXFR1 - Transmit FIFO Registers */ +/*! @{ */ +#define SPI_TXFR1_TXDATA_MASK (0xFFFFU) +#define SPI_TXFR1_TXDATA_SHIFT (0U) +#define SPI_TXFR1_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXFR1_TXDATA_SHIFT)) & SPI_TXFR1_TXDATA_MASK) +#define SPI_TXFR1_TXCMD_TXDATA_MASK (0xFFFF0000U) +#define SPI_TXFR1_TXCMD_TXDATA_SHIFT (16U) +#define SPI_TXFR1_TXCMD_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXFR1_TXCMD_TXDATA_SHIFT)) & SPI_TXFR1_TXCMD_TXDATA_MASK) +/*! @} */ + +/*! @name TXFR2 - Transmit FIFO Registers */ +/*! @{ */ +#define SPI_TXFR2_TXDATA_MASK (0xFFFFU) +#define SPI_TXFR2_TXDATA_SHIFT (0U) +#define SPI_TXFR2_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXFR2_TXDATA_SHIFT)) & SPI_TXFR2_TXDATA_MASK) +#define SPI_TXFR2_TXCMD_TXDATA_MASK (0xFFFF0000U) +#define SPI_TXFR2_TXCMD_TXDATA_SHIFT (16U) +#define SPI_TXFR2_TXCMD_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXFR2_TXCMD_TXDATA_SHIFT)) & SPI_TXFR2_TXCMD_TXDATA_MASK) +/*! @} */ + +/*! @name TXFR3 - Transmit FIFO Registers */ +/*! @{ */ +#define SPI_TXFR3_TXDATA_MASK (0xFFFFU) +#define SPI_TXFR3_TXDATA_SHIFT (0U) +#define SPI_TXFR3_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXFR3_TXDATA_SHIFT)) & SPI_TXFR3_TXDATA_MASK) +#define SPI_TXFR3_TXCMD_TXDATA_MASK (0xFFFF0000U) +#define SPI_TXFR3_TXCMD_TXDATA_SHIFT (16U) +#define SPI_TXFR3_TXCMD_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXFR3_TXCMD_TXDATA_SHIFT)) & SPI_TXFR3_TXCMD_TXDATA_MASK) +/*! @} */ + +/*! @name RXFR0 - Receive FIFO Registers */ +/*! @{ */ +#define SPI_RXFR0_RXDATA_MASK (0xFFFFFFFFU) +#define SPI_RXFR0_RXDATA_SHIFT (0U) +#define SPI_RXFR0_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXFR0_RXDATA_SHIFT)) & SPI_RXFR0_RXDATA_MASK) +/*! @} */ + +/*! @name RXFR1 - Receive FIFO Registers */ +/*! @{ */ +#define SPI_RXFR1_RXDATA_MASK (0xFFFFFFFFU) +#define SPI_RXFR1_RXDATA_SHIFT (0U) +#define SPI_RXFR1_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXFR1_RXDATA_SHIFT)) & SPI_RXFR1_RXDATA_MASK) +/*! @} */ + +/*! @name RXFR2 - Receive FIFO Registers */ +/*! @{ */ +#define SPI_RXFR2_RXDATA_MASK (0xFFFFFFFFU) +#define SPI_RXFR2_RXDATA_SHIFT (0U) +#define SPI_RXFR2_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXFR2_RXDATA_SHIFT)) & SPI_RXFR2_RXDATA_MASK) +/*! @} */ + +/*! @name RXFR3 - Receive FIFO Registers */ +/*! @{ */ +#define SPI_RXFR3_RXDATA_MASK (0xFFFFFFFFU) +#define SPI_RXFR3_RXDATA_SHIFT (0U) +#define SPI_RXFR3_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXFR3_RXDATA_SHIFT)) & SPI_RXFR3_RXDATA_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group SPI_Register_Masks */ + + +/* SPI - Peripheral instance base addresses */ +/** Peripheral SPI0 base address */ +#define SPI0_BASE (0x4002C000u) +/** Peripheral SPI0 base pointer */ +#define SPI0 ((SPI_Type *)SPI0_BASE) +/** Peripheral SPI1 base address */ +#define SPI1_BASE (0x4002D000u) +/** Peripheral SPI1 base pointer */ +#define SPI1 ((SPI_Type *)SPI1_BASE) +/** Peripheral SPI2 base address */ +#define SPI2_BASE (0x400AC000u) +/** Peripheral SPI2 base pointer */ +#define SPI2 ((SPI_Type *)SPI2_BASE) +/** Array initializer of SPI peripheral base addresses */ +#define SPI_BASE_ADDRS { SPI0_BASE, SPI1_BASE, SPI2_BASE } +/** Array initializer of SPI peripheral base pointers */ +#define SPI_BASE_PTRS { SPI0, SPI1, SPI2 } +/** Interrupt vectors for the SPI peripheral type */ +#define SPI_IRQS { SPI0_IRQn, SPI1_IRQn, SPI2_IRQn } + +/*! + * @} + */ /* end of group SPI_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SYSMPU Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SYSMPU_Peripheral_Access_Layer SYSMPU Peripheral Access Layer + * @{ + */ + +/** SYSMPU - Register Layout Typedef */ +typedef struct { + __IO uint32_t CESR; /**< Control/Error Status Register, offset: 0x0 */ + uint8_t RESERVED_0[12]; + struct { /* offset: 0x10, array step: 0x8 */ + __I uint32_t EAR; /**< Error Address Register, slave port n, array offset: 0x10, array step: 0x8 */ + __I uint32_t EDR; /**< Error Detail Register, slave port n, array offset: 0x14, array step: 0x8 */ + } SP[5]; + uint8_t RESERVED_1[968]; + __IO uint32_t WORD[12][4]; /**< Region Descriptor n, Word 0..Region Descriptor n, Word 3, array offset: 0x400, array step: index*0x10, index2*0x4 */ + uint8_t RESERVED_2[832]; + __IO uint32_t RGDAAC[12]; /**< Region Descriptor Alternate Access Control n, array offset: 0x800, array step: 0x4 */ +} SYSMPU_Type; + +/* ---------------------------------------------------------------------------- + -- SYSMPU Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SYSMPU_Register_Masks SYSMPU Register Masks + * @{ + */ + +/*! @name CESR - Control/Error Status Register */ +/*! @{ */ +#define SYSMPU_CESR_VLD_MASK (0x1U) +#define SYSMPU_CESR_VLD_SHIFT (0U) +/*! VLD - Valid + * 0b0..MPU is disabled. All accesses from all bus masters are allowed. + * 0b1..MPU is enabled + */ +#define SYSMPU_CESR_VLD(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_CESR_VLD_SHIFT)) & SYSMPU_CESR_VLD_MASK) +#define SYSMPU_CESR_NRGD_MASK (0xF00U) +#define SYSMPU_CESR_NRGD_SHIFT (8U) +/*! NRGD - Number Of Region Descriptors + * 0b0000..8 region descriptors + * 0b0001..12 region descriptors + * 0b0010..16 region descriptors + */ +#define SYSMPU_CESR_NRGD(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_CESR_NRGD_SHIFT)) & SYSMPU_CESR_NRGD_MASK) +#define SYSMPU_CESR_NSP_MASK (0xF000U) +#define SYSMPU_CESR_NSP_SHIFT (12U) +#define SYSMPU_CESR_NSP(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_CESR_NSP_SHIFT)) & SYSMPU_CESR_NSP_MASK) +#define SYSMPU_CESR_HRL_MASK (0xF0000U) +#define SYSMPU_CESR_HRL_SHIFT (16U) +#define SYSMPU_CESR_HRL(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_CESR_HRL_SHIFT)) & SYSMPU_CESR_HRL_MASK) +#define SYSMPU_CESR_SPERR_MASK (0xF8000000U) +#define SYSMPU_CESR_SPERR_SHIFT (27U) +/*! SPERR - Slave Port n Error + * 0b00000..No error has occurred for slave port n. + * 0b00001..An error has occurred for slave port n. + */ +#define SYSMPU_CESR_SPERR(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_CESR_SPERR_SHIFT)) & SYSMPU_CESR_SPERR_MASK) +/*! @} */ + +/*! @name EAR - Error Address Register, slave port n */ +/*! @{ */ +#define SYSMPU_EAR_EADDR_MASK (0xFFFFFFFFU) +#define SYSMPU_EAR_EADDR_SHIFT (0U) +#define SYSMPU_EAR_EADDR(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_EAR_EADDR_SHIFT)) & SYSMPU_EAR_EADDR_MASK) +/*! @} */ + +/* The count of SYSMPU_EAR */ +#define SYSMPU_EAR_COUNT (5U) + +/*! @name EDR - Error Detail Register, slave port n */ +/*! @{ */ +#define SYSMPU_EDR_ERW_MASK (0x1U) +#define SYSMPU_EDR_ERW_SHIFT (0U) +/*! ERW - Error Read/Write + * 0b0..Read + * 0b1..Write + */ +#define SYSMPU_EDR_ERW(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_EDR_ERW_SHIFT)) & SYSMPU_EDR_ERW_MASK) +#define SYSMPU_EDR_EATTR_MASK (0xEU) +#define SYSMPU_EDR_EATTR_SHIFT (1U) +/*! EATTR - Error Attributes + * 0b000..User mode, instruction access + * 0b001..User mode, data access + * 0b010..Supervisor mode, instruction access + * 0b011..Supervisor mode, data access + */ +#define SYSMPU_EDR_EATTR(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_EDR_EATTR_SHIFT)) & SYSMPU_EDR_EATTR_MASK) +#define SYSMPU_EDR_EMN_MASK (0xF0U) +#define SYSMPU_EDR_EMN_SHIFT (4U) +#define SYSMPU_EDR_EMN(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_EDR_EMN_SHIFT)) & SYSMPU_EDR_EMN_MASK) +#define SYSMPU_EDR_EPID_MASK (0xFF00U) +#define SYSMPU_EDR_EPID_SHIFT (8U) +#define SYSMPU_EDR_EPID(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_EDR_EPID_SHIFT)) & SYSMPU_EDR_EPID_MASK) +#define SYSMPU_EDR_EACD_MASK (0xFFFF0000U) +#define SYSMPU_EDR_EACD_SHIFT (16U) +#define SYSMPU_EDR_EACD(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_EDR_EACD_SHIFT)) & SYSMPU_EDR_EACD_MASK) +/*! @} */ + +/* The count of SYSMPU_EDR */ +#define SYSMPU_EDR_COUNT (5U) + +/*! @name WORD - Region Descriptor n, Word 0..Region Descriptor n, Word 3 */ +/*! @{ */ +#define SYSMPU_WORD_M0UM_MASK (0x7U) +#define SYSMPU_WORD_M0UM_SHIFT (0U) +#define SYSMPU_WORD_M0UM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M0UM_SHIFT)) & SYSMPU_WORD_M0UM_MASK) +#define SYSMPU_WORD_VLD_MASK (0x1U) +#define SYSMPU_WORD_VLD_SHIFT (0U) +/*! VLD - Valid + * 0b0..Region descriptor is invalid + * 0b1..Region descriptor is valid + */ +#define SYSMPU_WORD_VLD(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_VLD_SHIFT)) & SYSMPU_WORD_VLD_MASK) +#define SYSMPU_WORD_M0SM_MASK (0x18U) +#define SYSMPU_WORD_M0SM_SHIFT (3U) +#define SYSMPU_WORD_M0SM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M0SM_SHIFT)) & SYSMPU_WORD_M0SM_MASK) +#define SYSMPU_WORD_ENDADDR_MASK (0xFFFFFFE0U) +#define SYSMPU_WORD_ENDADDR_SHIFT (5U) +#define SYSMPU_WORD_ENDADDR(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_ENDADDR_SHIFT)) & SYSMPU_WORD_ENDADDR_MASK) +#define SYSMPU_WORD_M0PE_MASK (0x20U) +#define SYSMPU_WORD_M0PE_SHIFT (5U) +#define SYSMPU_WORD_M0PE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M0PE_SHIFT)) & SYSMPU_WORD_M0PE_MASK) +#define SYSMPU_WORD_SRTADDR_MASK (0xFFFFFFE0U) +#define SYSMPU_WORD_SRTADDR_SHIFT (5U) +#define SYSMPU_WORD_SRTADDR(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_SRTADDR_SHIFT)) & SYSMPU_WORD_SRTADDR_MASK) +#define SYSMPU_WORD_M1UM_MASK (0x1C0U) +#define SYSMPU_WORD_M1UM_SHIFT (6U) +#define SYSMPU_WORD_M1UM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M1UM_SHIFT)) & SYSMPU_WORD_M1UM_MASK) +#define SYSMPU_WORD_M1SM_MASK (0x600U) +#define SYSMPU_WORD_M1SM_SHIFT (9U) +#define SYSMPU_WORD_M1SM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M1SM_SHIFT)) & SYSMPU_WORD_M1SM_MASK) +#define SYSMPU_WORD_M1PE_MASK (0x800U) +#define SYSMPU_WORD_M1PE_SHIFT (11U) +#define SYSMPU_WORD_M1PE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M1PE_SHIFT)) & SYSMPU_WORD_M1PE_MASK) +#define SYSMPU_WORD_M2UM_MASK (0x7000U) +#define SYSMPU_WORD_M2UM_SHIFT (12U) +#define SYSMPU_WORD_M2UM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M2UM_SHIFT)) & SYSMPU_WORD_M2UM_MASK) +#define SYSMPU_WORD_M2SM_MASK (0x18000U) +#define SYSMPU_WORD_M2SM_SHIFT (15U) +#define SYSMPU_WORD_M2SM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M2SM_SHIFT)) & SYSMPU_WORD_M2SM_MASK) +#define SYSMPU_WORD_PIDMASK_MASK (0xFF0000U) +#define SYSMPU_WORD_PIDMASK_SHIFT (16U) +#define SYSMPU_WORD_PIDMASK(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_PIDMASK_SHIFT)) & SYSMPU_WORD_PIDMASK_MASK) +#define SYSMPU_WORD_M2PE_MASK (0x20000U) +#define SYSMPU_WORD_M2PE_SHIFT (17U) +#define SYSMPU_WORD_M2PE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M2PE_SHIFT)) & SYSMPU_WORD_M2PE_MASK) +#define SYSMPU_WORD_M3UM_MASK (0x1C0000U) +#define SYSMPU_WORD_M3UM_SHIFT (18U) +/*! M3UM - Bus Master 3 User Mode Access Control + * 0b000..An attempted access of that mode may be terminated with an access error (if not allowed by another descriptor) and the access not performed. + * 0b001..Allows the given access type to occur + */ +#define SYSMPU_WORD_M3UM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M3UM_SHIFT)) & SYSMPU_WORD_M3UM_MASK) +#define SYSMPU_WORD_M3SM_MASK (0x600000U) +#define SYSMPU_WORD_M3SM_SHIFT (21U) +/*! M3SM - Bus Master 3 Supervisor Mode Access Control + * 0b00..r/w/x; read, write and execute allowed + * 0b01..r/x; read and execute allowed, but no write + * 0b10..r/w; read and write allowed, but no execute + * 0b11..Same as User mode defined in M3UM + */ +#define SYSMPU_WORD_M3SM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M3SM_SHIFT)) & SYSMPU_WORD_M3SM_MASK) +#define SYSMPU_WORD_M3PE_MASK (0x800000U) +#define SYSMPU_WORD_M3PE_SHIFT (23U) +/*! M3PE - Bus Master 3 Process Identifier Enable + * 0b0..Do not include the process identifier in the evaluation + * 0b1..Include the process identifier and mask (RGDn_WORD3) in the region hit evaluation + */ +#define SYSMPU_WORD_M3PE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M3PE_SHIFT)) & SYSMPU_WORD_M3PE_MASK) +#define SYSMPU_WORD_M4WE_MASK (0x1000000U) +#define SYSMPU_WORD_M4WE_SHIFT (24U) +/*! M4WE - Bus Master 4 Write Enable + * 0b0..Bus master 4 writes terminate with an access error and the write is not performed + * 0b1..Bus master 4 writes allowed + */ +#define SYSMPU_WORD_M4WE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M4WE_SHIFT)) & SYSMPU_WORD_M4WE_MASK) +#define SYSMPU_WORD_PID_MASK (0xFF000000U) +#define SYSMPU_WORD_PID_SHIFT (24U) +#define SYSMPU_WORD_PID(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_PID_SHIFT)) & SYSMPU_WORD_PID_MASK) +#define SYSMPU_WORD_M4RE_MASK (0x2000000U) +#define SYSMPU_WORD_M4RE_SHIFT (25U) +/*! M4RE - Bus Master 4 Read Enable + * 0b0..Bus master 4 reads terminate with an access error and the read is not performed + * 0b1..Bus master 4 reads allowed + */ +#define SYSMPU_WORD_M4RE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M4RE_SHIFT)) & SYSMPU_WORD_M4RE_MASK) +#define SYSMPU_WORD_M5WE_MASK (0x4000000U) +#define SYSMPU_WORD_M5WE_SHIFT (26U) +/*! M5WE - Bus Master 5 Write Enable + * 0b0..Bus master 5 writes terminate with an access error and the write is not performed + * 0b1..Bus master 5 writes allowed + */ +#define SYSMPU_WORD_M5WE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M5WE_SHIFT)) & SYSMPU_WORD_M5WE_MASK) +#define SYSMPU_WORD_M5RE_MASK (0x8000000U) +#define SYSMPU_WORD_M5RE_SHIFT (27U) +/*! M5RE - Bus Master 5 Read Enable + * 0b0..Bus master 5 reads terminate with an access error and the read is not performed + * 0b1..Bus master 5 reads allowed + */ +#define SYSMPU_WORD_M5RE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M5RE_SHIFT)) & SYSMPU_WORD_M5RE_MASK) +#define SYSMPU_WORD_M6WE_MASK (0x10000000U) +#define SYSMPU_WORD_M6WE_SHIFT (28U) +/*! M6WE - Bus Master 6 Write Enable + * 0b0..Bus master 6 writes terminate with an access error and the write is not performed + * 0b1..Bus master 6 writes allowed + */ +#define SYSMPU_WORD_M6WE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M6WE_SHIFT)) & SYSMPU_WORD_M6WE_MASK) +#define SYSMPU_WORD_M6RE_MASK (0x20000000U) +#define SYSMPU_WORD_M6RE_SHIFT (29U) +/*! M6RE - Bus Master 6 Read Enable + * 0b0..Bus master 6 reads terminate with an access error and the read is not performed + * 0b1..Bus master 6 reads allowed + */ +#define SYSMPU_WORD_M6RE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M6RE_SHIFT)) & SYSMPU_WORD_M6RE_MASK) +#define SYSMPU_WORD_M7WE_MASK (0x40000000U) +#define SYSMPU_WORD_M7WE_SHIFT (30U) +/*! M7WE - Bus Master 7 Write Enable + * 0b0..Bus master 7 writes terminate with an access error and the write is not performed + * 0b1..Bus master 7 writes allowed + */ +#define SYSMPU_WORD_M7WE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M7WE_SHIFT)) & SYSMPU_WORD_M7WE_MASK) +#define SYSMPU_WORD_M7RE_MASK (0x80000000U) +#define SYSMPU_WORD_M7RE_SHIFT (31U) +/*! M7RE - Bus Master 7 Read Enable + * 0b0..Bus master 7 reads terminate with an access error and the read is not performed + * 0b1..Bus master 7 reads allowed + */ +#define SYSMPU_WORD_M7RE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M7RE_SHIFT)) & SYSMPU_WORD_M7RE_MASK) +/*! @} */ + +/* The count of SYSMPU_WORD */ +#define SYSMPU_WORD_COUNT (12U) + +/* The count of SYSMPU_WORD */ +#define SYSMPU_WORD_COUNT2 (4U) + +/*! @name RGDAAC - Region Descriptor Alternate Access Control n */ +/*! @{ */ +#define SYSMPU_RGDAAC_M0UM_MASK (0x7U) +#define SYSMPU_RGDAAC_M0UM_SHIFT (0U) +#define SYSMPU_RGDAAC_M0UM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M0UM_SHIFT)) & SYSMPU_RGDAAC_M0UM_MASK) +#define SYSMPU_RGDAAC_M0SM_MASK (0x18U) +#define SYSMPU_RGDAAC_M0SM_SHIFT (3U) +#define SYSMPU_RGDAAC_M0SM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M0SM_SHIFT)) & SYSMPU_RGDAAC_M0SM_MASK) +#define SYSMPU_RGDAAC_M0PE_MASK (0x20U) +#define SYSMPU_RGDAAC_M0PE_SHIFT (5U) +#define SYSMPU_RGDAAC_M0PE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M0PE_SHIFT)) & SYSMPU_RGDAAC_M0PE_MASK) +#define SYSMPU_RGDAAC_M1UM_MASK (0x1C0U) +#define SYSMPU_RGDAAC_M1UM_SHIFT (6U) +#define SYSMPU_RGDAAC_M1UM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M1UM_SHIFT)) & SYSMPU_RGDAAC_M1UM_MASK) +#define SYSMPU_RGDAAC_M1SM_MASK (0x600U) +#define SYSMPU_RGDAAC_M1SM_SHIFT (9U) +#define SYSMPU_RGDAAC_M1SM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M1SM_SHIFT)) & SYSMPU_RGDAAC_M1SM_MASK) +#define SYSMPU_RGDAAC_M1PE_MASK (0x800U) +#define SYSMPU_RGDAAC_M1PE_SHIFT (11U) +#define SYSMPU_RGDAAC_M1PE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M1PE_SHIFT)) & SYSMPU_RGDAAC_M1PE_MASK) +#define SYSMPU_RGDAAC_M2UM_MASK (0x7000U) +#define SYSMPU_RGDAAC_M2UM_SHIFT (12U) +#define SYSMPU_RGDAAC_M2UM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M2UM_SHIFT)) & SYSMPU_RGDAAC_M2UM_MASK) +#define SYSMPU_RGDAAC_M2SM_MASK (0x18000U) +#define SYSMPU_RGDAAC_M2SM_SHIFT (15U) +#define SYSMPU_RGDAAC_M2SM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M2SM_SHIFT)) & SYSMPU_RGDAAC_M2SM_MASK) +#define SYSMPU_RGDAAC_M2PE_MASK (0x20000U) +#define SYSMPU_RGDAAC_M2PE_SHIFT (17U) +#define SYSMPU_RGDAAC_M2PE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M2PE_SHIFT)) & SYSMPU_RGDAAC_M2PE_MASK) +#define SYSMPU_RGDAAC_M3UM_MASK (0x1C0000U) +#define SYSMPU_RGDAAC_M3UM_SHIFT (18U) +/*! M3UM - Bus Master 3 User Mode Access Control + * 0b000..An attempted access of that mode may be terminated with an access error (if not allowed by another descriptor) and the access not performed. + * 0b001..Allows the given access type to occur + */ +#define SYSMPU_RGDAAC_M3UM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M3UM_SHIFT)) & SYSMPU_RGDAAC_M3UM_MASK) +#define SYSMPU_RGDAAC_M3SM_MASK (0x600000U) +#define SYSMPU_RGDAAC_M3SM_SHIFT (21U) +/*! M3SM - Bus Master 3 Supervisor Mode Access Control + * 0b00..r/w/x; read, write and execute allowed + * 0b01..r/x; read and execute allowed, but no write + * 0b10..r/w; read and write allowed, but no execute + * 0b11..Same as User mode defined in M3UM + */ +#define SYSMPU_RGDAAC_M3SM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M3SM_SHIFT)) & SYSMPU_RGDAAC_M3SM_MASK) +#define SYSMPU_RGDAAC_M3PE_MASK (0x800000U) +#define SYSMPU_RGDAAC_M3PE_SHIFT (23U) +/*! M3PE - Bus Master 3 Process Identifier Enable + * 0b0..Do not include the process identifier in the evaluation + * 0b1..Include the process identifier and mask (RGDn.RGDAAC) in the region hit evaluation + */ +#define SYSMPU_RGDAAC_M3PE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M3PE_SHIFT)) & SYSMPU_RGDAAC_M3PE_MASK) +#define SYSMPU_RGDAAC_M4WE_MASK (0x1000000U) +#define SYSMPU_RGDAAC_M4WE_SHIFT (24U) +/*! M4WE - Bus Master 4 Write Enable + * 0b0..Bus master 4 writes terminate with an access error and the write is not performed + * 0b1..Bus master 4 writes allowed + */ +#define SYSMPU_RGDAAC_M4WE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M4WE_SHIFT)) & SYSMPU_RGDAAC_M4WE_MASK) +#define SYSMPU_RGDAAC_M4RE_MASK (0x2000000U) +#define SYSMPU_RGDAAC_M4RE_SHIFT (25U) +/*! M4RE - Bus Master 4 Read Enable + * 0b0..Bus master 4 reads terminate with an access error and the read is not performed + * 0b1..Bus master 4 reads allowed + */ +#define SYSMPU_RGDAAC_M4RE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M4RE_SHIFT)) & SYSMPU_RGDAAC_M4RE_MASK) +#define SYSMPU_RGDAAC_M5WE_MASK (0x4000000U) +#define SYSMPU_RGDAAC_M5WE_SHIFT (26U) +/*! M5WE - Bus Master 5 Write Enable + * 0b0..Bus master 5 writes terminate with an access error and the write is not performed + * 0b1..Bus master 5 writes allowed + */ +#define SYSMPU_RGDAAC_M5WE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M5WE_SHIFT)) & SYSMPU_RGDAAC_M5WE_MASK) +#define SYSMPU_RGDAAC_M5RE_MASK (0x8000000U) +#define SYSMPU_RGDAAC_M5RE_SHIFT (27U) +/*! M5RE - Bus Master 5 Read Enable + * 0b0..Bus master 5 reads terminate with an access error and the read is not performed + * 0b1..Bus master 5 reads allowed + */ +#define SYSMPU_RGDAAC_M5RE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M5RE_SHIFT)) & SYSMPU_RGDAAC_M5RE_MASK) +#define SYSMPU_RGDAAC_M6WE_MASK (0x10000000U) +#define SYSMPU_RGDAAC_M6WE_SHIFT (28U) +/*! M6WE - Bus Master 6 Write Enable + * 0b0..Bus master 6 writes terminate with an access error and the write is not performed + * 0b1..Bus master 6 writes allowed + */ +#define SYSMPU_RGDAAC_M6WE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M6WE_SHIFT)) & SYSMPU_RGDAAC_M6WE_MASK) +#define SYSMPU_RGDAAC_M6RE_MASK (0x20000000U) +#define SYSMPU_RGDAAC_M6RE_SHIFT (29U) +/*! M6RE - Bus Master 6 Read Enable + * 0b0..Bus master 6 reads terminate with an access error and the read is not performed + * 0b1..Bus master 6 reads allowed + */ +#define SYSMPU_RGDAAC_M6RE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M6RE_SHIFT)) & SYSMPU_RGDAAC_M6RE_MASK) +#define SYSMPU_RGDAAC_M7WE_MASK (0x40000000U) +#define SYSMPU_RGDAAC_M7WE_SHIFT (30U) +/*! M7WE - Bus Master 7 Write Enable + * 0b0..Bus master 7 writes terminate with an access error and the write is not performed + * 0b1..Bus master 7 writes allowed + */ +#define SYSMPU_RGDAAC_M7WE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M7WE_SHIFT)) & SYSMPU_RGDAAC_M7WE_MASK) +#define SYSMPU_RGDAAC_M7RE_MASK (0x80000000U) +#define SYSMPU_RGDAAC_M7RE_SHIFT (31U) +/*! M7RE - Bus Master 7 Read Enable + * 0b0..Bus master 7 reads terminate with an access error and the read is not performed + * 0b1..Bus master 7 reads allowed + */ +#define SYSMPU_RGDAAC_M7RE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M7RE_SHIFT)) & SYSMPU_RGDAAC_M7RE_MASK) +/*! @} */ + +/* The count of SYSMPU_RGDAAC */ +#define SYSMPU_RGDAAC_COUNT (12U) + + +/*! + * @} + */ /* end of group SYSMPU_Register_Masks */ + + +/* SYSMPU - Peripheral instance base addresses */ +/** Peripheral SYSMPU base address */ +#define SYSMPU_BASE (0x4000D000u) +/** Peripheral SYSMPU base pointer */ +#define SYSMPU ((SYSMPU_Type *)SYSMPU_BASE) +/** Array initializer of SYSMPU peripheral base addresses */ +#define SYSMPU_BASE_ADDRS { SYSMPU_BASE } +/** Array initializer of SYSMPU peripheral base pointers */ +#define SYSMPU_BASE_PTRS { SYSMPU } + +/*! + * @} + */ /* end of group SYSMPU_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- UART Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup UART_Peripheral_Access_Layer UART Peripheral Access Layer + * @{ + */ + +/** UART - Register Layout Typedef */ +typedef struct { + __IO uint8_t BDH; /**< UART Baud Rate Registers: High, offset: 0x0 */ + __IO uint8_t BDL; /**< UART Baud Rate Registers: Low, offset: 0x1 */ + __IO uint8_t C1; /**< UART Control Register 1, offset: 0x2 */ + __IO uint8_t C2; /**< UART Control Register 2, offset: 0x3 */ + __I uint8_t S1; /**< UART Status Register 1, offset: 0x4 */ + __IO uint8_t S2; /**< UART Status Register 2, offset: 0x5 */ + __IO uint8_t C3; /**< UART Control Register 3, offset: 0x6 */ + __IO uint8_t D; /**< UART Data Register, offset: 0x7 */ + __IO uint8_t MA1; /**< UART Match Address Registers 1, offset: 0x8 */ + __IO uint8_t MA2; /**< UART Match Address Registers 2, offset: 0x9 */ + __IO uint8_t C4; /**< UART Control Register 4, offset: 0xA */ + __IO uint8_t C5; /**< UART Control Register 5, offset: 0xB */ + __I uint8_t ED; /**< UART Extended Data Register, offset: 0xC */ + __IO uint8_t MODEM; /**< UART Modem Register, offset: 0xD */ + __IO uint8_t IR; /**< UART Infrared Register, offset: 0xE */ + uint8_t RESERVED_0[1]; + __IO uint8_t PFIFO; /**< UART FIFO Parameters, offset: 0x10 */ + __IO uint8_t CFIFO; /**< UART FIFO Control Register, offset: 0x11 */ + __IO uint8_t SFIFO; /**< UART FIFO Status Register, offset: 0x12 */ + __IO uint8_t TWFIFO; /**< UART FIFO Transmit Watermark, offset: 0x13 */ + __I uint8_t TCFIFO; /**< UART FIFO Transmit Count, offset: 0x14 */ + __IO uint8_t RWFIFO; /**< UART FIFO Receive Watermark, offset: 0x15 */ + __I uint8_t RCFIFO; /**< UART FIFO Receive Count, offset: 0x16 */ + uint8_t RESERVED_1[1]; + __IO uint8_t C7816; /**< UART 7816 Control Register, offset: 0x18 */ + __IO uint8_t IE7816; /**< UART 7816 Interrupt Enable Register, offset: 0x19 */ + __IO uint8_t IS7816; /**< UART 7816 Interrupt Status Register, offset: 0x1A */ + union { /* offset: 0x1B */ + __IO uint8_t WP7816T0; /**< UART 7816 Wait Parameter Register, offset: 0x1B */ + __IO uint8_t WP7816T1; /**< UART 7816 Wait Parameter Register, offset: 0x1B */ + }; + __IO uint8_t WN7816; /**< UART 7816 Wait N Register, offset: 0x1C */ + __IO uint8_t WF7816; /**< UART 7816 Wait FD Register, offset: 0x1D */ + __IO uint8_t ET7816; /**< UART 7816 Error Threshold Register, offset: 0x1E */ + __IO uint8_t TL7816; /**< UART 7816 Transmit Length Register, offset: 0x1F */ +} UART_Type; + +/* ---------------------------------------------------------------------------- + -- UART Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup UART_Register_Masks UART Register Masks + * @{ + */ + +/*! @name BDH - UART Baud Rate Registers: High */ +/*! @{ */ +#define UART_BDH_SBR_MASK (0x1FU) +#define UART_BDH_SBR_SHIFT (0U) +#define UART_BDH_SBR(x) (((uint8_t)(((uint8_t)(x)) << UART_BDH_SBR_SHIFT)) & UART_BDH_SBR_MASK) +#define UART_BDH_SBNS_MASK (0x20U) +#define UART_BDH_SBNS_SHIFT (5U) +/*! SBNS - Stop Bit Number Select + * 0b0..Data frame consists of a single stop bit. + * 0b1..Data frame consists of two stop bits. + */ +#define UART_BDH_SBNS(x) (((uint8_t)(((uint8_t)(x)) << UART_BDH_SBNS_SHIFT)) & UART_BDH_SBNS_MASK) +#define UART_BDH_RXEDGIE_MASK (0x40U) +#define UART_BDH_RXEDGIE_SHIFT (6U) +/*! RXEDGIE - RxD Input Active Edge Interrupt Enable + * 0b0..Hardware interrupts from RXEDGIF disabled using polling. + * 0b1..RXEDGIF interrupt request enabled. + */ +#define UART_BDH_RXEDGIE(x) (((uint8_t)(((uint8_t)(x)) << UART_BDH_RXEDGIE_SHIFT)) & UART_BDH_RXEDGIE_MASK) +#define UART_BDH_LBKDIE_MASK (0x80U) +#define UART_BDH_LBKDIE_SHIFT (7U) +/*! LBKDIE - LIN Break Detect Interrupt or DMA Request Enable + * 0b0..LBKDIF interrupt and DMA transfer requests disabled. + * 0b1..LBKDIF interrupt or DMA transfer requests enabled. + */ +#define UART_BDH_LBKDIE(x) (((uint8_t)(((uint8_t)(x)) << UART_BDH_LBKDIE_SHIFT)) & UART_BDH_LBKDIE_MASK) +/*! @} */ + +/*! @name BDL - UART Baud Rate Registers: Low */ +/*! @{ */ +#define UART_BDL_SBR_MASK (0xFFU) +#define UART_BDL_SBR_SHIFT (0U) +#define UART_BDL_SBR(x) (((uint8_t)(((uint8_t)(x)) << UART_BDL_SBR_SHIFT)) & UART_BDL_SBR_MASK) +/*! @} */ + +/*! @name C1 - UART Control Register 1 */ +/*! @{ */ +#define UART_C1_PT_MASK (0x1U) +#define UART_C1_PT_SHIFT (0U) +/*! PT - Parity Type + * 0b0..Even parity. + * 0b1..Odd parity. + */ +#define UART_C1_PT(x) (((uint8_t)(((uint8_t)(x)) << UART_C1_PT_SHIFT)) & UART_C1_PT_MASK) +#define UART_C1_PE_MASK (0x2U) +#define UART_C1_PE_SHIFT (1U) +/*! PE - Parity Enable + * 0b0..Parity function disabled. + * 0b1..Parity function enabled. + */ +#define UART_C1_PE(x) (((uint8_t)(((uint8_t)(x)) << UART_C1_PE_SHIFT)) & UART_C1_PE_MASK) +#define UART_C1_ILT_MASK (0x4U) +#define UART_C1_ILT_SHIFT (2U) +/*! ILT - Idle Line Type Select + * 0b0..Idle character bit count starts after start bit. + * 0b1..Idle character bit count starts after stop bit. + */ +#define UART_C1_ILT(x) (((uint8_t)(((uint8_t)(x)) << UART_C1_ILT_SHIFT)) & UART_C1_ILT_MASK) +#define UART_C1_WAKE_MASK (0x8U) +#define UART_C1_WAKE_SHIFT (3U) +/*! WAKE - Receiver Wakeup Method Select + * 0b0..Idle line wakeup. + * 0b1..Address mark wakeup. + */ +#define UART_C1_WAKE(x) (((uint8_t)(((uint8_t)(x)) << UART_C1_WAKE_SHIFT)) & UART_C1_WAKE_MASK) +#define UART_C1_M_MASK (0x10U) +#define UART_C1_M_SHIFT (4U) +/*! M - 9-bit or 8-bit Mode Select + * 0b0..Normal-start + 8 data bits (MSB/LSB first as determined by MSBF) + stop. + * 0b1..Use-start + 9 data bits (MSB/LSB first as determined by MSBF) + stop. + */ +#define UART_C1_M(x) (((uint8_t)(((uint8_t)(x)) << UART_C1_M_SHIFT)) & UART_C1_M_MASK) +#define UART_C1_RSRC_MASK (0x20U) +#define UART_C1_RSRC_SHIFT (5U) +/*! RSRC - Receiver Source Select + * 0b0..Selects internal loop back mode. The receiver input is internally connected to transmitter output. + * 0b1..Single wire UART mode where the receiver input is connected to the transmit pin input signal. + */ +#define UART_C1_RSRC(x) (((uint8_t)(((uint8_t)(x)) << UART_C1_RSRC_SHIFT)) & UART_C1_RSRC_MASK) +#define UART_C1_UARTSWAI_MASK (0x40U) +#define UART_C1_UARTSWAI_SHIFT (6U) +/*! UARTSWAI - UART Stops in Wait Mode + * 0b0..UART clock continues to run in Wait mode. + * 0b1..UART clock freezes while CPU is in Wait mode. + */ +#define UART_C1_UARTSWAI(x) (((uint8_t)(((uint8_t)(x)) << UART_C1_UARTSWAI_SHIFT)) & UART_C1_UARTSWAI_MASK) +#define UART_C1_LOOPS_MASK (0x80U) +#define UART_C1_LOOPS_SHIFT (7U) +/*! LOOPS - Loop Mode Select + * 0b0..Normal operation. + * 0b1..Loop mode where transmitter output is internally connected to receiver input. The receiver input is determined by RSRC. + */ +#define UART_C1_LOOPS(x) (((uint8_t)(((uint8_t)(x)) << UART_C1_LOOPS_SHIFT)) & UART_C1_LOOPS_MASK) +/*! @} */ + +/*! @name C2 - UART Control Register 2 */ +/*! @{ */ +#define UART_C2_SBK_MASK (0x1U) +#define UART_C2_SBK_SHIFT (0U) +/*! SBK - Send Break + * 0b0..Normal transmitter operation. + * 0b1..Queue break characters to be sent. + */ +#define UART_C2_SBK(x) (((uint8_t)(((uint8_t)(x)) << UART_C2_SBK_SHIFT)) & UART_C2_SBK_MASK) +#define UART_C2_RWU_MASK (0x2U) +#define UART_C2_RWU_SHIFT (1U) +/*! RWU - Receiver Wakeup Control + * 0b0..Normal operation. + * 0b1..RWU enables the wakeup function and inhibits further receiver interrupt requests. Normally, hardware wakes the receiver by automatically clearing RWU. + */ +#define UART_C2_RWU(x) (((uint8_t)(((uint8_t)(x)) << UART_C2_RWU_SHIFT)) & UART_C2_RWU_MASK) +#define UART_C2_RE_MASK (0x4U) +#define UART_C2_RE_SHIFT (2U) +/*! RE - Receiver Enable + * 0b0..Receiver off. + * 0b1..Receiver on. + */ +#define UART_C2_RE(x) (((uint8_t)(((uint8_t)(x)) << UART_C2_RE_SHIFT)) & UART_C2_RE_MASK) +#define UART_C2_TE_MASK (0x8U) +#define UART_C2_TE_SHIFT (3U) +/*! TE - Transmitter Enable + * 0b0..Transmitter off. + * 0b1..Transmitter on. + */ +#define UART_C2_TE(x) (((uint8_t)(((uint8_t)(x)) << UART_C2_TE_SHIFT)) & UART_C2_TE_MASK) +#define UART_C2_ILIE_MASK (0x10U) +#define UART_C2_ILIE_SHIFT (4U) +/*! ILIE - Idle Line Interrupt DMA Transfer Enable + * 0b0..IDLE interrupt requests disabled. and DMA transfer + * 0b1..IDLE interrupt requests enabled. or DMA transfer + */ +#define UART_C2_ILIE(x) (((uint8_t)(((uint8_t)(x)) << UART_C2_ILIE_SHIFT)) & UART_C2_ILIE_MASK) +#define UART_C2_RIE_MASK (0x20U) +#define UART_C2_RIE_SHIFT (5U) +/*! RIE - Receiver Full Interrupt or DMA Transfer Enable + * 0b0..RDRF interrupt and DMA transfer requests disabled. + * 0b1..RDRF interrupt or DMA transfer requests enabled. + */ +#define UART_C2_RIE(x) (((uint8_t)(((uint8_t)(x)) << UART_C2_RIE_SHIFT)) & UART_C2_RIE_MASK) +#define UART_C2_TCIE_MASK (0x40U) +#define UART_C2_TCIE_SHIFT (6U) +/*! TCIE - Transmission Complete Interrupt or DMA Transfer Enable + * 0b0..TC interrupt and DMA transfer requests disabled. + * 0b1..TC interrupt or DMA transfer requests enabled. + */ +#define UART_C2_TCIE(x) (((uint8_t)(((uint8_t)(x)) << UART_C2_TCIE_SHIFT)) & UART_C2_TCIE_MASK) +#define UART_C2_TIE_MASK (0x80U) +#define UART_C2_TIE_SHIFT (7U) +/*! TIE - Transmitter Interrupt or DMA Transfer Enable. + * 0b0..TDRE interrupt and DMA transfer requests disabled. + * 0b1..TDRE interrupt or DMA transfer requests enabled. + */ +#define UART_C2_TIE(x) (((uint8_t)(((uint8_t)(x)) << UART_C2_TIE_SHIFT)) & UART_C2_TIE_MASK) +/*! @} */ + +/*! @name S1 - UART Status Register 1 */ +/*! @{ */ +#define UART_S1_PF_MASK (0x1U) +#define UART_S1_PF_SHIFT (0U) +/*! PF - Parity Error Flag + * 0b0..No parity error detected since the last time this flag was cleared. If the receive buffer has a depth greater than 1, then there may be data in the receive buffer what was received with a parity error. + * 0b1..At least one dataword was received with a parity error since the last time this flag was cleared. + */ +#define UART_S1_PF(x) (((uint8_t)(((uint8_t)(x)) << UART_S1_PF_SHIFT)) & UART_S1_PF_MASK) +#define UART_S1_FE_MASK (0x2U) +#define UART_S1_FE_SHIFT (1U) +/*! FE - Framing Error Flag + * 0b0..No framing error detected. + * 0b1..Framing error. + */ +#define UART_S1_FE(x) (((uint8_t)(((uint8_t)(x)) << UART_S1_FE_SHIFT)) & UART_S1_FE_MASK) +#define UART_S1_NF_MASK (0x4U) +#define UART_S1_NF_SHIFT (2U) +/*! NF - Noise Flag + * 0b0..No noise detected since the last time this flag was cleared. If the receive buffer has a depth greater than 1 then there may be data in the receiver buffer that was received with noise. + * 0b1..At least one dataword was received with noise detected since the last time the flag was cleared. + */ +#define UART_S1_NF(x) (((uint8_t)(((uint8_t)(x)) << UART_S1_NF_SHIFT)) & UART_S1_NF_MASK) +#define UART_S1_OR_MASK (0x8U) +#define UART_S1_OR_SHIFT (3U) +/*! OR - Receiver Overrun Flag + * 0b0..No overrun has occurred since the last time the flag was cleared. + * 0b1..Overrun has occurred or the overrun flag has not been cleared since the last overrun occured. + */ +#define UART_S1_OR(x) (((uint8_t)(((uint8_t)(x)) << UART_S1_OR_SHIFT)) & UART_S1_OR_MASK) +#define UART_S1_IDLE_MASK (0x10U) +#define UART_S1_IDLE_SHIFT (4U) +/*! IDLE - Idle Line Flag + * 0b0..Receiver input is either active now or has never become active since the IDLE flag was last cleared. + * 0b1..Receiver input has become idle or the flag has not been cleared since it last asserted. + */ +#define UART_S1_IDLE(x) (((uint8_t)(((uint8_t)(x)) << UART_S1_IDLE_SHIFT)) & UART_S1_IDLE_MASK) +#define UART_S1_RDRF_MASK (0x20U) +#define UART_S1_RDRF_SHIFT (5U) +/*! RDRF - Receive Data Register Full Flag + * 0b0..The number of datawords in the receive buffer is less than the number indicated by RXWATER. + * 0b1..The number of datawords in the receive buffer is equal to or greater than the number indicated by RXWATER at some point in time since this flag was last cleared. + */ +#define UART_S1_RDRF(x) (((uint8_t)(((uint8_t)(x)) << UART_S1_RDRF_SHIFT)) & UART_S1_RDRF_MASK) +#define UART_S1_TC_MASK (0x40U) +#define UART_S1_TC_SHIFT (6U) +/*! TC - Transmit Complete Flag + * 0b0..Transmitter active (sending data, a preamble, or a break). + * 0b1..Transmitter idle (transmission activity complete). + */ +#define UART_S1_TC(x) (((uint8_t)(((uint8_t)(x)) << UART_S1_TC_SHIFT)) & UART_S1_TC_MASK) +#define UART_S1_TDRE_MASK (0x80U) +#define UART_S1_TDRE_SHIFT (7U) +/*! TDRE - Transmit Data Register Empty Flag + * 0b0..The amount of data in the transmit buffer is greater than the value indicated by TWFIFO[TXWATER]. + * 0b1..The amount of data in the transmit buffer is less than or equal to the value indicated by TWFIFO[TXWATER] at some point in time since the flag has been cleared. + */ +#define UART_S1_TDRE(x) (((uint8_t)(((uint8_t)(x)) << UART_S1_TDRE_SHIFT)) & UART_S1_TDRE_MASK) +/*! @} */ + +/*! @name S2 - UART Status Register 2 */ +/*! @{ */ +#define UART_S2_RAF_MASK (0x1U) +#define UART_S2_RAF_SHIFT (0U) +/*! RAF - Receiver Active Flag + * 0b0..UART receiver idle/inactive waiting for a start bit. + * 0b1..UART receiver active, RxD input not idle. + */ +#define UART_S2_RAF(x) (((uint8_t)(((uint8_t)(x)) << UART_S2_RAF_SHIFT)) & UART_S2_RAF_MASK) +#define UART_S2_LBKDE_MASK (0x2U) +#define UART_S2_LBKDE_SHIFT (1U) +/*! LBKDE - LIN Break Detection Enable + * 0b0..Break character detection is disabled. + * 0b1..Break character is detected at length of 11 bit times if C1[M] = 0 or 12 bits time if C1[M] = 1. + */ +#define UART_S2_LBKDE(x) (((uint8_t)(((uint8_t)(x)) << UART_S2_LBKDE_SHIFT)) & UART_S2_LBKDE_MASK) +#define UART_S2_BRK13_MASK (0x4U) +#define UART_S2_BRK13_SHIFT (2U) +/*! BRK13 - Break Transmit Character Length + * 0b0..Break character is 10, 11, or 12 bits long. + * 0b1..Break character is 13 or 14 bits long. + */ +#define UART_S2_BRK13(x) (((uint8_t)(((uint8_t)(x)) << UART_S2_BRK13_SHIFT)) & UART_S2_BRK13_MASK) +#define UART_S2_RWUID_MASK (0x8U) +#define UART_S2_RWUID_SHIFT (3U) +/*! RWUID - Receive Wakeup Idle Detect + * 0b0..S1[IDLE] is not set upon detection of an idle character. + * 0b1..S1[IDLE] is set upon detection of an idle character. + */ +#define UART_S2_RWUID(x) (((uint8_t)(((uint8_t)(x)) << UART_S2_RWUID_SHIFT)) & UART_S2_RWUID_MASK) +#define UART_S2_RXINV_MASK (0x10U) +#define UART_S2_RXINV_SHIFT (4U) +/*! RXINV - Receive Data Inversion + * 0b0..Receive data is not inverted. + * 0b1..Receive data is inverted. + */ +#define UART_S2_RXINV(x) (((uint8_t)(((uint8_t)(x)) << UART_S2_RXINV_SHIFT)) & UART_S2_RXINV_MASK) +#define UART_S2_MSBF_MASK (0x20U) +#define UART_S2_MSBF_SHIFT (5U) +/*! MSBF - Most Significant Bit First + * 0b0..LSB (bit0) is the first bit that is transmitted following the start bit. Further, the first bit received after the start bit is identified as bit0. + * 0b1..MSB (bit8, bit7 or bit6) is the first bit that is transmitted following the start bit, depending on the setting of C1[M] and C1[PE]. Further, the first bit received after the start bit is identified as bit8, bit7, or bit6, depending on the setting of C1[M] and C1[PE]. + */ +#define UART_S2_MSBF(x) (((uint8_t)(((uint8_t)(x)) << UART_S2_MSBF_SHIFT)) & UART_S2_MSBF_MASK) +#define UART_S2_RXEDGIF_MASK (0x40U) +#define UART_S2_RXEDGIF_SHIFT (6U) +/*! RXEDGIF - RxD Pin Active Edge Interrupt Flag + * 0b0..No active edge on the receive pin has occurred. + * 0b1..An active edge on the receive pin has occurred. + */ +#define UART_S2_RXEDGIF(x) (((uint8_t)(((uint8_t)(x)) << UART_S2_RXEDGIF_SHIFT)) & UART_S2_RXEDGIF_MASK) +#define UART_S2_LBKDIF_MASK (0x80U) +#define UART_S2_LBKDIF_SHIFT (7U) +/*! LBKDIF - LIN Break Detect Interrupt Flag + * 0b0..No LIN break character detected. + * 0b1..LIN break character detected. + */ +#define UART_S2_LBKDIF(x) (((uint8_t)(((uint8_t)(x)) << UART_S2_LBKDIF_SHIFT)) & UART_S2_LBKDIF_MASK) +/*! @} */ + +/*! @name C3 - UART Control Register 3 */ +/*! @{ */ +#define UART_C3_PEIE_MASK (0x1U) +#define UART_C3_PEIE_SHIFT (0U) +/*! PEIE - Parity Error Interrupt Enable + * 0b0..PF interrupt requests are disabled. + * 0b1..PF interrupt requests are enabled. + */ +#define UART_C3_PEIE(x) (((uint8_t)(((uint8_t)(x)) << UART_C3_PEIE_SHIFT)) & UART_C3_PEIE_MASK) +#define UART_C3_FEIE_MASK (0x2U) +#define UART_C3_FEIE_SHIFT (1U) +/*! FEIE - Framing Error Interrupt Enable + * 0b0..FE interrupt requests are disabled. + * 0b1..FE interrupt requests are enabled. + */ +#define UART_C3_FEIE(x) (((uint8_t)(((uint8_t)(x)) << UART_C3_FEIE_SHIFT)) & UART_C3_FEIE_MASK) +#define UART_C3_NEIE_MASK (0x4U) +#define UART_C3_NEIE_SHIFT (2U) +/*! NEIE - Noise Error Interrupt Enable + * 0b0..NF interrupt requests are disabled. + * 0b1..NF interrupt requests are enabled. + */ +#define UART_C3_NEIE(x) (((uint8_t)(((uint8_t)(x)) << UART_C3_NEIE_SHIFT)) & UART_C3_NEIE_MASK) +#define UART_C3_ORIE_MASK (0x8U) +#define UART_C3_ORIE_SHIFT (3U) +/*! ORIE - Overrun Error Interrupt Enable + * 0b0..OR interrupts are disabled. + * 0b1..OR interrupt requests are enabled. + */ +#define UART_C3_ORIE(x) (((uint8_t)(((uint8_t)(x)) << UART_C3_ORIE_SHIFT)) & UART_C3_ORIE_MASK) +#define UART_C3_TXINV_MASK (0x10U) +#define UART_C3_TXINV_SHIFT (4U) +/*! TXINV - Transmit Data Inversion. + * 0b0..Transmit data is not inverted. + * 0b1..Transmit data is inverted. + */ +#define UART_C3_TXINV(x) (((uint8_t)(((uint8_t)(x)) << UART_C3_TXINV_SHIFT)) & UART_C3_TXINV_MASK) +#define UART_C3_TXDIR_MASK (0x20U) +#define UART_C3_TXDIR_SHIFT (5U) +/*! TXDIR - Transmitter Pin Data Direction in Single-Wire mode + * 0b0..TXD pin is an input in single wire mode. + * 0b1..TXD pin is an output in single wire mode. + */ +#define UART_C3_TXDIR(x) (((uint8_t)(((uint8_t)(x)) << UART_C3_TXDIR_SHIFT)) & UART_C3_TXDIR_MASK) +#define UART_C3_T8_MASK (0x40U) +#define UART_C3_T8_SHIFT (6U) +#define UART_C3_T8(x) (((uint8_t)(((uint8_t)(x)) << UART_C3_T8_SHIFT)) & UART_C3_T8_MASK) +#define UART_C3_R8_MASK (0x80U) +#define UART_C3_R8_SHIFT (7U) +#define UART_C3_R8(x) (((uint8_t)(((uint8_t)(x)) << UART_C3_R8_SHIFT)) & UART_C3_R8_MASK) +/*! @} */ + +/*! @name D - UART Data Register */ +/*! @{ */ +#define UART_D_RT_MASK (0xFFU) +#define UART_D_RT_SHIFT (0U) +#define UART_D_RT(x) (((uint8_t)(((uint8_t)(x)) << UART_D_RT_SHIFT)) & UART_D_RT_MASK) +/*! @} */ + +/*! @name MA1 - UART Match Address Registers 1 */ +/*! @{ */ +#define UART_MA1_MA_MASK (0xFFU) +#define UART_MA1_MA_SHIFT (0U) +#define UART_MA1_MA(x) (((uint8_t)(((uint8_t)(x)) << UART_MA1_MA_SHIFT)) & UART_MA1_MA_MASK) +/*! @} */ + +/*! @name MA2 - UART Match Address Registers 2 */ +/*! @{ */ +#define UART_MA2_MA_MASK (0xFFU) +#define UART_MA2_MA_SHIFT (0U) +#define UART_MA2_MA(x) (((uint8_t)(((uint8_t)(x)) << UART_MA2_MA_SHIFT)) & UART_MA2_MA_MASK) +/*! @} */ + +/*! @name C4 - UART Control Register 4 */ +/*! @{ */ +#define UART_C4_BRFA_MASK (0x1FU) +#define UART_C4_BRFA_SHIFT (0U) +#define UART_C4_BRFA(x) (((uint8_t)(((uint8_t)(x)) << UART_C4_BRFA_SHIFT)) & UART_C4_BRFA_MASK) +#define UART_C4_M10_MASK (0x20U) +#define UART_C4_M10_SHIFT (5U) +/*! M10 - 10-bit Mode select + * 0b0..The parity bit is the ninth bit in the serial transmission. + * 0b1..The parity bit is the tenth bit in the serial transmission. + */ +#define UART_C4_M10(x) (((uint8_t)(((uint8_t)(x)) << UART_C4_M10_SHIFT)) & UART_C4_M10_MASK) +#define UART_C4_MAEN2_MASK (0x40U) +#define UART_C4_MAEN2_SHIFT (6U) +/*! MAEN2 - Match Address Mode Enable 2 + * 0b0..All data received is transferred to the data buffer if MAEN1 is cleared. + * 0b1..All data received with the most significant bit cleared, is discarded. All data received with the most significant bit set, is compared with contents of MA2 register. If no match occurs, the data is discarded. If a match occurs, data is transferred to the data buffer. This field must be cleared when C7816[ISO7816E] is set/enabled. + */ +#define UART_C4_MAEN2(x) (((uint8_t)(((uint8_t)(x)) << UART_C4_MAEN2_SHIFT)) & UART_C4_MAEN2_MASK) +#define UART_C4_MAEN1_MASK (0x80U) +#define UART_C4_MAEN1_SHIFT (7U) +/*! MAEN1 - Match Address Mode Enable 1 + * 0b0..All data received is transferred to the data buffer if MAEN2 is cleared. + * 0b1..All data received with the most significant bit cleared, is discarded. All data received with the most significant bit set, is compared with contents of MA1 register. If no match occurs, the data is discarded. If match occurs, data is transferred to the data buffer. This field must be cleared when C7816[ISO7816E] is set/enabled. + */ +#define UART_C4_MAEN1(x) (((uint8_t)(((uint8_t)(x)) << UART_C4_MAEN1_SHIFT)) & UART_C4_MAEN1_MASK) +/*! @} */ + +/*! @name C5 - UART Control Register 5 */ +/*! @{ */ +#define UART_C5_LBKDDMAS_MASK (0x8U) +#define UART_C5_LBKDDMAS_SHIFT (3U) +/*! LBKDDMAS - LIN Break Detect DMA Select Bit + * 0b0..If BDH[LBKDIE] and S2[LBKDIF] are set, the LBKDIF interrupt signal is asserted to request an interrupt service. + * 0b1..If BDH[LBKDIE] and S2[LBKDIF] are set, the LBKDIF DMA request signal is asserted to request a DMA transfer. + */ +#define UART_C5_LBKDDMAS(x) (((uint8_t)(((uint8_t)(x)) << UART_C5_LBKDDMAS_SHIFT)) & UART_C5_LBKDDMAS_MASK) +#define UART_C5_ILDMAS_MASK (0x10U) +#define UART_C5_ILDMAS_SHIFT (4U) +/*! ILDMAS - Idle Line DMA Select + * 0b0..If C2[ILIE] and S1[IDLE] are set, the IDLE interrupt request signal is asserted to request an interrupt service. + * 0b1..If C2[ILIE] and S1[IDLE] are set, the IDLE DMA request signal is asserted to request a DMA transfer. + */ +#define UART_C5_ILDMAS(x) (((uint8_t)(((uint8_t)(x)) << UART_C5_ILDMAS_SHIFT)) & UART_C5_ILDMAS_MASK) +#define UART_C5_RDMAS_MASK (0x20U) +#define UART_C5_RDMAS_SHIFT (5U) +/*! RDMAS - Receiver Full DMA Select + * 0b0..If C2[RIE] and S1[RDRF] are set, the RDFR interrupt request signal is asserted to request an interrupt service. + * 0b1..If C2[RIE] and S1[RDRF] are set, the RDRF DMA request signal is asserted to request a DMA transfer. + */ +#define UART_C5_RDMAS(x) (((uint8_t)(((uint8_t)(x)) << UART_C5_RDMAS_SHIFT)) & UART_C5_RDMAS_MASK) +#define UART_C5_TCDMAS_MASK (0x40U) +#define UART_C5_TCDMAS_SHIFT (6U) +/*! TCDMAS - Transmission Complete DMA Select + * 0b0..If C2[TCIE] is set and the S1[TC] flag is set, the TC interrupt request signal is asserted to request an interrupt service. + * 0b1..If C2[TCIE] is set and the S1[TC] flag is set, the TC DMA request signal is asserted to request a DMA transfer. + */ +#define UART_C5_TCDMAS(x) (((uint8_t)(((uint8_t)(x)) << UART_C5_TCDMAS_SHIFT)) & UART_C5_TCDMAS_MASK) +#define UART_C5_TDMAS_MASK (0x80U) +#define UART_C5_TDMAS_SHIFT (7U) +/*! TDMAS - Transmitter DMA Select + * 0b0..If C2[TIE] is set and the S1[TDRE] flag is set, the TDRE interrupt request signal is asserted to request interrupt service. + * 0b1..If C2[TIE] is set and the S1[TDRE] flag is set, the TDRE DMA request signal is asserted to request a DMA transfer. + */ +#define UART_C5_TDMAS(x) (((uint8_t)(((uint8_t)(x)) << UART_C5_TDMAS_SHIFT)) & UART_C5_TDMAS_MASK) +/*! @} */ + +/*! @name ED - UART Extended Data Register */ +/*! @{ */ +#define UART_ED_PARITYE_MASK (0x40U) +#define UART_ED_PARITYE_SHIFT (6U) +/*! PARITYE + * 0b0..The dataword was received without a parity error. + * 0b1..The dataword was received with a parity error. + */ +#define UART_ED_PARITYE(x) (((uint8_t)(((uint8_t)(x)) << UART_ED_PARITYE_SHIFT)) & UART_ED_PARITYE_MASK) +#define UART_ED_NOISY_MASK (0x80U) +#define UART_ED_NOISY_SHIFT (7U) +/*! NOISY + * 0b0..The dataword was received without noise. + * 0b1..The data was received with noise. + */ +#define UART_ED_NOISY(x) (((uint8_t)(((uint8_t)(x)) << UART_ED_NOISY_SHIFT)) & UART_ED_NOISY_MASK) +/*! @} */ + +/*! @name MODEM - UART Modem Register */ +/*! @{ */ +#define UART_MODEM_TXCTSE_MASK (0x1U) +#define UART_MODEM_TXCTSE_SHIFT (0U) +/*! TXCTSE - Transmitter clear-to-send enable + * 0b0..CTS has no effect on the transmitter. + * 0b1..Enables clear-to-send operation. The transmitter checks the state of CTS each time it is ready to send a character. If CTS is asserted, the character is sent. If CTS is deasserted, the signal TXD remains in the mark state and transmission is delayed until CTS is asserted. Changes in CTS as a character is being sent do not affect its transmission. + */ +#define UART_MODEM_TXCTSE(x) (((uint8_t)(((uint8_t)(x)) << UART_MODEM_TXCTSE_SHIFT)) & UART_MODEM_TXCTSE_MASK) +#define UART_MODEM_TXRTSE_MASK (0x2U) +#define UART_MODEM_TXRTSE_SHIFT (1U) +/*! TXRTSE - Transmitter request-to-send enable + * 0b0..The transmitter has no effect on RTS. + * 0b1..When a character is placed into an empty transmitter data buffer , RTS asserts one bit time before the start bit is transmitted. RTS deasserts one bit time after all characters in the transmitter data buffer and shift register are completely sent, including the last stop bit. (FIFO) (FIFO) + */ +#define UART_MODEM_TXRTSE(x) (((uint8_t)(((uint8_t)(x)) << UART_MODEM_TXRTSE_SHIFT)) & UART_MODEM_TXRTSE_MASK) +#define UART_MODEM_TXRTSPOL_MASK (0x4U) +#define UART_MODEM_TXRTSPOL_SHIFT (2U) +/*! TXRTSPOL - Transmitter request-to-send polarity + * 0b0..Transmitter RTS is active low. + * 0b1..Transmitter RTS is active high. + */ +#define UART_MODEM_TXRTSPOL(x) (((uint8_t)(((uint8_t)(x)) << UART_MODEM_TXRTSPOL_SHIFT)) & UART_MODEM_TXRTSPOL_MASK) +#define UART_MODEM_RXRTSE_MASK (0x8U) +#define UART_MODEM_RXRTSE_SHIFT (3U) +/*! RXRTSE - Receiver request-to-send enable + * 0b0..The receiver has no effect on RTS. + * 0b1..RTS is deasserted if the number of characters in the receiver data register (FIFO) is equal to or greater than RWFIFO[RXWATER]. RTS is asserted when the number of characters in the receiver data register (FIFO) is less than RWFIFO[RXWATER]. + */ +#define UART_MODEM_RXRTSE(x) (((uint8_t)(((uint8_t)(x)) << UART_MODEM_RXRTSE_SHIFT)) & UART_MODEM_RXRTSE_MASK) +/*! @} */ + +/*! @name IR - UART Infrared Register */ +/*! @{ */ +#define UART_IR_TNP_MASK (0x3U) +#define UART_IR_TNP_SHIFT (0U) +/*! TNP - Transmitter narrow pulse + * 0b00..3/16. + * 0b01..1/16. + * 0b10..1/32. + * 0b11..1/4. + */ +#define UART_IR_TNP(x) (((uint8_t)(((uint8_t)(x)) << UART_IR_TNP_SHIFT)) & UART_IR_TNP_MASK) +#define UART_IR_IREN_MASK (0x4U) +#define UART_IR_IREN_SHIFT (2U) +/*! IREN - Infrared enable + * 0b0..IR disabled. + * 0b1..IR enabled. + */ +#define UART_IR_IREN(x) (((uint8_t)(((uint8_t)(x)) << UART_IR_IREN_SHIFT)) & UART_IR_IREN_MASK) +/*! @} */ + +/*! @name PFIFO - UART FIFO Parameters */ +/*! @{ */ +#define UART_PFIFO_RXFIFOSIZE_MASK (0x7U) +#define UART_PFIFO_RXFIFOSIZE_SHIFT (0U) +/*! RXFIFOSIZE - Receive FIFO. Buffer Depth + * 0b000..Receive FIFO/Buffer depth = 1 dataword. + * 0b001..Receive FIFO/Buffer depth = 4 datawords. + * 0b010..Receive FIFO/Buffer depth = 8 datawords. + * 0b011..Receive FIFO/Buffer depth = 16 datawords. + * 0b100..Receive FIFO/Buffer depth = 32 datawords. + * 0b101..Receive FIFO/Buffer depth = 64 datawords. + * 0b110..Receive FIFO/Buffer depth = 128 datawords. + * 0b111..Reserved. + */ +#define UART_PFIFO_RXFIFOSIZE(x) (((uint8_t)(((uint8_t)(x)) << UART_PFIFO_RXFIFOSIZE_SHIFT)) & UART_PFIFO_RXFIFOSIZE_MASK) +#define UART_PFIFO_RXFE_MASK (0x8U) +#define UART_PFIFO_RXFE_SHIFT (3U) +/*! RXFE - Receive FIFO Enable + * 0b0..Receive FIFO is not enabled. Buffer is depth 1. (Legacy support) + * 0b1..Receive FIFO is enabled. Buffer is depth indicted by RXFIFOSIZE. + */ +#define UART_PFIFO_RXFE(x) (((uint8_t)(((uint8_t)(x)) << UART_PFIFO_RXFE_SHIFT)) & UART_PFIFO_RXFE_MASK) +#define UART_PFIFO_TXFIFOSIZE_MASK (0x70U) +#define UART_PFIFO_TXFIFOSIZE_SHIFT (4U) +/*! TXFIFOSIZE - Transmit FIFO. Buffer Depth + * 0b000..Transmit FIFO/Buffer depth = 1 dataword. + * 0b001..Transmit FIFO/Buffer depth = 4 datawords. + * 0b010..Transmit FIFO/Buffer depth = 8 datawords. + * 0b011..Transmit FIFO/Buffer depth = 16 datawords. + * 0b100..Transmit FIFO/Buffer depth = 32 datawords. + * 0b101..Transmit FIFO/Buffer depth = 64 datawords. + * 0b110..Transmit FIFO/Buffer depth = 128 datawords. + * 0b111..Reserved. + */ +#define UART_PFIFO_TXFIFOSIZE(x) (((uint8_t)(((uint8_t)(x)) << UART_PFIFO_TXFIFOSIZE_SHIFT)) & UART_PFIFO_TXFIFOSIZE_MASK) +#define UART_PFIFO_TXFE_MASK (0x80U) +#define UART_PFIFO_TXFE_SHIFT (7U) +/*! TXFE - Transmit FIFO Enable + * 0b0..Transmit FIFO is not enabled. Buffer is depth 1. (Legacy support). + * 0b1..Transmit FIFO is enabled. Buffer is depth indicated by TXFIFOSIZE. + */ +#define UART_PFIFO_TXFE(x) (((uint8_t)(((uint8_t)(x)) << UART_PFIFO_TXFE_SHIFT)) & UART_PFIFO_TXFE_MASK) +/*! @} */ + +/*! @name CFIFO - UART FIFO Control Register */ +/*! @{ */ +#define UART_CFIFO_RXUFE_MASK (0x1U) +#define UART_CFIFO_RXUFE_SHIFT (0U) +/*! RXUFE - Receive FIFO Underflow Interrupt Enable + * 0b0..RXUF flag does not generate an interrupt to the host. + * 0b1..RXUF flag generates an interrupt to the host. + */ +#define UART_CFIFO_RXUFE(x) (((uint8_t)(((uint8_t)(x)) << UART_CFIFO_RXUFE_SHIFT)) & UART_CFIFO_RXUFE_MASK) +#define UART_CFIFO_TXOFE_MASK (0x2U) +#define UART_CFIFO_TXOFE_SHIFT (1U) +/*! TXOFE - Transmit FIFO Overflow Interrupt Enable + * 0b0..TXOF flag does not generate an interrupt to the host. + * 0b1..TXOF flag generates an interrupt to the host. + */ +#define UART_CFIFO_TXOFE(x) (((uint8_t)(((uint8_t)(x)) << UART_CFIFO_TXOFE_SHIFT)) & UART_CFIFO_TXOFE_MASK) +#define UART_CFIFO_RXOFE_MASK (0x4U) +#define UART_CFIFO_RXOFE_SHIFT (2U) +/*! RXOFE - Receive FIFO Overflow Interrupt Enable + * 0b0..RXOF flag does not generate an interrupt to the host. + * 0b1..RXOF flag generates an interrupt to the host. + */ +#define UART_CFIFO_RXOFE(x) (((uint8_t)(((uint8_t)(x)) << UART_CFIFO_RXOFE_SHIFT)) & UART_CFIFO_RXOFE_MASK) +#define UART_CFIFO_RXFLUSH_MASK (0x40U) +#define UART_CFIFO_RXFLUSH_SHIFT (6U) +/*! RXFLUSH - Receive FIFO/Buffer Flush + * 0b0..No flush operation occurs. + * 0b1..All data in the receive FIFO/buffer is cleared out. + */ +#define UART_CFIFO_RXFLUSH(x) (((uint8_t)(((uint8_t)(x)) << UART_CFIFO_RXFLUSH_SHIFT)) & UART_CFIFO_RXFLUSH_MASK) +#define UART_CFIFO_TXFLUSH_MASK (0x80U) +#define UART_CFIFO_TXFLUSH_SHIFT (7U) +/*! TXFLUSH - Transmit FIFO/Buffer Flush + * 0b0..No flush operation occurs. + * 0b1..All data in the transmit FIFO/Buffer is cleared out. + */ +#define UART_CFIFO_TXFLUSH(x) (((uint8_t)(((uint8_t)(x)) << UART_CFIFO_TXFLUSH_SHIFT)) & UART_CFIFO_TXFLUSH_MASK) +/*! @} */ + +/*! @name SFIFO - UART FIFO Status Register */ +/*! @{ */ +#define UART_SFIFO_RXUF_MASK (0x1U) +#define UART_SFIFO_RXUF_SHIFT (0U) +/*! RXUF - Receiver Buffer Underflow Flag + * 0b0..No receive buffer underflow has occurred since the last time the flag was cleared. + * 0b1..At least one receive buffer underflow has occurred since the last time the flag was cleared. + */ +#define UART_SFIFO_RXUF(x) (((uint8_t)(((uint8_t)(x)) << UART_SFIFO_RXUF_SHIFT)) & UART_SFIFO_RXUF_MASK) +#define UART_SFIFO_TXOF_MASK (0x2U) +#define UART_SFIFO_TXOF_SHIFT (1U) +/*! TXOF - Transmitter Buffer Overflow Flag + * 0b0..No transmit buffer overflow has occurred since the last time the flag was cleared. + * 0b1..At least one transmit buffer overflow has occurred since the last time the flag was cleared. + */ +#define UART_SFIFO_TXOF(x) (((uint8_t)(((uint8_t)(x)) << UART_SFIFO_TXOF_SHIFT)) & UART_SFIFO_TXOF_MASK) +#define UART_SFIFO_RXOF_MASK (0x4U) +#define UART_SFIFO_RXOF_SHIFT (2U) +/*! RXOF - Receiver Buffer Overflow Flag + * 0b0..No receive buffer overflow has occurred since the last time the flag was cleared. + * 0b1..At least one receive buffer overflow has occurred since the last time the flag was cleared. + */ +#define UART_SFIFO_RXOF(x) (((uint8_t)(((uint8_t)(x)) << UART_SFIFO_RXOF_SHIFT)) & UART_SFIFO_RXOF_MASK) +#define UART_SFIFO_RXEMPT_MASK (0x40U) +#define UART_SFIFO_RXEMPT_SHIFT (6U) +/*! RXEMPT - Receive Buffer/FIFO Empty + * 0b0..Receive buffer is not empty. + * 0b1..Receive buffer is empty. + */ +#define UART_SFIFO_RXEMPT(x) (((uint8_t)(((uint8_t)(x)) << UART_SFIFO_RXEMPT_SHIFT)) & UART_SFIFO_RXEMPT_MASK) +#define UART_SFIFO_TXEMPT_MASK (0x80U) +#define UART_SFIFO_TXEMPT_SHIFT (7U) +/*! TXEMPT - Transmit Buffer/FIFO Empty + * 0b0..Transmit buffer is not empty. + * 0b1..Transmit buffer is empty. + */ +#define UART_SFIFO_TXEMPT(x) (((uint8_t)(((uint8_t)(x)) << UART_SFIFO_TXEMPT_SHIFT)) & UART_SFIFO_TXEMPT_MASK) +/*! @} */ + +/*! @name TWFIFO - UART FIFO Transmit Watermark */ +/*! @{ */ +#define UART_TWFIFO_TXWATER_MASK (0xFFU) +#define UART_TWFIFO_TXWATER_SHIFT (0U) +#define UART_TWFIFO_TXWATER(x) (((uint8_t)(((uint8_t)(x)) << UART_TWFIFO_TXWATER_SHIFT)) & UART_TWFIFO_TXWATER_MASK) +/*! @} */ + +/*! @name TCFIFO - UART FIFO Transmit Count */ +/*! @{ */ +#define UART_TCFIFO_TXCOUNT_MASK (0xFFU) +#define UART_TCFIFO_TXCOUNT_SHIFT (0U) +#define UART_TCFIFO_TXCOUNT(x) (((uint8_t)(((uint8_t)(x)) << UART_TCFIFO_TXCOUNT_SHIFT)) & UART_TCFIFO_TXCOUNT_MASK) +/*! @} */ + +/*! @name RWFIFO - UART FIFO Receive Watermark */ +/*! @{ */ +#define UART_RWFIFO_RXWATER_MASK (0xFFU) +#define UART_RWFIFO_RXWATER_SHIFT (0U) +#define UART_RWFIFO_RXWATER(x) (((uint8_t)(((uint8_t)(x)) << UART_RWFIFO_RXWATER_SHIFT)) & UART_RWFIFO_RXWATER_MASK) +/*! @} */ + +/*! @name RCFIFO - UART FIFO Receive Count */ +/*! @{ */ +#define UART_RCFIFO_RXCOUNT_MASK (0xFFU) +#define UART_RCFIFO_RXCOUNT_SHIFT (0U) +#define UART_RCFIFO_RXCOUNT(x) (((uint8_t)(((uint8_t)(x)) << UART_RCFIFO_RXCOUNT_SHIFT)) & UART_RCFIFO_RXCOUNT_MASK) +/*! @} */ + +/*! @name C7816 - UART 7816 Control Register */ +/*! @{ */ +#define UART_C7816_ISO_7816E_MASK (0x1U) +#define UART_C7816_ISO_7816E_SHIFT (0U) +/*! ISO_7816E - ISO-7816 Functionality Enabled + * 0b0..ISO-7816 functionality is turned off/not enabled. + * 0b1..ISO-7816 functionality is turned on/enabled. + */ +#define UART_C7816_ISO_7816E(x) (((uint8_t)(((uint8_t)(x)) << UART_C7816_ISO_7816E_SHIFT)) & UART_C7816_ISO_7816E_MASK) +#define UART_C7816_TTYPE_MASK (0x2U) +#define UART_C7816_TTYPE_SHIFT (1U) +/*! TTYPE - Transfer Type + * 0b0..T = 0 per the ISO-7816 specification. + * 0b1..T = 1 per the ISO-7816 specification. + */ +#define UART_C7816_TTYPE(x) (((uint8_t)(((uint8_t)(x)) << UART_C7816_TTYPE_SHIFT)) & UART_C7816_TTYPE_MASK) +#define UART_C7816_INIT_MASK (0x4U) +#define UART_C7816_INIT_SHIFT (2U) +/*! INIT - Detect Initial Character + * 0b0..Normal operating mode. Receiver does not seek to identify initial character. + * 0b1..Receiver searches for initial character. + */ +#define UART_C7816_INIT(x) (((uint8_t)(((uint8_t)(x)) << UART_C7816_INIT_SHIFT)) & UART_C7816_INIT_MASK) +#define UART_C7816_ANACK_MASK (0x8U) +#define UART_C7816_ANACK_SHIFT (3U) +/*! ANACK - Generate NACK on Error + * 0b0..No NACK is automatically generated. + * 0b1..A NACK is automatically generated if a parity error is detected or if an invalid initial character is detected. + */ +#define UART_C7816_ANACK(x) (((uint8_t)(((uint8_t)(x)) << UART_C7816_ANACK_SHIFT)) & UART_C7816_ANACK_MASK) +#define UART_C7816_ONACK_MASK (0x10U) +#define UART_C7816_ONACK_SHIFT (4U) +/*! ONACK - Generate NACK on Overflow + * 0b0..The received data does not generate a NACK when the receipt of the data results in an overflow event. + * 0b1..If the receiver buffer overflows, a NACK is automatically sent on a received character. + */ +#define UART_C7816_ONACK(x) (((uint8_t)(((uint8_t)(x)) << UART_C7816_ONACK_SHIFT)) & UART_C7816_ONACK_MASK) +/*! @} */ + +/*! @name IE7816 - UART 7816 Interrupt Enable Register */ +/*! @{ */ +#define UART_IE7816_RXTE_MASK (0x1U) +#define UART_IE7816_RXTE_SHIFT (0U) +/*! RXTE - Receive Threshold Exceeded Interrupt Enable + * 0b0..The assertion of IS7816[RXT] does not result in the generation of an interrupt. + * 0b1..The assertion of IS7816[RXT] results in the generation of an interrupt. + */ +#define UART_IE7816_RXTE(x) (((uint8_t)(((uint8_t)(x)) << UART_IE7816_RXTE_SHIFT)) & UART_IE7816_RXTE_MASK) +#define UART_IE7816_TXTE_MASK (0x2U) +#define UART_IE7816_TXTE_SHIFT (1U) +/*! TXTE - Transmit Threshold Exceeded Interrupt Enable + * 0b0..The assertion of IS7816[TXT] does not result in the generation of an interrupt. + * 0b1..The assertion of IS7816[TXT] results in the generation of an interrupt. + */ +#define UART_IE7816_TXTE(x) (((uint8_t)(((uint8_t)(x)) << UART_IE7816_TXTE_SHIFT)) & UART_IE7816_TXTE_MASK) +#define UART_IE7816_GTVE_MASK (0x4U) +#define UART_IE7816_GTVE_SHIFT (2U) +/*! GTVE - Guard Timer Violated Interrupt Enable + * 0b0..The assertion of IS7816[GTV] does not result in the generation of an interrupt. + * 0b1..The assertion of IS7816[GTV] results in the generation of an interrupt. + */ +#define UART_IE7816_GTVE(x) (((uint8_t)(((uint8_t)(x)) << UART_IE7816_GTVE_SHIFT)) & UART_IE7816_GTVE_MASK) +#define UART_IE7816_INITDE_MASK (0x10U) +#define UART_IE7816_INITDE_SHIFT (4U) +/*! INITDE - Initial Character Detected Interrupt Enable + * 0b0..The assertion of IS7816[INITD] does not result in the generation of an interrupt. + * 0b1..The assertion of IS7816[INITD] results in the generation of an interrupt. + */ +#define UART_IE7816_INITDE(x) (((uint8_t)(((uint8_t)(x)) << UART_IE7816_INITDE_SHIFT)) & UART_IE7816_INITDE_MASK) +#define UART_IE7816_BWTE_MASK (0x20U) +#define UART_IE7816_BWTE_SHIFT (5U) +/*! BWTE - Block Wait Timer Interrupt Enable + * 0b0..The assertion of IS7816[BWT] does not result in the generation of an interrupt. + * 0b1..The assertion of IS7816[BWT] results in the generation of an interrupt. + */ +#define UART_IE7816_BWTE(x) (((uint8_t)(((uint8_t)(x)) << UART_IE7816_BWTE_SHIFT)) & UART_IE7816_BWTE_MASK) +#define UART_IE7816_CWTE_MASK (0x40U) +#define UART_IE7816_CWTE_SHIFT (6U) +/*! CWTE - Character Wait Timer Interrupt Enable + * 0b0..The assertion of IS7816[CWT] does not result in the generation of an interrupt. + * 0b1..The assertion of IS7816[CWT] results in the generation of an interrupt. + */ +#define UART_IE7816_CWTE(x) (((uint8_t)(((uint8_t)(x)) << UART_IE7816_CWTE_SHIFT)) & UART_IE7816_CWTE_MASK) +#define UART_IE7816_WTE_MASK (0x80U) +#define UART_IE7816_WTE_SHIFT (7U) +/*! WTE - Wait Timer Interrupt Enable + * 0b0..The assertion of IS7816[WT] does not result in the generation of an interrupt. + * 0b1..The assertion of IS7816[WT] results in the generation of an interrupt. + */ +#define UART_IE7816_WTE(x) (((uint8_t)(((uint8_t)(x)) << UART_IE7816_WTE_SHIFT)) & UART_IE7816_WTE_MASK) +/*! @} */ + +/*! @name IS7816 - UART 7816 Interrupt Status Register */ +/*! @{ */ +#define UART_IS7816_RXT_MASK (0x1U) +#define UART_IS7816_RXT_SHIFT (0U) +/*! RXT - Receive Threshold Exceeded Interrupt + * 0b0..The number of consecutive NACKS generated as a result of parity errors and buffer overruns is less than or equal to the value in ET7816[RXTHRESHOLD]. + * 0b1..The number of consecutive NACKS generated as a result of parity errors and buffer overruns is greater than the value in ET7816[RXTHRESHOLD]. + */ +#define UART_IS7816_RXT(x) (((uint8_t)(((uint8_t)(x)) << UART_IS7816_RXT_SHIFT)) & UART_IS7816_RXT_MASK) +#define UART_IS7816_TXT_MASK (0x2U) +#define UART_IS7816_TXT_SHIFT (1U) +/*! TXT - Transmit Threshold Exceeded Interrupt + * 0b0..The number of retries and corresponding NACKS does not exceed the value in ET7816[TXTHRESHOLD]. + * 0b1..The number of retries and corresponding NACKS exceeds the value in ET7816[TXTHRESHOLD]. + */ +#define UART_IS7816_TXT(x) (((uint8_t)(((uint8_t)(x)) << UART_IS7816_TXT_SHIFT)) & UART_IS7816_TXT_MASK) +#define UART_IS7816_GTV_MASK (0x4U) +#define UART_IS7816_GTV_SHIFT (2U) +/*! GTV - Guard Timer Violated Interrupt + * 0b0..A guard time (GT, CGT, or BGT) has not been violated. + * 0b1..A guard time (GT, CGT, or BGT) has been violated. + */ +#define UART_IS7816_GTV(x) (((uint8_t)(((uint8_t)(x)) << UART_IS7816_GTV_SHIFT)) & UART_IS7816_GTV_MASK) +#define UART_IS7816_INITD_MASK (0x10U) +#define UART_IS7816_INITD_SHIFT (4U) +/*! INITD - Initial Character Detected Interrupt + * 0b0..A valid initial character has not been received. + * 0b1..A valid initial character has been received. + */ +#define UART_IS7816_INITD(x) (((uint8_t)(((uint8_t)(x)) << UART_IS7816_INITD_SHIFT)) & UART_IS7816_INITD_MASK) +#define UART_IS7816_BWT_MASK (0x20U) +#define UART_IS7816_BWT_SHIFT (5U) +/*! BWT - Block Wait Timer Interrupt + * 0b0..Block wait time (BWT) has not been violated. + * 0b1..Block wait time (BWT) has been violated. + */ +#define UART_IS7816_BWT(x) (((uint8_t)(((uint8_t)(x)) << UART_IS7816_BWT_SHIFT)) & UART_IS7816_BWT_MASK) +#define UART_IS7816_CWT_MASK (0x40U) +#define UART_IS7816_CWT_SHIFT (6U) +/*! CWT - Character Wait Timer Interrupt + * 0b0..Character wait time (CWT) has not been violated. + * 0b1..Character wait time (CWT) has been violated. + */ +#define UART_IS7816_CWT(x) (((uint8_t)(((uint8_t)(x)) << UART_IS7816_CWT_SHIFT)) & UART_IS7816_CWT_MASK) +#define UART_IS7816_WT_MASK (0x80U) +#define UART_IS7816_WT_SHIFT (7U) +/*! WT - Wait Timer Interrupt + * 0b0..Wait time (WT) has not been violated. + * 0b1..Wait time (WT) has been violated. + */ +#define UART_IS7816_WT(x) (((uint8_t)(((uint8_t)(x)) << UART_IS7816_WT_SHIFT)) & UART_IS7816_WT_MASK) +/*! @} */ + +/*! @name WP7816T0 - UART 7816 Wait Parameter Register */ +/*! @{ */ +#define UART_WP7816T0_WI_MASK (0xFFU) +#define UART_WP7816T0_WI_SHIFT (0U) +#define UART_WP7816T0_WI(x) (((uint8_t)(((uint8_t)(x)) << UART_WP7816T0_WI_SHIFT)) & UART_WP7816T0_WI_MASK) +/*! @} */ + +/*! @name WP7816T1 - UART 7816 Wait Parameter Register */ +/*! @{ */ +#define UART_WP7816T1_BWI_MASK (0xFU) +#define UART_WP7816T1_BWI_SHIFT (0U) +#define UART_WP7816T1_BWI(x) (((uint8_t)(((uint8_t)(x)) << UART_WP7816T1_BWI_SHIFT)) & UART_WP7816T1_BWI_MASK) +#define UART_WP7816T1_CWI_MASK (0xF0U) +#define UART_WP7816T1_CWI_SHIFT (4U) +#define UART_WP7816T1_CWI(x) (((uint8_t)(((uint8_t)(x)) << UART_WP7816T1_CWI_SHIFT)) & UART_WP7816T1_CWI_MASK) +/*! @} */ + +/*! @name WN7816 - UART 7816 Wait N Register */ +/*! @{ */ +#define UART_WN7816_GTN_MASK (0xFFU) +#define UART_WN7816_GTN_SHIFT (0U) +#define UART_WN7816_GTN(x) (((uint8_t)(((uint8_t)(x)) << UART_WN7816_GTN_SHIFT)) & UART_WN7816_GTN_MASK) +/*! @} */ + +/*! @name WF7816 - UART 7816 Wait FD Register */ +/*! @{ */ +#define UART_WF7816_GTFD_MASK (0xFFU) +#define UART_WF7816_GTFD_SHIFT (0U) +#define UART_WF7816_GTFD(x) (((uint8_t)(((uint8_t)(x)) << UART_WF7816_GTFD_SHIFT)) & UART_WF7816_GTFD_MASK) +/*! @} */ + +/*! @name ET7816 - UART 7816 Error Threshold Register */ +/*! @{ */ +#define UART_ET7816_RXTHRESHOLD_MASK (0xFU) +#define UART_ET7816_RXTHRESHOLD_SHIFT (0U) +#define UART_ET7816_RXTHRESHOLD(x) (((uint8_t)(((uint8_t)(x)) << UART_ET7816_RXTHRESHOLD_SHIFT)) & UART_ET7816_RXTHRESHOLD_MASK) +#define UART_ET7816_TXTHRESHOLD_MASK (0xF0U) +#define UART_ET7816_TXTHRESHOLD_SHIFT (4U) +/*! TXTHRESHOLD - Transmit NACK Threshold + * 0b0000..TXT asserts on the first NACK that is received. + * 0b0001..TXT asserts on the second NACK that is received. + */ +#define UART_ET7816_TXTHRESHOLD(x) (((uint8_t)(((uint8_t)(x)) << UART_ET7816_TXTHRESHOLD_SHIFT)) & UART_ET7816_TXTHRESHOLD_MASK) +/*! @} */ + +/*! @name TL7816 - UART 7816 Transmit Length Register */ +/*! @{ */ +#define UART_TL7816_TLEN_MASK (0xFFU) +#define UART_TL7816_TLEN_SHIFT (0U) +#define UART_TL7816_TLEN(x) (((uint8_t)(((uint8_t)(x)) << UART_TL7816_TLEN_SHIFT)) & UART_TL7816_TLEN_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group UART_Register_Masks */ + + +/* UART - Peripheral instance base addresses */ +/** Peripheral UART0 base address */ +#define UART0_BASE (0x4006A000u) +/** Peripheral UART0 base pointer */ +#define UART0 ((UART_Type *)UART0_BASE) +/** Peripheral UART1 base address */ +#define UART1_BASE (0x4006B000u) +/** Peripheral UART1 base pointer */ +#define UART1 ((UART_Type *)UART1_BASE) +/** Peripheral UART2 base address */ +#define UART2_BASE (0x4006C000u) +/** Peripheral UART2 base pointer */ +#define UART2 ((UART_Type *)UART2_BASE) +/** Peripheral UART3 base address */ +#define UART3_BASE (0x4006D000u) +/** Peripheral UART3 base pointer */ +#define UART3 ((UART_Type *)UART3_BASE) +/** Peripheral UART4 base address */ +#define UART4_BASE (0x400EA000u) +/** Peripheral UART4 base pointer */ +#define UART4 ((UART_Type *)UART4_BASE) +/** Peripheral UART5 base address */ +#define UART5_BASE (0x400EB000u) +/** Peripheral UART5 base pointer */ +#define UART5 ((UART_Type *)UART5_BASE) +/** Array initializer of UART peripheral base addresses */ +#define UART_BASE_ADDRS { UART0_BASE, UART1_BASE, UART2_BASE, UART3_BASE, UART4_BASE, UART5_BASE } +/** Array initializer of UART peripheral base pointers */ +#define UART_BASE_PTRS { UART0, UART1, UART2, UART3, UART4, UART5 } +/** Interrupt vectors for the UART peripheral type */ +#define UART_RX_TX_IRQS { UART0_RX_TX_IRQn, UART1_RX_TX_IRQn, UART2_RX_TX_IRQn, UART3_RX_TX_IRQn, UART4_RX_TX_IRQn, UART5_RX_TX_IRQn } +#define UART_ERR_IRQS { UART0_ERR_IRQn, UART1_ERR_IRQn, UART2_ERR_IRQn, UART3_ERR_IRQn, UART4_ERR_IRQn, UART5_ERR_IRQn } +#define UART_LON_IRQS { UART0_LON_IRQn, NotAvail_IRQn, NotAvail_IRQn, NotAvail_IRQn, NotAvail_IRQn, NotAvail_IRQn } + +/*! + * @} + */ /* end of group UART_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- USB Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USB_Peripheral_Access_Layer USB Peripheral Access Layer + * @{ + */ + +/** USB - Register Layout Typedef */ +typedef struct { + __I uint8_t PERID; /**< Peripheral ID register, offset: 0x0 */ + uint8_t RESERVED_0[3]; + __I uint8_t IDCOMP; /**< Peripheral ID Complement register, offset: 0x4 */ + uint8_t RESERVED_1[3]; + __I uint8_t REV; /**< Peripheral Revision register, offset: 0x8 */ + uint8_t RESERVED_2[3]; + __I uint8_t ADDINFO; /**< Peripheral Additional Info register, offset: 0xC */ + uint8_t RESERVED_3[3]; + __IO uint8_t OTGISTAT; /**< OTG Interrupt Status register, offset: 0x10 */ + uint8_t RESERVED_4[3]; + __IO uint8_t OTGICR; /**< OTG Interrupt Control register, offset: 0x14 */ + uint8_t RESERVED_5[3]; + __IO uint8_t OTGSTAT; /**< OTG Status register, offset: 0x18 */ + uint8_t RESERVED_6[3]; + __IO uint8_t OTGCTL; /**< OTG Control register, offset: 0x1C */ + uint8_t RESERVED_7[99]; + __IO uint8_t ISTAT; /**< Interrupt Status register, offset: 0x80 */ + uint8_t RESERVED_8[3]; + __IO uint8_t INTEN; /**< Interrupt Enable register, offset: 0x84 */ + uint8_t RESERVED_9[3]; + __IO uint8_t ERRSTAT; /**< Error Interrupt Status register, offset: 0x88 */ + uint8_t RESERVED_10[3]; + __IO uint8_t ERREN; /**< Error Interrupt Enable register, offset: 0x8C */ + uint8_t RESERVED_11[3]; + __I uint8_t STAT; /**< Status register, offset: 0x90 */ + uint8_t RESERVED_12[3]; + __IO uint8_t CTL; /**< Control register, offset: 0x94 */ + uint8_t RESERVED_13[3]; + __IO uint8_t ADDR; /**< Address register, offset: 0x98 */ + uint8_t RESERVED_14[3]; + __IO uint8_t BDTPAGE1; /**< BDT Page register 1, offset: 0x9C */ + uint8_t RESERVED_15[3]; + __IO uint8_t FRMNUML; /**< Frame Number register Low, offset: 0xA0 */ + uint8_t RESERVED_16[3]; + __IO uint8_t FRMNUMH; /**< Frame Number register High, offset: 0xA4 */ + uint8_t RESERVED_17[3]; + __IO uint8_t TOKEN; /**< Token register, offset: 0xA8 */ + uint8_t RESERVED_18[3]; + __IO uint8_t SOFTHLD; /**< SOF Threshold register, offset: 0xAC */ + uint8_t RESERVED_19[3]; + __IO uint8_t BDTPAGE2; /**< BDT Page Register 2, offset: 0xB0 */ + uint8_t RESERVED_20[3]; + __IO uint8_t BDTPAGE3; /**< BDT Page Register 3, offset: 0xB4 */ + uint8_t RESERVED_21[11]; + struct { /* offset: 0xC0, array step: 0x4 */ + __IO uint8_t ENDPT; /**< Endpoint Control register, array offset: 0xC0, array step: 0x4 */ + uint8_t RESERVED_0[3]; + } ENDPOINT[16]; + __IO uint8_t USBCTRL; /**< USB Control register, offset: 0x100 */ + uint8_t RESERVED_22[3]; + __I uint8_t OBSERVE; /**< USB OTG Observe register, offset: 0x104 */ + uint8_t RESERVED_23[3]; + __IO uint8_t CONTROL; /**< USB OTG Control register, offset: 0x108 */ + uint8_t RESERVED_24[3]; + __IO uint8_t USBTRC0; /**< USB Transceiver Control register 0, offset: 0x10C */ + uint8_t RESERVED_25[7]; + __IO uint8_t USBFRMADJUST; /**< Frame Adjust Register, offset: 0x114 */ + uint8_t RESERVED_26[43]; + __IO uint8_t CLK_RECOVER_CTRL; /**< USB Clock recovery control, offset: 0x140 */ + uint8_t RESERVED_27[3]; + __IO uint8_t CLK_RECOVER_IRC_EN; /**< IRC48M oscillator enable register, offset: 0x144 */ + uint8_t RESERVED_28[23]; + __IO uint8_t CLK_RECOVER_INT_STATUS; /**< Clock recovery separated interrupt status, offset: 0x15C */ +} USB_Type; + +/* ---------------------------------------------------------------------------- + -- USB Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USB_Register_Masks USB Register Masks + * @{ + */ + +/*! @name PERID - Peripheral ID register */ +/*! @{ */ +#define USB_PERID_ID_MASK (0x3FU) +#define USB_PERID_ID_SHIFT (0U) +#define USB_PERID_ID(x) (((uint8_t)(((uint8_t)(x)) << USB_PERID_ID_SHIFT)) & USB_PERID_ID_MASK) +/*! @} */ + +/*! @name IDCOMP - Peripheral ID Complement register */ +/*! @{ */ +#define USB_IDCOMP_NID_MASK (0x3FU) +#define USB_IDCOMP_NID_SHIFT (0U) +#define USB_IDCOMP_NID(x) (((uint8_t)(((uint8_t)(x)) << USB_IDCOMP_NID_SHIFT)) & USB_IDCOMP_NID_MASK) +/*! @} */ + +/*! @name REV - Peripheral Revision register */ +/*! @{ */ +#define USB_REV_REV_MASK (0xFFU) +#define USB_REV_REV_SHIFT (0U) +#define USB_REV_REV(x) (((uint8_t)(((uint8_t)(x)) << USB_REV_REV_SHIFT)) & USB_REV_REV_MASK) +/*! @} */ + +/*! @name ADDINFO - Peripheral Additional Info register */ +/*! @{ */ +#define USB_ADDINFO_IEHOST_MASK (0x1U) +#define USB_ADDINFO_IEHOST_SHIFT (0U) +#define USB_ADDINFO_IEHOST(x) (((uint8_t)(((uint8_t)(x)) << USB_ADDINFO_IEHOST_SHIFT)) & USB_ADDINFO_IEHOST_MASK) +#define USB_ADDINFO_IRQNUM_MASK (0xF8U) +#define USB_ADDINFO_IRQNUM_SHIFT (3U) +#define USB_ADDINFO_IRQNUM(x) (((uint8_t)(((uint8_t)(x)) << USB_ADDINFO_IRQNUM_SHIFT)) & USB_ADDINFO_IRQNUM_MASK) +/*! @} */ + +/*! @name OTGISTAT - OTG Interrupt Status register */ +/*! @{ */ +#define USB_OTGISTAT_AVBUSCHG_MASK (0x1U) +#define USB_OTGISTAT_AVBUSCHG_SHIFT (0U) +#define USB_OTGISTAT_AVBUSCHG(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGISTAT_AVBUSCHG_SHIFT)) & USB_OTGISTAT_AVBUSCHG_MASK) +#define USB_OTGISTAT_B_SESS_CHG_MASK (0x4U) +#define USB_OTGISTAT_B_SESS_CHG_SHIFT (2U) +#define USB_OTGISTAT_B_SESS_CHG(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGISTAT_B_SESS_CHG_SHIFT)) & USB_OTGISTAT_B_SESS_CHG_MASK) +#define USB_OTGISTAT_SESSVLDCHG_MASK (0x8U) +#define USB_OTGISTAT_SESSVLDCHG_SHIFT (3U) +#define USB_OTGISTAT_SESSVLDCHG(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGISTAT_SESSVLDCHG_SHIFT)) & USB_OTGISTAT_SESSVLDCHG_MASK) +#define USB_OTGISTAT_LINE_STATE_CHG_MASK (0x20U) +#define USB_OTGISTAT_LINE_STATE_CHG_SHIFT (5U) +#define USB_OTGISTAT_LINE_STATE_CHG(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGISTAT_LINE_STATE_CHG_SHIFT)) & USB_OTGISTAT_LINE_STATE_CHG_MASK) +#define USB_OTGISTAT_ONEMSEC_MASK (0x40U) +#define USB_OTGISTAT_ONEMSEC_SHIFT (6U) +#define USB_OTGISTAT_ONEMSEC(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGISTAT_ONEMSEC_SHIFT)) & USB_OTGISTAT_ONEMSEC_MASK) +#define USB_OTGISTAT_IDCHG_MASK (0x80U) +#define USB_OTGISTAT_IDCHG_SHIFT (7U) +#define USB_OTGISTAT_IDCHG(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGISTAT_IDCHG_SHIFT)) & USB_OTGISTAT_IDCHG_MASK) +/*! @} */ + +/*! @name OTGICR - OTG Interrupt Control register */ +/*! @{ */ +#define USB_OTGICR_AVBUSEN_MASK (0x1U) +#define USB_OTGICR_AVBUSEN_SHIFT (0U) +/*! AVBUSEN - A VBUS Valid Interrupt Enable + * 0b0..Disables the AVBUSCHG interrupt. + * 0b1..Enables the AVBUSCHG interrupt. + */ +#define USB_OTGICR_AVBUSEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGICR_AVBUSEN_SHIFT)) & USB_OTGICR_AVBUSEN_MASK) +#define USB_OTGICR_BSESSEN_MASK (0x4U) +#define USB_OTGICR_BSESSEN_SHIFT (2U) +/*! BSESSEN - B Session END Interrupt Enable + * 0b0..Disables the B_SESS_CHG interrupt. + * 0b1..Enables the B_SESS_CHG interrupt. + */ +#define USB_OTGICR_BSESSEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGICR_BSESSEN_SHIFT)) & USB_OTGICR_BSESSEN_MASK) +#define USB_OTGICR_SESSVLDEN_MASK (0x8U) +#define USB_OTGICR_SESSVLDEN_SHIFT (3U) +/*! SESSVLDEN - Session Valid Interrupt Enable + * 0b0..Disables the SESSVLDCHG interrupt. + * 0b1..Enables the SESSVLDCHG interrupt. + */ +#define USB_OTGICR_SESSVLDEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGICR_SESSVLDEN_SHIFT)) & USB_OTGICR_SESSVLDEN_MASK) +#define USB_OTGICR_LINESTATEEN_MASK (0x20U) +#define USB_OTGICR_LINESTATEEN_SHIFT (5U) +/*! LINESTATEEN - Line State Change Interrupt Enable + * 0b0..Disables the LINE_STAT_CHG interrupt. + * 0b1..Enables the LINE_STAT_CHG interrupt. + */ +#define USB_OTGICR_LINESTATEEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGICR_LINESTATEEN_SHIFT)) & USB_OTGICR_LINESTATEEN_MASK) +#define USB_OTGICR_ONEMSECEN_MASK (0x40U) +#define USB_OTGICR_ONEMSECEN_SHIFT (6U) +/*! ONEMSECEN - One Millisecond Interrupt Enable + * 0b0..Diables the 1ms timer interrupt. + * 0b1..Enables the 1ms timer interrupt. + */ +#define USB_OTGICR_ONEMSECEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGICR_ONEMSECEN_SHIFT)) & USB_OTGICR_ONEMSECEN_MASK) +#define USB_OTGICR_IDEN_MASK (0x80U) +#define USB_OTGICR_IDEN_SHIFT (7U) +/*! IDEN - ID Interrupt Enable + * 0b0..The ID interrupt is disabled + * 0b1..The ID interrupt is enabled + */ +#define USB_OTGICR_IDEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGICR_IDEN_SHIFT)) & USB_OTGICR_IDEN_MASK) +/*! @} */ + +/*! @name OTGSTAT - OTG Status register */ +/*! @{ */ +#define USB_OTGSTAT_AVBUSVLD_MASK (0x1U) +#define USB_OTGSTAT_AVBUSVLD_SHIFT (0U) +/*! AVBUSVLD - A VBUS Valid + * 0b0..The VBUS voltage is below the A VBUS Valid threshold. + * 0b1..The VBUS voltage is above the A VBUS Valid threshold. + */ +#define USB_OTGSTAT_AVBUSVLD(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGSTAT_AVBUSVLD_SHIFT)) & USB_OTGSTAT_AVBUSVLD_MASK) +#define USB_OTGSTAT_BSESSEND_MASK (0x4U) +#define USB_OTGSTAT_BSESSEND_SHIFT (2U) +/*! BSESSEND - B Session End + * 0b0..The VBUS voltage is above the B session end threshold. + * 0b1..The VBUS voltage is below the B session end threshold. + */ +#define USB_OTGSTAT_BSESSEND(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGSTAT_BSESSEND_SHIFT)) & USB_OTGSTAT_BSESSEND_MASK) +#define USB_OTGSTAT_SESS_VLD_MASK (0x8U) +#define USB_OTGSTAT_SESS_VLD_SHIFT (3U) +/*! SESS_VLD - Session Valid + * 0b0..The VBUS voltage is below the B session valid threshold + * 0b1..The VBUS voltage is above the B session valid threshold. + */ +#define USB_OTGSTAT_SESS_VLD(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGSTAT_SESS_VLD_SHIFT)) & USB_OTGSTAT_SESS_VLD_MASK) +#define USB_OTGSTAT_LINESTATESTABLE_MASK (0x20U) +#define USB_OTGSTAT_LINESTATESTABLE_SHIFT (5U) +/*! LINESTATESTABLE + * 0b0..The LINE_STAT_CHG bit is not yet stable. + * 0b1..The LINE_STAT_CHG bit has been debounced and is stable. + */ +#define USB_OTGSTAT_LINESTATESTABLE(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGSTAT_LINESTATESTABLE_SHIFT)) & USB_OTGSTAT_LINESTATESTABLE_MASK) +#define USB_OTGSTAT_ONEMSECEN_MASK (0x40U) +#define USB_OTGSTAT_ONEMSECEN_SHIFT (6U) +#define USB_OTGSTAT_ONEMSECEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGSTAT_ONEMSECEN_SHIFT)) & USB_OTGSTAT_ONEMSECEN_MASK) +#define USB_OTGSTAT_ID_MASK (0x80U) +#define USB_OTGSTAT_ID_SHIFT (7U) +/*! ID + * 0b0..Indicates a Type A cable is plugged into the USB connector. + * 0b1..Indicates no cable is attached or a Type B cable is plugged into the USB connector. + */ +#define USB_OTGSTAT_ID(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGSTAT_ID_SHIFT)) & USB_OTGSTAT_ID_MASK) +/*! @} */ + +/*! @name OTGCTL - OTG Control register */ +/*! @{ */ +#define USB_OTGCTL_OTGEN_MASK (0x4U) +#define USB_OTGCTL_OTGEN_SHIFT (2U) +/*! OTGEN - On-The-Go pullup/pulldown resistor enable + * 0b0..If USB_EN is 1 and HOST_MODE is 0 in the Control Register (CTL), then the D+ Data Line pull-up resistors are enabled. If HOST_MODE is 1 the D+ and D- Data Line pull-down resistors are engaged. + * 0b1..The pull-up and pull-down controls in this register are used. + */ +#define USB_OTGCTL_OTGEN(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGCTL_OTGEN_SHIFT)) & USB_OTGCTL_OTGEN_MASK) +#define USB_OTGCTL_DMLOW_MASK (0x10U) +#define USB_OTGCTL_DMLOW_SHIFT (4U) +/*! DMLOW - D- Data Line pull-down resistor enable + * 0b0..D- pulldown resistor is not enabled. + * 0b1..D- pulldown resistor is enabled. + */ +#define USB_OTGCTL_DMLOW(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGCTL_DMLOW_SHIFT)) & USB_OTGCTL_DMLOW_MASK) +#define USB_OTGCTL_DPLOW_MASK (0x20U) +#define USB_OTGCTL_DPLOW_SHIFT (5U) +/*! DPLOW - D+ Data Line pull-down resistor enable + * 0b0..D+ pulldown resistor is not enabled. + * 0b1..D+ pulldown resistor is enabled. + */ +#define USB_OTGCTL_DPLOW(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGCTL_DPLOW_SHIFT)) & USB_OTGCTL_DPLOW_MASK) +#define USB_OTGCTL_DPHIGH_MASK (0x80U) +#define USB_OTGCTL_DPHIGH_SHIFT (7U) +/*! DPHIGH - D+ Data Line pullup resistor enable + * 0b0..D+ pullup resistor is not enabled + * 0b1..D+ pullup resistor is enabled + */ +#define USB_OTGCTL_DPHIGH(x) (((uint8_t)(((uint8_t)(x)) << USB_OTGCTL_DPHIGH_SHIFT)) & USB_OTGCTL_DPHIGH_MASK) +/*! @} */ + +/*! @name ISTAT - Interrupt Status register */ +/*! @{ */ +#define USB_ISTAT_USBRST_MASK (0x1U) +#define USB_ISTAT_USBRST_SHIFT (0U) +#define USB_ISTAT_USBRST(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_USBRST_SHIFT)) & USB_ISTAT_USBRST_MASK) +#define USB_ISTAT_ERROR_MASK (0x2U) +#define USB_ISTAT_ERROR_SHIFT (1U) +#define USB_ISTAT_ERROR(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_ERROR_SHIFT)) & USB_ISTAT_ERROR_MASK) +#define USB_ISTAT_SOFTOK_MASK (0x4U) +#define USB_ISTAT_SOFTOK_SHIFT (2U) +#define USB_ISTAT_SOFTOK(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_SOFTOK_SHIFT)) & USB_ISTAT_SOFTOK_MASK) +#define USB_ISTAT_TOKDNE_MASK (0x8U) +#define USB_ISTAT_TOKDNE_SHIFT (3U) +#define USB_ISTAT_TOKDNE(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_TOKDNE_SHIFT)) & USB_ISTAT_TOKDNE_MASK) +#define USB_ISTAT_SLEEP_MASK (0x10U) +#define USB_ISTAT_SLEEP_SHIFT (4U) +#define USB_ISTAT_SLEEP(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_SLEEP_SHIFT)) & USB_ISTAT_SLEEP_MASK) +#define USB_ISTAT_RESUME_MASK (0x20U) +#define USB_ISTAT_RESUME_SHIFT (5U) +#define USB_ISTAT_RESUME(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_RESUME_SHIFT)) & USB_ISTAT_RESUME_MASK) +#define USB_ISTAT_ATTACH_MASK (0x40U) +#define USB_ISTAT_ATTACH_SHIFT (6U) +#define USB_ISTAT_ATTACH(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_ATTACH_SHIFT)) & USB_ISTAT_ATTACH_MASK) +#define USB_ISTAT_STALL_MASK (0x80U) +#define USB_ISTAT_STALL_SHIFT (7U) +#define USB_ISTAT_STALL(x) (((uint8_t)(((uint8_t)(x)) << USB_ISTAT_STALL_SHIFT)) & USB_ISTAT_STALL_MASK) +/*! @} */ + +/*! @name INTEN - Interrupt Enable register */ +/*! @{ */ +#define USB_INTEN_USBRSTEN_MASK (0x1U) +#define USB_INTEN_USBRSTEN_SHIFT (0U) +/*! USBRSTEN - USBRST Interrupt Enable + * 0b0..Disables the USBRST interrupt. + * 0b1..Enables the USBRST interrupt. + */ +#define USB_INTEN_USBRSTEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_USBRSTEN_SHIFT)) & USB_INTEN_USBRSTEN_MASK) +#define USB_INTEN_ERROREN_MASK (0x2U) +#define USB_INTEN_ERROREN_SHIFT (1U) +/*! ERROREN - ERROR Interrupt Enable + * 0b0..Disables the ERROR interrupt. + * 0b1..Enables the ERROR interrupt. + */ +#define USB_INTEN_ERROREN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_ERROREN_SHIFT)) & USB_INTEN_ERROREN_MASK) +#define USB_INTEN_SOFTOKEN_MASK (0x4U) +#define USB_INTEN_SOFTOKEN_SHIFT (2U) +/*! SOFTOKEN - SOFTOK Interrupt Enable + * 0b0..Disbles the SOFTOK interrupt. + * 0b1..Enables the SOFTOK interrupt. + */ +#define USB_INTEN_SOFTOKEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_SOFTOKEN_SHIFT)) & USB_INTEN_SOFTOKEN_MASK) +#define USB_INTEN_TOKDNEEN_MASK (0x8U) +#define USB_INTEN_TOKDNEEN_SHIFT (3U) +/*! TOKDNEEN - TOKDNE Interrupt Enable + * 0b0..Disables the TOKDNE interrupt. + * 0b1..Enables the TOKDNE interrupt. + */ +#define USB_INTEN_TOKDNEEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_TOKDNEEN_SHIFT)) & USB_INTEN_TOKDNEEN_MASK) +#define USB_INTEN_SLEEPEN_MASK (0x10U) +#define USB_INTEN_SLEEPEN_SHIFT (4U) +/*! SLEEPEN - SLEEP Interrupt Enable + * 0b0..Disables the SLEEP interrupt. + * 0b1..Enables the SLEEP interrupt. + */ +#define USB_INTEN_SLEEPEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_SLEEPEN_SHIFT)) & USB_INTEN_SLEEPEN_MASK) +#define USB_INTEN_RESUMEEN_MASK (0x20U) +#define USB_INTEN_RESUMEEN_SHIFT (5U) +/*! RESUMEEN - RESUME Interrupt Enable + * 0b0..Disables the RESUME interrupt. + * 0b1..Enables the RESUME interrupt. + */ +#define USB_INTEN_RESUMEEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_RESUMEEN_SHIFT)) & USB_INTEN_RESUMEEN_MASK) +#define USB_INTEN_ATTACHEN_MASK (0x40U) +#define USB_INTEN_ATTACHEN_SHIFT (6U) +/*! ATTACHEN - ATTACH Interrupt Enable + * 0b0..Disables the ATTACH interrupt. + * 0b1..Enables the ATTACH interrupt. + */ +#define USB_INTEN_ATTACHEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_ATTACHEN_SHIFT)) & USB_INTEN_ATTACHEN_MASK) +#define USB_INTEN_STALLEN_MASK (0x80U) +#define USB_INTEN_STALLEN_SHIFT (7U) +/*! STALLEN - STALL Interrupt Enable + * 0b0..Diasbles the STALL interrupt. + * 0b1..Enables the STALL interrupt. + */ +#define USB_INTEN_STALLEN(x) (((uint8_t)(((uint8_t)(x)) << USB_INTEN_STALLEN_SHIFT)) & USB_INTEN_STALLEN_MASK) +/*! @} */ + +/*! @name ERRSTAT - Error Interrupt Status register */ +/*! @{ */ +#define USB_ERRSTAT_PIDERR_MASK (0x1U) +#define USB_ERRSTAT_PIDERR_SHIFT (0U) +#define USB_ERRSTAT_PIDERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_PIDERR_SHIFT)) & USB_ERRSTAT_PIDERR_MASK) +#define USB_ERRSTAT_CRC5EOF_MASK (0x2U) +#define USB_ERRSTAT_CRC5EOF_SHIFT (1U) +#define USB_ERRSTAT_CRC5EOF(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_CRC5EOF_SHIFT)) & USB_ERRSTAT_CRC5EOF_MASK) +#define USB_ERRSTAT_CRC16_MASK (0x4U) +#define USB_ERRSTAT_CRC16_SHIFT (2U) +#define USB_ERRSTAT_CRC16(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_CRC16_SHIFT)) & USB_ERRSTAT_CRC16_MASK) +#define USB_ERRSTAT_DFN8_MASK (0x8U) +#define USB_ERRSTAT_DFN8_SHIFT (3U) +#define USB_ERRSTAT_DFN8(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_DFN8_SHIFT)) & USB_ERRSTAT_DFN8_MASK) +#define USB_ERRSTAT_BTOERR_MASK (0x10U) +#define USB_ERRSTAT_BTOERR_SHIFT (4U) +#define USB_ERRSTAT_BTOERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_BTOERR_SHIFT)) & USB_ERRSTAT_BTOERR_MASK) +#define USB_ERRSTAT_DMAERR_MASK (0x20U) +#define USB_ERRSTAT_DMAERR_SHIFT (5U) +#define USB_ERRSTAT_DMAERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_DMAERR_SHIFT)) & USB_ERRSTAT_DMAERR_MASK) +#define USB_ERRSTAT_BTSERR_MASK (0x80U) +#define USB_ERRSTAT_BTSERR_SHIFT (7U) +#define USB_ERRSTAT_BTSERR(x) (((uint8_t)(((uint8_t)(x)) << USB_ERRSTAT_BTSERR_SHIFT)) & USB_ERRSTAT_BTSERR_MASK) +/*! @} */ + +/*! @name ERREN - Error Interrupt Enable register */ +/*! @{ */ +#define USB_ERREN_PIDERREN_MASK (0x1U) +#define USB_ERREN_PIDERREN_SHIFT (0U) +/*! PIDERREN - PIDERR Interrupt Enable + * 0b0..Disables the PIDERR interrupt. + * 0b1..Enters the PIDERR interrupt. + */ +#define USB_ERREN_PIDERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_PIDERREN_SHIFT)) & USB_ERREN_PIDERREN_MASK) +#define USB_ERREN_CRC5EOFEN_MASK (0x2U) +#define USB_ERREN_CRC5EOFEN_SHIFT (1U) +/*! CRC5EOFEN - CRC5/EOF Interrupt Enable + * 0b0..Disables the CRC5/EOF interrupt. + * 0b1..Enables the CRC5/EOF interrupt. + */ +#define USB_ERREN_CRC5EOFEN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_CRC5EOFEN_SHIFT)) & USB_ERREN_CRC5EOFEN_MASK) +#define USB_ERREN_CRC16EN_MASK (0x4U) +#define USB_ERREN_CRC16EN_SHIFT (2U) +/*! CRC16EN - CRC16 Interrupt Enable + * 0b0..Disables the CRC16 interrupt. + * 0b1..Enables the CRC16 interrupt. + */ +#define USB_ERREN_CRC16EN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_CRC16EN_SHIFT)) & USB_ERREN_CRC16EN_MASK) +#define USB_ERREN_DFN8EN_MASK (0x8U) +#define USB_ERREN_DFN8EN_SHIFT (3U) +/*! DFN8EN - DFN8 Interrupt Enable + * 0b0..Disables the DFN8 interrupt. + * 0b1..Enables the DFN8 interrupt. + */ +#define USB_ERREN_DFN8EN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_DFN8EN_SHIFT)) & USB_ERREN_DFN8EN_MASK) +#define USB_ERREN_BTOERREN_MASK (0x10U) +#define USB_ERREN_BTOERREN_SHIFT (4U) +/*! BTOERREN - BTOERR Interrupt Enable + * 0b0..Disables the BTOERR interrupt. + * 0b1..Enables the BTOERR interrupt. + */ +#define USB_ERREN_BTOERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_BTOERREN_SHIFT)) & USB_ERREN_BTOERREN_MASK) +#define USB_ERREN_DMAERREN_MASK (0x20U) +#define USB_ERREN_DMAERREN_SHIFT (5U) +/*! DMAERREN - DMAERR Interrupt Enable + * 0b0..Disables the DMAERR interrupt. + * 0b1..Enables the DMAERR interrupt. + */ +#define USB_ERREN_DMAERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_DMAERREN_SHIFT)) & USB_ERREN_DMAERREN_MASK) +#define USB_ERREN_BTSERREN_MASK (0x80U) +#define USB_ERREN_BTSERREN_SHIFT (7U) +/*! BTSERREN - BTSERR Interrupt Enable + * 0b0..Disables the BTSERR interrupt. + * 0b1..Enables the BTSERR interrupt. + */ +#define USB_ERREN_BTSERREN(x) (((uint8_t)(((uint8_t)(x)) << USB_ERREN_BTSERREN_SHIFT)) & USB_ERREN_BTSERREN_MASK) +/*! @} */ + +/*! @name STAT - Status register */ +/*! @{ */ +#define USB_STAT_ODD_MASK (0x4U) +#define USB_STAT_ODD_SHIFT (2U) +#define USB_STAT_ODD(x) (((uint8_t)(((uint8_t)(x)) << USB_STAT_ODD_SHIFT)) & USB_STAT_ODD_MASK) +#define USB_STAT_TX_MASK (0x8U) +#define USB_STAT_TX_SHIFT (3U) +/*! TX - Transmit Indicator + * 0b0..The most recent transaction was a receive operation. + * 0b1..The most recent transaction was a transmit operation. + */ +#define USB_STAT_TX(x) (((uint8_t)(((uint8_t)(x)) << USB_STAT_TX_SHIFT)) & USB_STAT_TX_MASK) +#define USB_STAT_ENDP_MASK (0xF0U) +#define USB_STAT_ENDP_SHIFT (4U) +#define USB_STAT_ENDP(x) (((uint8_t)(((uint8_t)(x)) << USB_STAT_ENDP_SHIFT)) & USB_STAT_ENDP_MASK) +/*! @} */ + +/*! @name CTL - Control register */ +/*! @{ */ +#define USB_CTL_USBENSOFEN_MASK (0x1U) +#define USB_CTL_USBENSOFEN_SHIFT (0U) +/*! USBENSOFEN - USB Enable + * 0b0..Disables the USB Module. + * 0b1..Enables the USB Module. + */ +#define USB_CTL_USBENSOFEN(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_USBENSOFEN_SHIFT)) & USB_CTL_USBENSOFEN_MASK) +#define USB_CTL_ODDRST_MASK (0x2U) +#define USB_CTL_ODDRST_SHIFT (1U) +#define USB_CTL_ODDRST(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_ODDRST_SHIFT)) & USB_CTL_ODDRST_MASK) +#define USB_CTL_RESUME_MASK (0x4U) +#define USB_CTL_RESUME_SHIFT (2U) +#define USB_CTL_RESUME(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_RESUME_SHIFT)) & USB_CTL_RESUME_MASK) +#define USB_CTL_HOSTMODEEN_MASK (0x8U) +#define USB_CTL_HOSTMODEEN_SHIFT (3U) +#define USB_CTL_HOSTMODEEN(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_HOSTMODEEN_SHIFT)) & USB_CTL_HOSTMODEEN_MASK) +#define USB_CTL_RESET_MASK (0x10U) +#define USB_CTL_RESET_SHIFT (4U) +#define USB_CTL_RESET(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_RESET_SHIFT)) & USB_CTL_RESET_MASK) +#define USB_CTL_TXSUSPENDTOKENBUSY_MASK (0x20U) +#define USB_CTL_TXSUSPENDTOKENBUSY_SHIFT (5U) +#define USB_CTL_TXSUSPENDTOKENBUSY(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_TXSUSPENDTOKENBUSY_SHIFT)) & USB_CTL_TXSUSPENDTOKENBUSY_MASK) +#define USB_CTL_SE0_MASK (0x40U) +#define USB_CTL_SE0_SHIFT (6U) +#define USB_CTL_SE0(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_SE0_SHIFT)) & USB_CTL_SE0_MASK) +#define USB_CTL_JSTATE_MASK (0x80U) +#define USB_CTL_JSTATE_SHIFT (7U) +#define USB_CTL_JSTATE(x) (((uint8_t)(((uint8_t)(x)) << USB_CTL_JSTATE_SHIFT)) & USB_CTL_JSTATE_MASK) +/*! @} */ + +/*! @name ADDR - Address register */ +/*! @{ */ +#define USB_ADDR_ADDR_MASK (0x7FU) +#define USB_ADDR_ADDR_SHIFT (0U) +#define USB_ADDR_ADDR(x) (((uint8_t)(((uint8_t)(x)) << USB_ADDR_ADDR_SHIFT)) & USB_ADDR_ADDR_MASK) +#define USB_ADDR_LSEN_MASK (0x80U) +#define USB_ADDR_LSEN_SHIFT (7U) +#define USB_ADDR_LSEN(x) (((uint8_t)(((uint8_t)(x)) << USB_ADDR_LSEN_SHIFT)) & USB_ADDR_LSEN_MASK) +/*! @} */ + +/*! @name BDTPAGE1 - BDT Page register 1 */ +/*! @{ */ +#define USB_BDTPAGE1_BDTBA_MASK (0xFEU) +#define USB_BDTPAGE1_BDTBA_SHIFT (1U) +#define USB_BDTPAGE1_BDTBA(x) (((uint8_t)(((uint8_t)(x)) << USB_BDTPAGE1_BDTBA_SHIFT)) & USB_BDTPAGE1_BDTBA_MASK) +/*! @} */ + +/*! @name FRMNUML - Frame Number register Low */ +/*! @{ */ +#define USB_FRMNUML_FRM_MASK (0xFFU) +#define USB_FRMNUML_FRM_SHIFT (0U) +#define USB_FRMNUML_FRM(x) (((uint8_t)(((uint8_t)(x)) << USB_FRMNUML_FRM_SHIFT)) & USB_FRMNUML_FRM_MASK) +/*! @} */ + +/*! @name FRMNUMH - Frame Number register High */ +/*! @{ */ +#define USB_FRMNUMH_FRM_MASK (0x7U) +#define USB_FRMNUMH_FRM_SHIFT (0U) +#define USB_FRMNUMH_FRM(x) (((uint8_t)(((uint8_t)(x)) << USB_FRMNUMH_FRM_SHIFT)) & USB_FRMNUMH_FRM_MASK) +/*! @} */ + +/*! @name TOKEN - Token register */ +/*! @{ */ +#define USB_TOKEN_TOKENENDPT_MASK (0xFU) +#define USB_TOKEN_TOKENENDPT_SHIFT (0U) +#define USB_TOKEN_TOKENENDPT(x) (((uint8_t)(((uint8_t)(x)) << USB_TOKEN_TOKENENDPT_SHIFT)) & USB_TOKEN_TOKENENDPT_MASK) +#define USB_TOKEN_TOKENPID_MASK (0xF0U) +#define USB_TOKEN_TOKENPID_SHIFT (4U) +/*! TOKENPID + * 0b0001..OUT Token. USB Module performs an OUT (TX) transaction. + * 0b1001..IN Token. USB Module performs an In (RX) transaction. + * 0b1101..SETUP Token. USB Module performs a SETUP (TX) transaction + */ +#define USB_TOKEN_TOKENPID(x) (((uint8_t)(((uint8_t)(x)) << USB_TOKEN_TOKENPID_SHIFT)) & USB_TOKEN_TOKENPID_MASK) +/*! @} */ + +/*! @name SOFTHLD - SOF Threshold register */ +/*! @{ */ +#define USB_SOFTHLD_CNT_MASK (0xFFU) +#define USB_SOFTHLD_CNT_SHIFT (0U) +#define USB_SOFTHLD_CNT(x) (((uint8_t)(((uint8_t)(x)) << USB_SOFTHLD_CNT_SHIFT)) & USB_SOFTHLD_CNT_MASK) +/*! @} */ + +/*! @name BDTPAGE2 - BDT Page Register 2 */ +/*! @{ */ +#define USB_BDTPAGE2_BDTBA_MASK (0xFFU) +#define USB_BDTPAGE2_BDTBA_SHIFT (0U) +#define USB_BDTPAGE2_BDTBA(x) (((uint8_t)(((uint8_t)(x)) << USB_BDTPAGE2_BDTBA_SHIFT)) & USB_BDTPAGE2_BDTBA_MASK) +/*! @} */ + +/*! @name BDTPAGE3 - BDT Page Register 3 */ +/*! @{ */ +#define USB_BDTPAGE3_BDTBA_MASK (0xFFU) +#define USB_BDTPAGE3_BDTBA_SHIFT (0U) +#define USB_BDTPAGE3_BDTBA(x) (((uint8_t)(((uint8_t)(x)) << USB_BDTPAGE3_BDTBA_SHIFT)) & USB_BDTPAGE3_BDTBA_MASK) +/*! @} */ + +/*! @name ENDPT - Endpoint Control register */ +/*! @{ */ +#define USB_ENDPT_EPHSHK_MASK (0x1U) +#define USB_ENDPT_EPHSHK_SHIFT (0U) +#define USB_ENDPT_EPHSHK(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPHSHK_SHIFT)) & USB_ENDPT_EPHSHK_MASK) +#define USB_ENDPT_EPSTALL_MASK (0x2U) +#define USB_ENDPT_EPSTALL_SHIFT (1U) +#define USB_ENDPT_EPSTALL(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPSTALL_SHIFT)) & USB_ENDPT_EPSTALL_MASK) +#define USB_ENDPT_EPTXEN_MASK (0x4U) +#define USB_ENDPT_EPTXEN_SHIFT (2U) +#define USB_ENDPT_EPTXEN(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPTXEN_SHIFT)) & USB_ENDPT_EPTXEN_MASK) +#define USB_ENDPT_EPRXEN_MASK (0x8U) +#define USB_ENDPT_EPRXEN_SHIFT (3U) +#define USB_ENDPT_EPRXEN(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPRXEN_SHIFT)) & USB_ENDPT_EPRXEN_MASK) +#define USB_ENDPT_EPCTLDIS_MASK (0x10U) +#define USB_ENDPT_EPCTLDIS_SHIFT (4U) +#define USB_ENDPT_EPCTLDIS(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_EPCTLDIS_SHIFT)) & USB_ENDPT_EPCTLDIS_MASK) +#define USB_ENDPT_RETRYDIS_MASK (0x40U) +#define USB_ENDPT_RETRYDIS_SHIFT (6U) +#define USB_ENDPT_RETRYDIS(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_RETRYDIS_SHIFT)) & USB_ENDPT_RETRYDIS_MASK) +#define USB_ENDPT_HOSTWOHUB_MASK (0x80U) +#define USB_ENDPT_HOSTWOHUB_SHIFT (7U) +#define USB_ENDPT_HOSTWOHUB(x) (((uint8_t)(((uint8_t)(x)) << USB_ENDPT_HOSTWOHUB_SHIFT)) & USB_ENDPT_HOSTWOHUB_MASK) +/*! @} */ + +/* The count of USB_ENDPT */ +#define USB_ENDPT_COUNT (16U) + +/*! @name USBCTRL - USB Control register */ +/*! @{ */ +#define USB_USBCTRL_PDE_MASK (0x40U) +#define USB_USBCTRL_PDE_SHIFT (6U) +/*! PDE + * 0b0..Weak pulldowns are disabled on D+ and D-. + * 0b1..Weak pulldowns are enabled on D+ and D-. + */ +#define USB_USBCTRL_PDE(x) (((uint8_t)(((uint8_t)(x)) << USB_USBCTRL_PDE_SHIFT)) & USB_USBCTRL_PDE_MASK) +#define USB_USBCTRL_SUSP_MASK (0x80U) +#define USB_USBCTRL_SUSP_SHIFT (7U) +/*! SUSP + * 0b0..USB transceiver is not in suspend state. + * 0b1..USB transceiver is in suspend state. + */ +#define USB_USBCTRL_SUSP(x) (((uint8_t)(((uint8_t)(x)) << USB_USBCTRL_SUSP_SHIFT)) & USB_USBCTRL_SUSP_MASK) +/*! @} */ + +/*! @name OBSERVE - USB OTG Observe register */ +/*! @{ */ +#define USB_OBSERVE_DMPD_MASK (0x10U) +#define USB_OBSERVE_DMPD_SHIFT (4U) +/*! DMPD + * 0b0..D- pulldown disabled. + * 0b1..D- pulldown enabled. + */ +#define USB_OBSERVE_DMPD(x) (((uint8_t)(((uint8_t)(x)) << USB_OBSERVE_DMPD_SHIFT)) & USB_OBSERVE_DMPD_MASK) +#define USB_OBSERVE_DPPD_MASK (0x40U) +#define USB_OBSERVE_DPPD_SHIFT (6U) +/*! DPPD + * 0b0..D+ pulldown disabled. + * 0b1..D+ pulldown enabled. + */ +#define USB_OBSERVE_DPPD(x) (((uint8_t)(((uint8_t)(x)) << USB_OBSERVE_DPPD_SHIFT)) & USB_OBSERVE_DPPD_MASK) +#define USB_OBSERVE_DPPU_MASK (0x80U) +#define USB_OBSERVE_DPPU_SHIFT (7U) +/*! DPPU + * 0b0..D+ pullup disabled. + * 0b1..D+ pullup enabled. + */ +#define USB_OBSERVE_DPPU(x) (((uint8_t)(((uint8_t)(x)) << USB_OBSERVE_DPPU_SHIFT)) & USB_OBSERVE_DPPU_MASK) +/*! @} */ + +/*! @name CONTROL - USB OTG Control register */ +/*! @{ */ +#define USB_CONTROL_DPPULLUPNONOTG_MASK (0x10U) +#define USB_CONTROL_DPPULLUPNONOTG_SHIFT (4U) +/*! DPPULLUPNONOTG + * 0b0..DP Pullup in non-OTG device mode is not enabled. + * 0b1..DP Pullup in non-OTG device mode is enabled. + */ +#define USB_CONTROL_DPPULLUPNONOTG(x) (((uint8_t)(((uint8_t)(x)) << USB_CONTROL_DPPULLUPNONOTG_SHIFT)) & USB_CONTROL_DPPULLUPNONOTG_MASK) +/*! @} */ + +/*! @name USBTRC0 - USB Transceiver Control register 0 */ +/*! @{ */ +#define USB_USBTRC0_USB_RESUME_INT_MASK (0x1U) +#define USB_USBTRC0_USB_RESUME_INT_SHIFT (0U) +/*! USB_RESUME_INT - USB Asynchronous Interrupt + * 0b0..No interrupt was generated. + * 0b1..Interrupt was generated because of the USB asynchronous interrupt. + */ +#define USB_USBTRC0_USB_RESUME_INT(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_USB_RESUME_INT_SHIFT)) & USB_USBTRC0_USB_RESUME_INT_MASK) +#define USB_USBTRC0_SYNC_DET_MASK (0x2U) +#define USB_USBTRC0_SYNC_DET_SHIFT (1U) +/*! SYNC_DET - Synchronous USB Interrupt Detect + * 0b0..Synchronous interrupt has not been detected. + * 0b1..Synchronous interrupt has been detected. + */ +#define USB_USBTRC0_SYNC_DET(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_SYNC_DET_SHIFT)) & USB_USBTRC0_SYNC_DET_MASK) +#define USB_USBTRC0_USB_CLK_RECOVERY_INT_MASK (0x4U) +#define USB_USBTRC0_USB_CLK_RECOVERY_INT_SHIFT (2U) +#define USB_USBTRC0_USB_CLK_RECOVERY_INT(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_USB_CLK_RECOVERY_INT_SHIFT)) & USB_USBTRC0_USB_CLK_RECOVERY_INT_MASK) +#define USB_USBTRC0_USBRESMEN_MASK (0x20U) +#define USB_USBTRC0_USBRESMEN_SHIFT (5U) +/*! USBRESMEN - Asynchronous Resume Interrupt Enable + * 0b0..USB asynchronous wakeup from suspend mode disabled. + * 0b1..USB asynchronous wakeup from suspend mode enabled. The asynchronous resume interrupt differs from the synchronous resume interrupt in that it asynchronously detects K-state using the unfiltered state of the D+ and D- pins. This interrupt should only be enabled when the Transceiver is suspended. + */ +#define USB_USBTRC0_USBRESMEN(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_USBRESMEN_SHIFT)) & USB_USBTRC0_USBRESMEN_MASK) +#define USB_USBTRC0_USBRESET_MASK (0x80U) +#define USB_USBTRC0_USBRESET_SHIFT (7U) +/*! USBRESET - USB Reset + * 0b0..Normal USB module operation. + * 0b1..Returns the USB module to its reset state. + */ +#define USB_USBTRC0_USBRESET(x) (((uint8_t)(((uint8_t)(x)) << USB_USBTRC0_USBRESET_SHIFT)) & USB_USBTRC0_USBRESET_MASK) +/*! @} */ + +/*! @name USBFRMADJUST - Frame Adjust Register */ +/*! @{ */ +#define USB_USBFRMADJUST_ADJ_MASK (0xFFU) +#define USB_USBFRMADJUST_ADJ_SHIFT (0U) +#define USB_USBFRMADJUST_ADJ(x) (((uint8_t)(((uint8_t)(x)) << USB_USBFRMADJUST_ADJ_SHIFT)) & USB_USBFRMADJUST_ADJ_MASK) +/*! @} */ + +/*! @name CLK_RECOVER_CTRL - USB Clock recovery control */ +/*! @{ */ +#define USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN_MASK (0x20U) +#define USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN_SHIFT (5U) +/*! RESTART_IFRTRIM_EN - Restart from IFR trim value + * 0b0..Trim fine adjustment always works based on the previous updated trim fine value (default) + * 0b1..Trim fine restarts from the IFR trim value whenever bus_reset/bus_resume is detected or module enable is desasserted + */ +#define USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN_SHIFT)) & USB_CLK_RECOVER_CTRL_RESTART_IFRTRIM_EN_MASK) +#define USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN_MASK (0x40U) +#define USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN_SHIFT (6U) +/*! RESET_RESUME_ROUGH_EN - Reset/resume to rough phase enable + * 0b0..Always works in tracking phase after the 1st time rough to track transition (default) + * 0b1..Go back to rough stage whenever bus reset or bus resume occurs + */ +#define USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN_SHIFT)) & USB_CLK_RECOVER_CTRL_RESET_RESUME_ROUGH_EN_MASK) +#define USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK (0x80U) +#define USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_SHIFT (7U) +/*! CLOCK_RECOVER_EN - Crystal-less USB enable + * 0b0..Disable clock recovery block (default) + * 0b1..Enable clock recovery block + */ +#define USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_SHIFT)) & USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK) +/*! @} */ + +/*! @name CLK_RECOVER_IRC_EN - IRC48M oscillator enable register */ +/*! @{ */ +#define USB_CLK_RECOVER_IRC_EN_REG_EN_MASK (0x1U) +#define USB_CLK_RECOVER_IRC_EN_REG_EN_SHIFT (0U) +/*! REG_EN - IRC48M regulator enable + * 0b0..IRC48M local regulator is disabled + * 0b1..IRC48M local regulator is enabled (default) + */ +#define USB_CLK_RECOVER_IRC_EN_REG_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_IRC_EN_REG_EN_SHIFT)) & USB_CLK_RECOVER_IRC_EN_REG_EN_MASK) +#define USB_CLK_RECOVER_IRC_EN_IRC_EN_MASK (0x2U) +#define USB_CLK_RECOVER_IRC_EN_IRC_EN_SHIFT (1U) +/*! IRC_EN - IRC48M enable + * 0b0..Disable the IRC48M module (default) + * 0b1..Enable the IRC48M module + */ +#define USB_CLK_RECOVER_IRC_EN_IRC_EN(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_IRC_EN_IRC_EN_SHIFT)) & USB_CLK_RECOVER_IRC_EN_IRC_EN_MASK) +/*! @} */ + +/*! @name CLK_RECOVER_INT_STATUS - Clock recovery separated interrupt status */ +/*! @{ */ +#define USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_MASK (0x10U) +#define USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_SHIFT (4U) +/*! OVF_ERROR + * 0b0..No interrupt is reported + * 0b1..Unmasked interrupt has been generated + */ +#define USB_CLK_RECOVER_INT_STATUS_OVF_ERROR(x) (((uint8_t)(((uint8_t)(x)) << USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_SHIFT)) & USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group USB_Register_Masks */ + + +/* USB - Peripheral instance base addresses */ +/** Peripheral USB0 base address */ +#define USB0_BASE (0x40072000u) +/** Peripheral USB0 base pointer */ +#define USB0 ((USB_Type *)USB0_BASE) +/** Array initializer of USB peripheral base addresses */ +#define USB_BASE_ADDRS { USB0_BASE } +/** Array initializer of USB peripheral base pointers */ +#define USB_BASE_PTRS { USB0 } +/** Interrupt vectors for the USB peripheral type */ +#define USB_IRQS { USB0_IRQn } + +/*! + * @} + */ /* end of group USB_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- USBDCD Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USBDCD_Peripheral_Access_Layer USBDCD Peripheral Access Layer + * @{ + */ + +/** USBDCD - Register Layout Typedef */ +typedef struct { + __IO uint32_t CONTROL; /**< Control register, offset: 0x0 */ + __IO uint32_t CLOCK; /**< Clock register, offset: 0x4 */ + __I uint32_t STATUS; /**< Status register, offset: 0x8 */ + uint8_t RESERVED_0[4]; + __IO uint32_t TIMER0; /**< TIMER0 register, offset: 0x10 */ + __IO uint32_t TIMER1; /**< TIMER1 register, offset: 0x14 */ + union { /* offset: 0x18 */ + __IO uint32_t TIMER2_BC11; /**< TIMER2_BC11 register, offset: 0x18 */ + __IO uint32_t TIMER2_BC12; /**< TIMER2_BC12 register, offset: 0x18 */ + }; +} USBDCD_Type; + +/* ---------------------------------------------------------------------------- + -- USBDCD Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USBDCD_Register_Masks USBDCD Register Masks + * @{ + */ + +/*! @name CONTROL - Control register */ +/*! @{ */ +#define USBDCD_CONTROL_IACK_MASK (0x1U) +#define USBDCD_CONTROL_IACK_SHIFT (0U) +/*! IACK - Interrupt Acknowledge + * 0b0..Do not clear the interrupt. + * 0b1..Clear the IF bit (interrupt flag). + */ +#define USBDCD_CONTROL_IACK(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_CONTROL_IACK_SHIFT)) & USBDCD_CONTROL_IACK_MASK) +#define USBDCD_CONTROL_IF_MASK (0x100U) +#define USBDCD_CONTROL_IF_SHIFT (8U) +/*! IF - Interrupt Flag + * 0b0..No interrupt is pending. + * 0b1..An interrupt is pending. + */ +#define USBDCD_CONTROL_IF(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_CONTROL_IF_SHIFT)) & USBDCD_CONTROL_IF_MASK) +#define USBDCD_CONTROL_IE_MASK (0x10000U) +#define USBDCD_CONTROL_IE_SHIFT (16U) +/*! IE - Interrupt Enable + * 0b0..Disable interrupts to the system. + * 0b1..Enable interrupts to the system. + */ +#define USBDCD_CONTROL_IE(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_CONTROL_IE_SHIFT)) & USBDCD_CONTROL_IE_MASK) +#define USBDCD_CONTROL_BC12_MASK (0x20000U) +#define USBDCD_CONTROL_BC12_SHIFT (17U) +/*! BC12 + * 0b0..Compatible with BC1.1 (default) + * 0b1..Compatible with BC1.2 + */ +#define USBDCD_CONTROL_BC12(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_CONTROL_BC12_SHIFT)) & USBDCD_CONTROL_BC12_MASK) +#define USBDCD_CONTROL_START_MASK (0x1000000U) +#define USBDCD_CONTROL_START_SHIFT (24U) +/*! START - Start Change Detection Sequence + * 0b0..Do not start the sequence. Writes of this value have no effect. + * 0b1..Initiate the charger detection sequence. If the sequence is already running, writes of this value have no effect. + */ +#define USBDCD_CONTROL_START(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_CONTROL_START_SHIFT)) & USBDCD_CONTROL_START_MASK) +#define USBDCD_CONTROL_SR_MASK (0x2000000U) +#define USBDCD_CONTROL_SR_SHIFT (25U) +/*! SR - Software Reset + * 0b0..Do not perform a software reset. + * 0b1..Perform a software reset. + */ +#define USBDCD_CONTROL_SR(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_CONTROL_SR_SHIFT)) & USBDCD_CONTROL_SR_MASK) +/*! @} */ + +/*! @name CLOCK - Clock register */ +/*! @{ */ +#define USBDCD_CLOCK_CLOCK_UNIT_MASK (0x1U) +#define USBDCD_CLOCK_CLOCK_UNIT_SHIFT (0U) +/*! CLOCK_UNIT - Unit of Measurement Encoding for Clock Speed + * 0b0..kHz Speed (between 1 kHz and 1023 kHz) + * 0b1..MHz Speed (between 1 MHz and 1023 MHz) + */ +#define USBDCD_CLOCK_CLOCK_UNIT(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_CLOCK_CLOCK_UNIT_SHIFT)) & USBDCD_CLOCK_CLOCK_UNIT_MASK) +#define USBDCD_CLOCK_CLOCK_SPEED_MASK (0xFFCU) +#define USBDCD_CLOCK_CLOCK_SPEED_SHIFT (2U) +#define USBDCD_CLOCK_CLOCK_SPEED(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_CLOCK_CLOCK_SPEED_SHIFT)) & USBDCD_CLOCK_CLOCK_SPEED_MASK) +/*! @} */ + +/*! @name STATUS - Status register */ +/*! @{ */ +#define USBDCD_STATUS_SEQ_RES_MASK (0x30000U) +#define USBDCD_STATUS_SEQ_RES_SHIFT (16U) +/*! SEQ_RES - Charger Detection Sequence Results + * 0b00..No results to report. + * 0b01..Attached to a standard host. Must comply with USB 2.0 by drawing only 2.5 mA (max) until connected. + * 0b10..Attached to a charging port. The exact meaning depends on bit 18: 0: Attached to either a charging host or a dedicated charger. The charger type detection has not completed. 1: Attached to a charging host. The charger type detection has completed. + * 0b11..Attached to a dedicated charger. + */ +#define USBDCD_STATUS_SEQ_RES(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_STATUS_SEQ_RES_SHIFT)) & USBDCD_STATUS_SEQ_RES_MASK) +#define USBDCD_STATUS_SEQ_STAT_MASK (0xC0000U) +#define USBDCD_STATUS_SEQ_STAT_SHIFT (18U) +/*! SEQ_STAT - Charger Detection Sequence Status + * 0b00..The module is either not enabled, or the module is enabled but the data pins have not yet been detected. + * 0b01..Data pin contact detection is complete. + * 0b10..Charging port detection is complete. + * 0b11..Charger type detection is complete. + */ +#define USBDCD_STATUS_SEQ_STAT(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_STATUS_SEQ_STAT_SHIFT)) & USBDCD_STATUS_SEQ_STAT_MASK) +#define USBDCD_STATUS_ERR_MASK (0x100000U) +#define USBDCD_STATUS_ERR_SHIFT (20U) +/*! ERR - Error Flag + * 0b0..No sequence errors. + * 0b1..Error in the detection sequence. See the SEQ_STAT field to determine the phase in which the error occurred. + */ +#define USBDCD_STATUS_ERR(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_STATUS_ERR_SHIFT)) & USBDCD_STATUS_ERR_MASK) +#define USBDCD_STATUS_TO_MASK (0x200000U) +#define USBDCD_STATUS_TO_SHIFT (21U) +/*! TO - Timeout Flag + * 0b0..The detection sequence has not been running for over 1 s. + * 0b1..It has been over 1 s since the data pin contact was detected and debounced. + */ +#define USBDCD_STATUS_TO(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_STATUS_TO_SHIFT)) & USBDCD_STATUS_TO_MASK) +#define USBDCD_STATUS_ACTIVE_MASK (0x400000U) +#define USBDCD_STATUS_ACTIVE_SHIFT (22U) +/*! ACTIVE - Active Status Indicator + * 0b0..The sequence is not running. + * 0b1..The sequence is running. + */ +#define USBDCD_STATUS_ACTIVE(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_STATUS_ACTIVE_SHIFT)) & USBDCD_STATUS_ACTIVE_MASK) +/*! @} */ + +/*! @name TIMER0 - TIMER0 register */ +/*! @{ */ +#define USBDCD_TIMER0_TUNITCON_MASK (0xFFFU) +#define USBDCD_TIMER0_TUNITCON_SHIFT (0U) +#define USBDCD_TIMER0_TUNITCON(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_TIMER0_TUNITCON_SHIFT)) & USBDCD_TIMER0_TUNITCON_MASK) +#define USBDCD_TIMER0_TSEQ_INIT_MASK (0x3FF0000U) +#define USBDCD_TIMER0_TSEQ_INIT_SHIFT (16U) +#define USBDCD_TIMER0_TSEQ_INIT(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_TIMER0_TSEQ_INIT_SHIFT)) & USBDCD_TIMER0_TSEQ_INIT_MASK) +/*! @} */ + +/*! @name TIMER1 - TIMER1 register */ +/*! @{ */ +#define USBDCD_TIMER1_TVDPSRC_ON_MASK (0x3FFU) +#define USBDCD_TIMER1_TVDPSRC_ON_SHIFT (0U) +#define USBDCD_TIMER1_TVDPSRC_ON(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_TIMER1_TVDPSRC_ON_SHIFT)) & USBDCD_TIMER1_TVDPSRC_ON_MASK) +#define USBDCD_TIMER1_TDCD_DBNC_MASK (0x3FF0000U) +#define USBDCD_TIMER1_TDCD_DBNC_SHIFT (16U) +#define USBDCD_TIMER1_TDCD_DBNC(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_TIMER1_TDCD_DBNC_SHIFT)) & USBDCD_TIMER1_TDCD_DBNC_MASK) +/*! @} */ + +/*! @name TIMER2_BC11 - TIMER2_BC11 register */ +/*! @{ */ +#define USBDCD_TIMER2_BC11_CHECK_DM_MASK (0xFU) +#define USBDCD_TIMER2_BC11_CHECK_DM_SHIFT (0U) +#define USBDCD_TIMER2_BC11_CHECK_DM(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_TIMER2_BC11_CHECK_DM_SHIFT)) & USBDCD_TIMER2_BC11_CHECK_DM_MASK) +#define USBDCD_TIMER2_BC11_TVDPSRC_CON_MASK (0x3FF0000U) +#define USBDCD_TIMER2_BC11_TVDPSRC_CON_SHIFT (16U) +#define USBDCD_TIMER2_BC11_TVDPSRC_CON(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_TIMER2_BC11_TVDPSRC_CON_SHIFT)) & USBDCD_TIMER2_BC11_TVDPSRC_CON_MASK) +/*! @} */ + +/*! @name TIMER2_BC12 - TIMER2_BC12 register */ +/*! @{ */ +#define USBDCD_TIMER2_BC12_TVDMSRC_ON_MASK (0x3FFU) +#define USBDCD_TIMER2_BC12_TVDMSRC_ON_SHIFT (0U) +#define USBDCD_TIMER2_BC12_TVDMSRC_ON(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_TIMER2_BC12_TVDMSRC_ON_SHIFT)) & USBDCD_TIMER2_BC12_TVDMSRC_ON_MASK) +#define USBDCD_TIMER2_BC12_TWAIT_AFTER_PRD_MASK (0x3FF0000U) +#define USBDCD_TIMER2_BC12_TWAIT_AFTER_PRD_SHIFT (16U) +#define USBDCD_TIMER2_BC12_TWAIT_AFTER_PRD(x) (((uint32_t)(((uint32_t)(x)) << USBDCD_TIMER2_BC12_TWAIT_AFTER_PRD_SHIFT)) & USBDCD_TIMER2_BC12_TWAIT_AFTER_PRD_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group USBDCD_Register_Masks */ + + +/* USBDCD - Peripheral instance base addresses */ +/** Peripheral USBDCD base address */ +#define USBDCD_BASE (0x40035000u) +/** Peripheral USBDCD base pointer */ +#define USBDCD ((USBDCD_Type *)USBDCD_BASE) +/** Array initializer of USBDCD peripheral base addresses */ +#define USBDCD_BASE_ADDRS { USBDCD_BASE } +/** Array initializer of USBDCD peripheral base pointers */ +#define USBDCD_BASE_PTRS { USBDCD } +/** Interrupt vectors for the USBDCD peripheral type */ +#define USBDCD_IRQS { USBDCD_IRQn } + +/*! + * @} + */ /* end of group USBDCD_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- VREF Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup VREF_Peripheral_Access_Layer VREF Peripheral Access Layer + * @{ + */ + +/** VREF - Register Layout Typedef */ +typedef struct { + __IO uint8_t TRM; /**< VREF Trim Register, offset: 0x0 */ + __IO uint8_t SC; /**< VREF Status and Control Register, offset: 0x1 */ +} VREF_Type; + +/* ---------------------------------------------------------------------------- + -- VREF Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup VREF_Register_Masks VREF Register Masks + * @{ + */ + +/*! @name TRM - VREF Trim Register */ +/*! @{ */ +#define VREF_TRM_TRIM_MASK (0x3FU) +#define VREF_TRM_TRIM_SHIFT (0U) +/*! TRIM - Trim bits + * 0b000000..Min + * 0b111111..Max + */ +#define VREF_TRM_TRIM(x) (((uint8_t)(((uint8_t)(x)) << VREF_TRM_TRIM_SHIFT)) & VREF_TRM_TRIM_MASK) +#define VREF_TRM_CHOPEN_MASK (0x40U) +#define VREF_TRM_CHOPEN_SHIFT (6U) +/*! CHOPEN - Chop oscillator enable. When set, internal chopping operation is enabled and the internal analog offset will be minimized. + * 0b0..Chop oscillator is disabled. + * 0b1..Chop oscillator is enabled. + */ +#define VREF_TRM_CHOPEN(x) (((uint8_t)(((uint8_t)(x)) << VREF_TRM_CHOPEN_SHIFT)) & VREF_TRM_CHOPEN_MASK) +/*! @} */ + +/*! @name SC - VREF Status and Control Register */ +/*! @{ */ +#define VREF_SC_MODE_LV_MASK (0x3U) +#define VREF_SC_MODE_LV_SHIFT (0U) +/*! MODE_LV - Buffer Mode selection + * 0b00..Bandgap on only, for stabilization and startup + * 0b01..High power buffer mode enabled + * 0b10..Low-power buffer mode enabled + * 0b11..Reserved + */ +#define VREF_SC_MODE_LV(x) (((uint8_t)(((uint8_t)(x)) << VREF_SC_MODE_LV_SHIFT)) & VREF_SC_MODE_LV_MASK) +#define VREF_SC_VREFST_MASK (0x4U) +#define VREF_SC_VREFST_SHIFT (2U) +/*! VREFST - Internal Voltage Reference stable + * 0b0..The module is disabled or not stable. + * 0b1..The module is stable. + */ +#define VREF_SC_VREFST(x) (((uint8_t)(((uint8_t)(x)) << VREF_SC_VREFST_SHIFT)) & VREF_SC_VREFST_MASK) +#define VREF_SC_ICOMPEN_MASK (0x20U) +#define VREF_SC_ICOMPEN_SHIFT (5U) +/*! ICOMPEN - Second order curvature compensation enable + * 0b0..Disabled + * 0b1..Enabled + */ +#define VREF_SC_ICOMPEN(x) (((uint8_t)(((uint8_t)(x)) << VREF_SC_ICOMPEN_SHIFT)) & VREF_SC_ICOMPEN_MASK) +#define VREF_SC_REGEN_MASK (0x40U) +#define VREF_SC_REGEN_SHIFT (6U) +/*! REGEN - Regulator enable + * 0b0..Internal 1.75 V regulator is disabled. + * 0b1..Internal 1.75 V regulator is enabled. + */ +#define VREF_SC_REGEN(x) (((uint8_t)(((uint8_t)(x)) << VREF_SC_REGEN_SHIFT)) & VREF_SC_REGEN_MASK) +#define VREF_SC_VREFEN_MASK (0x80U) +#define VREF_SC_VREFEN_SHIFT (7U) +/*! VREFEN - Internal Voltage Reference enable + * 0b0..The module is disabled. + * 0b1..The module is enabled. + */ +#define VREF_SC_VREFEN(x) (((uint8_t)(((uint8_t)(x)) << VREF_SC_VREFEN_SHIFT)) & VREF_SC_VREFEN_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group VREF_Register_Masks */ + + +/* VREF - Peripheral instance base addresses */ +/** Peripheral VREF base address */ +#define VREF_BASE (0x40074000u) +/** Peripheral VREF base pointer */ +#define VREF ((VREF_Type *)VREF_BASE) +/** Array initializer of VREF peripheral base addresses */ +#define VREF_BASE_ADDRS { VREF_BASE } +/** Array initializer of VREF peripheral base pointers */ +#define VREF_BASE_PTRS { VREF } + +/*! + * @} + */ /* end of group VREF_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- WDOG Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup WDOG_Peripheral_Access_Layer WDOG Peripheral Access Layer + * @{ + */ + +/** WDOG - Register Layout Typedef */ +typedef struct { + __IO uint16_t STCTRLH; /**< Watchdog Status and Control Register High, offset: 0x0 */ + __IO uint16_t STCTRLL; /**< Watchdog Status and Control Register Low, offset: 0x2 */ + __IO uint16_t TOVALH; /**< Watchdog Time-out Value Register High, offset: 0x4 */ + __IO uint16_t TOVALL; /**< Watchdog Time-out Value Register Low, offset: 0x6 */ + __IO uint16_t WINH; /**< Watchdog Window Register High, offset: 0x8 */ + __IO uint16_t WINL; /**< Watchdog Window Register Low, offset: 0xA */ + __IO uint16_t REFRESH; /**< Watchdog Refresh register, offset: 0xC */ + __IO uint16_t UNLOCK; /**< Watchdog Unlock register, offset: 0xE */ + __IO uint16_t TMROUTH; /**< Watchdog Timer Output Register High, offset: 0x10 */ + __IO uint16_t TMROUTL; /**< Watchdog Timer Output Register Low, offset: 0x12 */ + __IO uint16_t RSTCNT; /**< Watchdog Reset Count register, offset: 0x14 */ + __IO uint16_t PRESC; /**< Watchdog Prescaler register, offset: 0x16 */ +} WDOG_Type; + +/* ---------------------------------------------------------------------------- + -- WDOG Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup WDOG_Register_Masks WDOG Register Masks + * @{ + */ + +/*! @name STCTRLH - Watchdog Status and Control Register High */ +/*! @{ */ +#define WDOG_STCTRLH_WDOGEN_MASK (0x1U) +#define WDOG_STCTRLH_WDOGEN_SHIFT (0U) +/*! WDOGEN + * 0b0..WDOG is disabled. + * 0b1..WDOG is enabled. + */ +#define WDOG_STCTRLH_WDOGEN(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_WDOGEN_SHIFT)) & WDOG_STCTRLH_WDOGEN_MASK) +#define WDOG_STCTRLH_CLKSRC_MASK (0x2U) +#define WDOG_STCTRLH_CLKSRC_SHIFT (1U) +/*! CLKSRC + * 0b0..WDOG clock sourced from LPO . + * 0b1..WDOG clock sourced from alternate clock source. + */ +#define WDOG_STCTRLH_CLKSRC(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_CLKSRC_SHIFT)) & WDOG_STCTRLH_CLKSRC_MASK) +#define WDOG_STCTRLH_IRQRSTEN_MASK (0x4U) +#define WDOG_STCTRLH_IRQRSTEN_SHIFT (2U) +/*! IRQRSTEN + * 0b0..WDOG time-out generates reset only. + * 0b1..WDOG time-out initially generates an interrupt. After WCT, it generates a reset. + */ +#define WDOG_STCTRLH_IRQRSTEN(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_IRQRSTEN_SHIFT)) & WDOG_STCTRLH_IRQRSTEN_MASK) +#define WDOG_STCTRLH_WINEN_MASK (0x8U) +#define WDOG_STCTRLH_WINEN_SHIFT (3U) +/*! WINEN + * 0b0..Windowing mode is disabled. + * 0b1..Windowing mode is enabled. + */ +#define WDOG_STCTRLH_WINEN(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_WINEN_SHIFT)) & WDOG_STCTRLH_WINEN_MASK) +#define WDOG_STCTRLH_ALLOWUPDATE_MASK (0x10U) +#define WDOG_STCTRLH_ALLOWUPDATE_SHIFT (4U) +/*! ALLOWUPDATE + * 0b0..No further updates allowed to WDOG write-once registers. + * 0b1..WDOG write-once registers can be unlocked for updating. + */ +#define WDOG_STCTRLH_ALLOWUPDATE(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_ALLOWUPDATE_SHIFT)) & WDOG_STCTRLH_ALLOWUPDATE_MASK) +#define WDOG_STCTRLH_DBGEN_MASK (0x20U) +#define WDOG_STCTRLH_DBGEN_SHIFT (5U) +/*! DBGEN + * 0b0..WDOG is disabled in CPU Debug mode. + * 0b1..WDOG is enabled in CPU Debug mode. + */ +#define WDOG_STCTRLH_DBGEN(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_DBGEN_SHIFT)) & WDOG_STCTRLH_DBGEN_MASK) +#define WDOG_STCTRLH_STOPEN_MASK (0x40U) +#define WDOG_STCTRLH_STOPEN_SHIFT (6U) +/*! STOPEN + * 0b0..WDOG is disabled in CPU Stop mode. + * 0b1..WDOG is enabled in CPU Stop mode. + */ +#define WDOG_STCTRLH_STOPEN(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_STOPEN_SHIFT)) & WDOG_STCTRLH_STOPEN_MASK) +#define WDOG_STCTRLH_WAITEN_MASK (0x80U) +#define WDOG_STCTRLH_WAITEN_SHIFT (7U) +/*! WAITEN + * 0b0..WDOG is disabled in CPU Wait mode. + * 0b1..WDOG is enabled in CPU Wait mode. + */ +#define WDOG_STCTRLH_WAITEN(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_WAITEN_SHIFT)) & WDOG_STCTRLH_WAITEN_MASK) +#define WDOG_STCTRLH_TESTWDOG_MASK (0x400U) +#define WDOG_STCTRLH_TESTWDOG_SHIFT (10U) +#define WDOG_STCTRLH_TESTWDOG(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_TESTWDOG_SHIFT)) & WDOG_STCTRLH_TESTWDOG_MASK) +#define WDOG_STCTRLH_TESTSEL_MASK (0x800U) +#define WDOG_STCTRLH_TESTSEL_SHIFT (11U) +/*! TESTSEL + * 0b0..Quick test. The timer runs in normal operation. You can load a small time-out value to do a quick test. + * 0b1..Byte test. Puts the timer in the byte test mode where individual bytes of the timer are enabled for operation and are compared for time-out against the corresponding byte of the programmed time-out value. Select the byte through BYTESEL[1:0] for testing. + */ +#define WDOG_STCTRLH_TESTSEL(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_TESTSEL_SHIFT)) & WDOG_STCTRLH_TESTSEL_MASK) +#define WDOG_STCTRLH_BYTESEL_MASK (0x3000U) +#define WDOG_STCTRLH_BYTESEL_SHIFT (12U) +/*! BYTESEL + * 0b00..Byte 0 selected + * 0b01..Byte 1 selected + * 0b10..Byte 2 selected + * 0b11..Byte 3 selected + */ +#define WDOG_STCTRLH_BYTESEL(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_BYTESEL_SHIFT)) & WDOG_STCTRLH_BYTESEL_MASK) +#define WDOG_STCTRLH_DISTESTWDOG_MASK (0x4000U) +#define WDOG_STCTRLH_DISTESTWDOG_SHIFT (14U) +/*! DISTESTWDOG + * 0b0..WDOG functional test mode is not disabled. + * 0b1..WDOG functional test mode is disabled permanently until reset. + */ +#define WDOG_STCTRLH_DISTESTWDOG(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLH_DISTESTWDOG_SHIFT)) & WDOG_STCTRLH_DISTESTWDOG_MASK) +/*! @} */ + +/*! @name STCTRLL - Watchdog Status and Control Register Low */ +/*! @{ */ +#define WDOG_STCTRLL_INTFLG_MASK (0x8000U) +#define WDOG_STCTRLL_INTFLG_SHIFT (15U) +#define WDOG_STCTRLL_INTFLG(x) (((uint16_t)(((uint16_t)(x)) << WDOG_STCTRLL_INTFLG_SHIFT)) & WDOG_STCTRLL_INTFLG_MASK) +/*! @} */ + +/*! @name TOVALH - Watchdog Time-out Value Register High */ +/*! @{ */ +#define WDOG_TOVALH_TOVALHIGH_MASK (0xFFFFU) +#define WDOG_TOVALH_TOVALHIGH_SHIFT (0U) +#define WDOG_TOVALH_TOVALHIGH(x) (((uint16_t)(((uint16_t)(x)) << WDOG_TOVALH_TOVALHIGH_SHIFT)) & WDOG_TOVALH_TOVALHIGH_MASK) +/*! @} */ + +/*! @name TOVALL - Watchdog Time-out Value Register Low */ +/*! @{ */ +#define WDOG_TOVALL_TOVALLOW_MASK (0xFFFFU) +#define WDOG_TOVALL_TOVALLOW_SHIFT (0U) +#define WDOG_TOVALL_TOVALLOW(x) (((uint16_t)(((uint16_t)(x)) << WDOG_TOVALL_TOVALLOW_SHIFT)) & WDOG_TOVALL_TOVALLOW_MASK) +/*! @} */ + +/*! @name WINH - Watchdog Window Register High */ +/*! @{ */ +#define WDOG_WINH_WINHIGH_MASK (0xFFFFU) +#define WDOG_WINH_WINHIGH_SHIFT (0U) +#define WDOG_WINH_WINHIGH(x) (((uint16_t)(((uint16_t)(x)) << WDOG_WINH_WINHIGH_SHIFT)) & WDOG_WINH_WINHIGH_MASK) +/*! @} */ + +/*! @name WINL - Watchdog Window Register Low */ +/*! @{ */ +#define WDOG_WINL_WINLOW_MASK (0xFFFFU) +#define WDOG_WINL_WINLOW_SHIFT (0U) +#define WDOG_WINL_WINLOW(x) (((uint16_t)(((uint16_t)(x)) << WDOG_WINL_WINLOW_SHIFT)) & WDOG_WINL_WINLOW_MASK) +/*! @} */ + +/*! @name REFRESH - Watchdog Refresh register */ +/*! @{ */ +#define WDOG_REFRESH_WDOGREFRESH_MASK (0xFFFFU) +#define WDOG_REFRESH_WDOGREFRESH_SHIFT (0U) +#define WDOG_REFRESH_WDOGREFRESH(x) (((uint16_t)(((uint16_t)(x)) << WDOG_REFRESH_WDOGREFRESH_SHIFT)) & WDOG_REFRESH_WDOGREFRESH_MASK) +/*! @} */ + +/*! @name UNLOCK - Watchdog Unlock register */ +/*! @{ */ +#define WDOG_UNLOCK_WDOGUNLOCK_MASK (0xFFFFU) +#define WDOG_UNLOCK_WDOGUNLOCK_SHIFT (0U) +#define WDOG_UNLOCK_WDOGUNLOCK(x) (((uint16_t)(((uint16_t)(x)) << WDOG_UNLOCK_WDOGUNLOCK_SHIFT)) & WDOG_UNLOCK_WDOGUNLOCK_MASK) +/*! @} */ + +/*! @name TMROUTH - Watchdog Timer Output Register High */ +/*! @{ */ +#define WDOG_TMROUTH_TIMEROUTHIGH_MASK (0xFFFFU) +#define WDOG_TMROUTH_TIMEROUTHIGH_SHIFT (0U) +#define WDOG_TMROUTH_TIMEROUTHIGH(x) (((uint16_t)(((uint16_t)(x)) << WDOG_TMROUTH_TIMEROUTHIGH_SHIFT)) & WDOG_TMROUTH_TIMEROUTHIGH_MASK) +/*! @} */ + +/*! @name TMROUTL - Watchdog Timer Output Register Low */ +/*! @{ */ +#define WDOG_TMROUTL_TIMEROUTLOW_MASK (0xFFFFU) +#define WDOG_TMROUTL_TIMEROUTLOW_SHIFT (0U) +#define WDOG_TMROUTL_TIMEROUTLOW(x) (((uint16_t)(((uint16_t)(x)) << WDOG_TMROUTL_TIMEROUTLOW_SHIFT)) & WDOG_TMROUTL_TIMEROUTLOW_MASK) +/*! @} */ + +/*! @name RSTCNT - Watchdog Reset Count register */ +/*! @{ */ +#define WDOG_RSTCNT_RSTCNT_MASK (0xFFFFU) +#define WDOG_RSTCNT_RSTCNT_SHIFT (0U) +#define WDOG_RSTCNT_RSTCNT(x) (((uint16_t)(((uint16_t)(x)) << WDOG_RSTCNT_RSTCNT_SHIFT)) & WDOG_RSTCNT_RSTCNT_MASK) +/*! @} */ + +/*! @name PRESC - Watchdog Prescaler register */ +/*! @{ */ +#define WDOG_PRESC_PRESCVAL_MASK (0x700U) +#define WDOG_PRESC_PRESCVAL_SHIFT (8U) +#define WDOG_PRESC_PRESCVAL(x) (((uint16_t)(((uint16_t)(x)) << WDOG_PRESC_PRESCVAL_SHIFT)) & WDOG_PRESC_PRESCVAL_MASK) +/*! @} */ + + +/*! + * @} + */ /* end of group WDOG_Register_Masks */ + + +/* WDOG - Peripheral instance base addresses */ +/** Peripheral WDOG base address */ +#define WDOG_BASE (0x40052000u) +/** Peripheral WDOG base pointer */ +#define WDOG ((WDOG_Type *)WDOG_BASE) +/** Array initializer of WDOG peripheral base addresses */ +#define WDOG_BASE_ADDRS { WDOG_BASE } +/** Array initializer of WDOG peripheral base pointers */ +#define WDOG_BASE_PTRS { WDOG } +/** Interrupt vectors for the WDOG peripheral type */ +#define WDOG_IRQS { WDOG_EWM_IRQn } + +/*! + * @} + */ /* end of group WDOG_Peripheral_Access_Layer */ + + +/* +** End of section using anonymous unions +*/ + +#if defined(__ARMCC_VERSION) + #if (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic pop + #else + #pragma pop + #endif +#elif defined(__CWCC__) + #pragma pop +#elif defined(__GNUC__) + /* leave anonymous unions enabled */ +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma language=default +#else + #error Not supported compiler type +#endif + +/*! + * @} + */ /* end of group Peripheral_access_layer */ + + +/* ---------------------------------------------------------------------------- + -- Macros for use with bit field definitions (xxx_SHIFT, xxx_MASK). + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Bit_Field_Generic_Macros Macros for use with bit field definitions (xxx_SHIFT, xxx_MASK). + * @{ + */ + +#if defined(__ARMCC_VERSION) + #if (__ARMCC_VERSION >= 6010050) + #pragma clang system_header + #endif +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma system_include +#endif + +/** + * @brief Mask and left-shift a bit field value for use in a register bit range. + * @param field Name of the register bit field. + * @param value Value of the bit field. + * @return Masked and shifted value. + */ +#define NXP_VAL2FLD(field, value) (((value) << (field ## _SHIFT)) & (field ## _MASK)) +/** + * @brief Mask and right-shift a register value to extract a bit field value. + * @param field Name of the register bit field. + * @param value Value of the register. + * @return Masked and shifted bit field value. + */ +#define NXP_FLD2VAL(field, value) (((value) & (field ## _MASK)) >> (field ## _SHIFT)) + +/*! + * @} + */ /* end of group Bit_Field_Generic_Macros */ + + +/* ---------------------------------------------------------------------------- + -- SDK Compatibility + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SDK_Compatibility_Symbols SDK Compatibility + * @{ + */ + +#define ENET_RMON_R_DROP_REG(base) ENET_IEEE_R_DROP_REG(base) +#define ENET_RMON_R_FRAME_OK_REG(base) ENET_IEEE_R_FRAME_OK_REG(base) +#define MCG_C2_EREFS0_MASK MCG_C2_EREFS_MASK +#define MCG_C2_EREFS0_SHIFT MCG_C2_EREFS_SHIFT +#define MCG_C2_HGO0_MASK MCG_C2_HGO_MASK +#define MCG_C2_HGO0_SHIFT MCG_C2_HGO_SHIFT +#define MCG_C2_RANGE0_MASK MCG_C2_RANGE_MASK +#define MCG_C2_RANGE0_SHIFT MCG_C2_RANGE_SHIFT +#define MCG_C2_RANGE0(x) MCG_C2_RANGE(x) +#define MCM_ISR_REG(base) MCM_ISCR_REG(base) +#define MCM_ISR_FIOC_MASK MCM_ISCR_FIOC_MASK +#define MCM_ISR_FIOC_SHIFT MCM_ISCR_FIOC_SHIFT +#define MCM_ISR_FDZC_MASK MCM_ISCR_FDZC_MASK +#define MCM_ISR_FDZC_SHIFT MCM_ISCR_FDZC_SHIFT +#define MCM_ISR_FOFC_MASK MCM_ISCR_FOFC_MASK +#define MCM_ISR_FOFC_SHIFT MCM_ISCR_FOFC_SHIFT +#define MCM_ISR_FUFC_MASK MCM_ISCR_FUFC_MASK +#define MCM_ISR_FUFC_SHIFT MCM_ISCR_FUFC_SHIFT +#define MCM_ISR_FIXC_MASK MCM_ISCR_FIXC_MASK +#define MCM_ISR_FIXC_SHIFT MCM_ISCR_FIXC_SHIFT +#define MCM_ISR_FIDC_MASK MCM_ISCR_FIDC_MASK +#define MCM_ISR_FIDC_SHIFT MCM_ISCR_FIDC_SHIFT +#define MCM_ISR_FIOCE_MASK MCM_ISCR_FIOCE_MASK +#define MCM_ISR_FIOCE_SHIFT MCM_ISCR_FIOCE_SHIFT +#define MCM_ISR_FDZCE_MASK MCM_ISCR_FDZCE_MASK +#define MCM_ISR_FDZCE_SHIFT MCM_ISCR_FDZCE_SHIFT +#define MCM_ISR_FOFCE_MASK MCM_ISCR_FOFCE_MASK +#define MCM_ISR_FOFCE_SHIFT MCM_ISCR_FOFCE_SHIFT +#define MCM_ISR_FUFCE_MASK MCM_ISCR_FUFCE_MASK +#define MCM_ISR_FUFCE_SHIFT MCM_ISCR_FUFCE_SHIFT +#define MCM_ISR_FIXCE_MASK MCM_ISCR_FIXCE_MASK +#define MCM_ISR_FIXCE_SHIFT MCM_ISCR_FIXCE_SHIFT +#define MCM_ISR_FIDCE_MASK MCM_ISCR_FIDCE_MASK +#define MCM_ISR_FIDCE_SHIFT MCM_ISCR_FIDCE_SHIFT +#define DSPI0 SPI0 +#define DSPI1 SPI1 +#define DSPI2 SPI2 +#define FLEXCAN0 CAN0 +#define PTA_BASE GPIOA_BASE +#define PTA GPIOA +#define PTB_BASE GPIOB_BASE +#define PTB GPIOB +#define PTC_BASE GPIOC_BASE +#define PTC GPIOC +#define PTD_BASE GPIOD_BASE +#define PTD GPIOD +#define PTE_BASE GPIOE_BASE +#define PTE GPIOE +#define UART_WP7816_T_TYPE0_REG(base) UART_WP7816T0_REG(base) +#define UART_WP7816_T_TYPE1_REG(base) UART_WP7816T1_REG(base) +#define UART_WP7816_T_TYPE0_WI_MASK UART_WP7816T0_WI_MASK +#define UART_WP7816_T_TYPE0_WI_SHIFT UART_WP7816T0_WI_SHIFT +#define UART_WP7816_T_TYPE0_WI(x) UART_WP7816T0_WI(x) +#define UART_WP7816_T_TYPE1_BWI_MASK UART_WP7816T1_BWI_MASK +#define UART_WP7816_T_TYPE1_BWI_SHIFT UART_WP7816T1_BWI_SHIFT +#define UART_WP7816_T_TYPE1_BWI(x) UART_WP7816T1_BWI(x) +#define UART_WP7816_T_TYPE1_CWI_MASK UART_WP7816T1_CWI_MASK +#define UART_WP7816_T_TYPE1_CWI_SHIFT UART_WP7816T1_CWI_SHIFT +#define UART_WP7816_T_TYPE1_CWI(x) UART_WP7816T1_CWI(x) +#define Watchdog_IRQn WDOG_EWM_IRQn +#define Watchdog_IRQHandler WDOG_EWM_IRQHandler +#define LPTimer_IRQn LPTMR0_IRQn +#define LPTimer_IRQHandler LPTMR0_IRQHandler +#define LLW_IRQn LLWU_IRQn +#define LLW_IRQHandler LLWU_IRQHandler +#define DMAMUX0 DMAMUX +#define WDOG0 WDOG +#define MCM0 MCM +#define RTC0 RTC + +/*! + * @} + */ /* end of group SDK_Compatibility_Symbols */ + + +#endif /* _MK64F12_H_ */ + diff --git a/device/MK64F12_features.h b/device/MK64F12_features.h new file mode 100644 index 0000000..a0a4d29 --- /dev/null +++ b/device/MK64F12_features.h @@ -0,0 +1,1942 @@ +/* +** ################################################################### +** Version: rev. 2.15, 2016-03-21 +** Build: b180801 +** +** Abstract: +** Chip specific module features. +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2018 NXP +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** Revisions: +** - rev. 1.0 (2013-08-12) +** Initial version. +** - rev. 2.0 (2013-10-29) +** Register accessor macros added to the memory map. +** Symbols for Processor Expert memory map compatibility added to the memory map. +** Startup file for gcc has been updated according to CMSIS 3.2. +** System initialization updated. +** MCG - registers updated. +** PORTA, PORTB, PORTC, PORTE - registers for digital filter removed. +** - rev. 2.1 (2013-10-30) +** Definition of BITBAND macros updated to support peripherals with 32-bit acces disabled. +** - rev. 2.2 (2013-12-09) +** DMA - EARS register removed. +** AIPS0, AIPS1 - MPRA register updated. +** - rev. 2.3 (2014-01-24) +** Update according to reference manual rev. 2 +** ENET, MCG, MCM, SIM, USB - registers updated +** - rev. 2.4 (2014-01-30) +** Added single maximum value generation and a constrain to varying feature values that only numbers can have maximum. +** - rev. 2.5 (2014-02-10) +** The declaration of clock configurations has been moved to separate header file system_MK64F12.h +** Update of SystemInit() and SystemCoreClockUpdate() functions. +** - rev. 2.6 (2014-02-10) +** The declaration of clock configurations has been moved to separate header file system_MK64F12.h +** Update of SystemInit() and SystemCoreClockUpdate() functions. +** Module access macro module_BASES replaced by module_BASE_PTRS. +** - rev. 2.7 (2014-08-28) +** Update of system files - default clock configuration changed. +** Update of startup files - possibility to override DefaultISR added. +** - rev. 2.8 (2014-10-14) +** Interrupt INT_LPTimer renamed to INT_LPTMR0, interrupt INT_Watchdog renamed to INT_WDOG_EWM. +** - rev. 2.9 (2015-01-21) +** Added FSL_FEATURE_SOC_peripheral_COUNT with number of peripheral instances +** - rev. 2.10 (2015-02-19) +** Renamed interrupt vector LLW to LLWU. +** - rev. 2.11 (2015-05-19) +** FSL_FEATURE_SOC_CAU_COUNT remamed to FSL_FEATURE_SOC_MMCAU_COUNT. +** Added FSL_FEATURE_SOC_peripheral_COUNT for TRNG and HSADC. +** Added features for PDB and PORT. +** - rev. 2.12 (2015-05-25) +** Added FSL_FEATURE_FLASH_PFLASH_START_ADDRESS +** - rev. 2.13 (2015-05-27) +** Several USB features added. +** - rev. 2.14 (2015-06-08) +** FTM features BUS_CLOCK and FAST_CLOCK removed. +** - rev. 2.15 (2016-03-21) +** Added MK64FN1M0CAJ12 part. +** +** ################################################################### +*/ + +#ifndef _MK64F12_FEATURES_H_ +#define _MK64F12_FEATURES_H_ + +/* SOC module features */ + +#if defined(CPU_MK64FN1M0CAJ12) || defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLQ12) || defined(CPU_MK64FN1M0VMD12) || \ + defined(CPU_MK64FX512VDC12) || defined(CPU_MK64FX512VLQ12) || defined(CPU_MK64FX512VMD12) + /* @brief ADC16 availability on the SoC. */ + #define FSL_FEATURE_SOC_ADC16_COUNT (2) + /* @brief AIPS availability on the SoC. */ + #define FSL_FEATURE_SOC_AIPS_COUNT (2) + /* @brief AXBS availability on the SoC. */ + #define FSL_FEATURE_SOC_AXBS_COUNT (1) + /* @brief FLEXCAN availability on the SoC. */ + #define FSL_FEATURE_SOC_FLEXCAN_COUNT (1) + /* @brief MMCAU availability on the SoC. */ + #define FSL_FEATURE_SOC_MMCAU_COUNT (1) + /* @brief CMP availability on the SoC. */ + #define FSL_FEATURE_SOC_CMP_COUNT (3) + /* @brief CMT availability on the SoC. */ + #define FSL_FEATURE_SOC_CMT_COUNT (1) + /* @brief CRC availability on the SoC. */ + #define FSL_FEATURE_SOC_CRC_COUNT (1) + /* @brief DAC availability on the SoC. */ + #define FSL_FEATURE_SOC_DAC_COUNT (2) + /* @brief EDMA availability on the SoC. */ + #define FSL_FEATURE_SOC_EDMA_COUNT (1) + /* @brief DMAMUX availability on the SoC. */ + #define FSL_FEATURE_SOC_DMAMUX_COUNT (1) + /* @brief DSPI availability on the SoC. */ + #define FSL_FEATURE_SOC_DSPI_COUNT (3) + /* @brief ENET availability on the SoC. */ + #define FSL_FEATURE_SOC_ENET_COUNT (1) + /* @brief EWM availability on the SoC. */ + #define FSL_FEATURE_SOC_EWM_COUNT (1) + /* @brief FB availability on the SoC. */ + #define FSL_FEATURE_SOC_FB_COUNT (1) + /* @brief FMC availability on the SoC. */ + #define FSL_FEATURE_SOC_FMC_COUNT (1) + /* @brief FTFE availability on the SoC. */ + #define FSL_FEATURE_SOC_FTFE_COUNT (1) + /* @brief FTM availability on the SoC. */ + #define FSL_FEATURE_SOC_FTM_COUNT (4) + /* @brief GPIO availability on the SoC. */ + #define FSL_FEATURE_SOC_GPIO_COUNT (5) + /* @brief I2C availability on the SoC. */ + #define FSL_FEATURE_SOC_I2C_COUNT (3) + /* @brief I2S availability on the SoC. */ + #define FSL_FEATURE_SOC_I2S_COUNT (1) + /* @brief LLWU availability on the SoC. */ + #define FSL_FEATURE_SOC_LLWU_COUNT (1) + /* @brief LPTMR availability on the SoC. */ + #define FSL_FEATURE_SOC_LPTMR_COUNT (1) + /* @brief MCG availability on the SoC. */ + #define FSL_FEATURE_SOC_MCG_COUNT (1) + /* @brief MCM availability on the SoC. */ + #define FSL_FEATURE_SOC_MCM_COUNT (1) + /* @brief SYSMPU availability on the SoC. */ + #define FSL_FEATURE_SOC_SYSMPU_COUNT (1) + /* @brief OSC availability on the SoC. */ + #define FSL_FEATURE_SOC_OSC_COUNT (1) + /* @brief PDB availability on the SoC. */ + #define FSL_FEATURE_SOC_PDB_COUNT (1) + /* @brief PIT availability on the SoC. */ + #define FSL_FEATURE_SOC_PIT_COUNT (1) + /* @brief PMC availability on the SoC. */ + #define FSL_FEATURE_SOC_PMC_COUNT (1) + /* @brief PORT availability on the SoC. */ + #define FSL_FEATURE_SOC_PORT_COUNT (5) + /* @brief RCM availability on the SoC. */ + #define FSL_FEATURE_SOC_RCM_COUNT (1) + /* @brief RFSYS availability on the SoC. */ + #define FSL_FEATURE_SOC_RFSYS_COUNT (1) + /* @brief RFVBAT availability on the SoC. */ + #define FSL_FEATURE_SOC_RFVBAT_COUNT (1) + /* @brief RNG availability on the SoC. */ + #define FSL_FEATURE_SOC_RNG_COUNT (1) + /* @brief RTC availability on the SoC. */ + #define FSL_FEATURE_SOC_RTC_COUNT (1) + /* @brief SDHC availability on the SoC. */ + #define FSL_FEATURE_SOC_SDHC_COUNT (1) + /* @brief SIM availability on the SoC. */ + #define FSL_FEATURE_SOC_SIM_COUNT (1) + /* @brief SMC availability on the SoC. */ + #define FSL_FEATURE_SOC_SMC_COUNT (1) + /* @brief UART availability on the SoC. */ + #define FSL_FEATURE_SOC_UART_COUNT (6) + /* @brief USB availability on the SoC. */ + #define FSL_FEATURE_SOC_USB_COUNT (1) + /* @brief USBDCD availability on the SoC. */ + #define FSL_FEATURE_SOC_USBDCD_COUNT (1) + /* @brief VREF availability on the SoC. */ + #define FSL_FEATURE_SOC_VREF_COUNT (1) + /* @brief WDOG availability on the SoC. */ + #define FSL_FEATURE_SOC_WDOG_COUNT (1) +#elif defined(CPU_MK64FN1M0VLL12) || defined(CPU_MK64FX512VLL12) + /* @brief ADC16 availability on the SoC. */ + #define FSL_FEATURE_SOC_ADC16_COUNT (2) + /* @brief AIPS availability on the SoC. */ + #define FSL_FEATURE_SOC_AIPS_COUNT (2) + /* @brief AXBS availability on the SoC. */ + #define FSL_FEATURE_SOC_AXBS_COUNT (1) + /* @brief FLEXCAN availability on the SoC. */ + #define FSL_FEATURE_SOC_FLEXCAN_COUNT (1) + /* @brief MMCAU availability on the SoC. */ + #define FSL_FEATURE_SOC_MMCAU_COUNT (1) + /* @brief CMP availability on the SoC. */ + #define FSL_FEATURE_SOC_CMP_COUNT (3) + /* @brief CMT availability on the SoC. */ + #define FSL_FEATURE_SOC_CMT_COUNT (1) + /* @brief CRC availability on the SoC. */ + #define FSL_FEATURE_SOC_CRC_COUNT (1) + /* @brief DAC availability on the SoC. */ + #define FSL_FEATURE_SOC_DAC_COUNT (1) + /* @brief EDMA availability on the SoC. */ + #define FSL_FEATURE_SOC_EDMA_COUNT (1) + /* @brief DMAMUX availability on the SoC. */ + #define FSL_FEATURE_SOC_DMAMUX_COUNT (1) + /* @brief DSPI availability on the SoC. */ + #define FSL_FEATURE_SOC_DSPI_COUNT (3) + /* @brief ENET availability on the SoC. */ + #define FSL_FEATURE_SOC_ENET_COUNT (1) + /* @brief EWM availability on the SoC. */ + #define FSL_FEATURE_SOC_EWM_COUNT (1) + /* @brief FB availability on the SoC. */ + #define FSL_FEATURE_SOC_FB_COUNT (1) + /* @brief FMC availability on the SoC. */ + #define FSL_FEATURE_SOC_FMC_COUNT (1) + /* @brief FTFE availability on the SoC. */ + #define FSL_FEATURE_SOC_FTFE_COUNT (1) + /* @brief FTM availability on the SoC. */ + #define FSL_FEATURE_SOC_FTM_COUNT (4) + /* @brief GPIO availability on the SoC. */ + #define FSL_FEATURE_SOC_GPIO_COUNT (5) + /* @brief I2C availability on the SoC. */ + #define FSL_FEATURE_SOC_I2C_COUNT (3) + /* @brief I2S availability on the SoC. */ + #define FSL_FEATURE_SOC_I2S_COUNT (1) + /* @brief LLWU availability on the SoC. */ + #define FSL_FEATURE_SOC_LLWU_COUNT (1) + /* @brief LPTMR availability on the SoC. */ + #define FSL_FEATURE_SOC_LPTMR_COUNT (1) + /* @brief MCG availability on the SoC. */ + #define FSL_FEATURE_SOC_MCG_COUNT (1) + /* @brief MCM availability on the SoC. */ + #define FSL_FEATURE_SOC_MCM_COUNT (1) + /* @brief SYSMPU availability on the SoC. */ + #define FSL_FEATURE_SOC_SYSMPU_COUNT (1) + /* @brief OSC availability on the SoC. */ + #define FSL_FEATURE_SOC_OSC_COUNT (1) + /* @brief PDB availability on the SoC. */ + #define FSL_FEATURE_SOC_PDB_COUNT (1) + /* @brief PIT availability on the SoC. */ + #define FSL_FEATURE_SOC_PIT_COUNT (1) + /* @brief PMC availability on the SoC. */ + #define FSL_FEATURE_SOC_PMC_COUNT (1) + /* @brief PORT availability on the SoC. */ + #define FSL_FEATURE_SOC_PORT_COUNT (5) + /* @brief RCM availability on the SoC. */ + #define FSL_FEATURE_SOC_RCM_COUNT (1) + /* @brief RFSYS availability on the SoC. */ + #define FSL_FEATURE_SOC_RFSYS_COUNT (1) + /* @brief RFVBAT availability on the SoC. */ + #define FSL_FEATURE_SOC_RFVBAT_COUNT (1) + /* @brief RNG availability on the SoC. */ + #define FSL_FEATURE_SOC_RNG_COUNT (1) + /* @brief RTC availability on the SoC. */ + #define FSL_FEATURE_SOC_RTC_COUNT (1) + /* @brief SDHC availability on the SoC. */ + #define FSL_FEATURE_SOC_SDHC_COUNT (1) + /* @brief SIM availability on the SoC. */ + #define FSL_FEATURE_SOC_SIM_COUNT (1) + /* @brief SMC availability on the SoC. */ + #define FSL_FEATURE_SOC_SMC_COUNT (1) + /* @brief UART availability on the SoC. */ + #define FSL_FEATURE_SOC_UART_COUNT (5) + /* @brief USB availability on the SoC. */ + #define FSL_FEATURE_SOC_USB_COUNT (1) + /* @brief USBDCD availability on the SoC. */ + #define FSL_FEATURE_SOC_USBDCD_COUNT (1) + /* @brief VREF availability on the SoC. */ + #define FSL_FEATURE_SOC_VREF_COUNT (1) + /* @brief WDOG availability on the SoC. */ + #define FSL_FEATURE_SOC_WDOG_COUNT (1) +#endif + +/* ADC16 module features */ + +/* @brief Has Programmable Gain Amplifier (PGA) in ADC (register PGA). */ +#define FSL_FEATURE_ADC16_HAS_PGA (0) +/* @brief Has PGA chopping control in ADC (bit PGA[PGACHPb] or PGA[PGACHP]). */ +#define FSL_FEATURE_ADC16_HAS_PGA_CHOPPING (0) +/* @brief Has PGA offset measurement mode in ADC (bit PGA[PGAOFSM]). */ +#define FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT (0) +/* @brief Has DMA support (bit SC2[DMAEN] or SC4[DMAEN]). */ +#define FSL_FEATURE_ADC16_HAS_DMA (1) +/* @brief Has differential mode (bitfield SC1x[DIFF]). */ +#define FSL_FEATURE_ADC16_HAS_DIFF_MODE (1) +/* @brief Has FIFO (bit SC4[AFDEP]). */ +#define FSL_FEATURE_ADC16_HAS_FIFO (0) +/* @brief FIFO size if available (bitfield SC4[AFDEP]). */ +#define FSL_FEATURE_ADC16_FIFO_SIZE (0) +/* @brief Has channel set a/b multiplexor (bitfield CFG2[MUXSEL]). */ +#define FSL_FEATURE_ADC16_HAS_MUX_SELECT (1) +/* @brief Has HW trigger masking (bitfield SC5[HTRGMASKE]. */ +#define FSL_FEATURE_ADC16_HAS_HW_TRIGGER_MASK (0) +/* @brief Has calibration feature (bit SC3[CAL] and registers CLPx, CLMx). */ +#define FSL_FEATURE_ADC16_HAS_CALIBRATION (1) +/* @brief Has HW averaging (bit SC3[AVGE]). */ +#define FSL_FEATURE_ADC16_HAS_HW_AVERAGE (1) +/* @brief Has offset correction (register OFS). */ +#define FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION (1) +/* @brief Maximum ADC resolution. */ +#define FSL_FEATURE_ADC16_MAX_RESOLUTION (16) +/* @brief Number of SC1x and Rx register pairs (conversion control and result registers). */ +#define FSL_FEATURE_ADC16_CONVERSION_CONTROL_COUNT (2) + +/* FLEXCAN module features */ + +/* @brief Message buffer size */ +#define FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(x) (16) +/* @brief Has doze mode support (register bit field MCR[DOZE]). */ +#define FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT (0) +/* @brief Insatnce has doze mode support (register bit field MCR[DOZE]). */ +#define FSL_FEATURE_FLEXCAN_INSTANCE_HAS_DOZE_MODE_SUPPORTn(x) (0) +/* @brief Has a glitch filter on the receive pin (register bit field MCR[WAKSRC]). */ +#define FSL_FEATURE_FLEXCAN_HAS_GLITCH_FILTER (1) +/* @brief Has extended interrupt mask and flag register (register IMASK2, IFLAG2). */ +#define FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER (0) +/* @brief Instance has extended bit timing register (register CBT). */ +#define FSL_FEATURE_FLEXCAN_INSTANCE_HAS_EXTENDED_TIMING_REGISTERn(x) (0) +/* @brief Has a receive FIFO DMA feature (register bit field MCR[DMA]). */ +#define FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA (0) +/* @brief Instance has a receive FIFO DMA feature (register bit field MCR[DMA]). */ +#define FSL_FEATURE_FLEXCAN_INSTANCE_HAS_RX_FIFO_DMAn(x) (0) +/* @brief Has separate message buffer 0 interrupt flag (register bit field IFLAG1[BUF0I]). */ +#define FSL_FEATURE_FLEXCAN_HAS_SEPARATE_BUFFER_0_FLAG (1) +/* @brief Has bitfield name BUF31TO0M. */ +#define FSL_FEATURE_FLEXCAN_HAS_BUF31TO0M (0) +/* @brief Number of interrupt vectors. */ +#define FSL_FEATURE_FLEXCAN_INTERRUPT_COUNT (6) +/* @brief Is affected by errata with ID 5641 (Module does not transmit a message that is enabled to be transmitted at a specific moment during the arbitration process). */ +#define FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641 (0) + +/* CMP module features */ + +/* @brief Has Trigger mode in CMP (register bit field CR1[TRIGM]). */ +#define FSL_FEATURE_CMP_HAS_TRIGGER_MODE (0) +/* @brief Has Window mode in CMP (register bit field CR1[WE]). */ +#define FSL_FEATURE_CMP_HAS_WINDOW_MODE (1) +/* @brief Has External sample supported in CMP (register bit field CR1[SE]). */ +#define FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT (1) +/* @brief Has DMA support in CMP (register bit field SCR[DMAEN]). */ +#define FSL_FEATURE_CMP_HAS_DMA (1) +/* @brief Has Pass Through mode in CMP (register bit field MUXCR[PSTM]). */ +#define FSL_FEATURE_CMP_HAS_PASS_THROUGH_MODE (1) +/* @brief Has DAC Test function in CMP (register DACTEST). */ +#define FSL_FEATURE_CMP_HAS_DAC_TEST (0) + +/* CRC module features */ + +/* @brief Has data register with name CRC */ +#define FSL_FEATURE_CRC_HAS_CRC_REG (0) + +/* DAC module features */ + +/* @brief Define the size of hardware buffer */ +#define FSL_FEATURE_DAC_BUFFER_SIZE (16) +/* @brief Define whether the buffer supports watermark event detection or not. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION (1) +/* @brief Define whether the buffer supports watermark selection detection or not. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION (1) +/* @brief Define whether the buffer supports watermark event 1 word before buffer upper limit. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD (1) +/* @brief Define whether the buffer supports watermark event 2 words before buffer upper limit. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_2_WORDS (1) +/* @brief Define whether the buffer supports watermark event 3 words before buffer upper limit. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_3_WORDS (1) +/* @brief Define whether the buffer supports watermark event 4 words before buffer upper limit. */ +#define FSL_FEATURE_DAC_HAS_WATERMARK_4_WORDS (1) +/* @brief Define whether FIFO buffer mode is available or not. */ +#define FSL_FEATURE_DAC_HAS_BUFFER_FIFO_MODE (0) +/* @brief Define whether swing buffer mode is available or not.. */ +#define FSL_FEATURE_DAC_HAS_BUFFER_SWING_MODE (1) + +/* EDMA module features */ + +/* @brief Number of DMA channels (related to number of registers TCD, DCHPRI, bit fields ERQ[ERQn], EEI[EEIn], INT[INTn], ERR[ERRn], HRS[HRSn] and bit field widths ES[ERRCHN], CEEI[CEEI], SEEI[SEEI], CERQ[CERQ], SERQ[SERQ], CDNE[CDNE], SSRT[SSRT], CERR[CERR], CINT[CINT], TCDn_CITER_ELINKYES[LINKCH], TCDn_CSR[MAJORLINKCH], TCDn_BITER_ELINKYES[LINKCH]). (Valid only for eDMA modules.) */ +#define FSL_FEATURE_EDMA_MODULE_CHANNEL (16) +/* @brief Total number of DMA channels on all modules. */ +#define FSL_FEATURE_EDMA_DMAMUX_CHANNELS (FSL_FEATURE_SOC_EDMA_COUNT * 16) +/* @brief Number of DMA channel groups (register bit fields CR[ERGA], CR[GRPnPRI], ES[GPE], DCHPRIn[GRPPRI]). (Valid only for eDMA modules.) */ +#define FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT (1) +/* @brief Has DMA_Error interrupt vector. */ +#define FSL_FEATURE_EDMA_HAS_ERROR_IRQ (1) +/* @brief Number of DMA channels with asynchronous request capability (register EARS). (Valid only for eDMA modules.) */ +#define FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT (0) + +/* DMAMUX module features */ + +/* @brief Number of DMA channels (related to number of register CHCFGn). */ +#define FSL_FEATURE_DMAMUX_MODULE_CHANNEL (16) +/* @brief Total number of DMA channels on all modules. */ +#define FSL_FEATURE_DMAMUX_DMAMUX_CHANNELS (FSL_FEATURE_SOC_DMAMUX_COUNT * 16) +/* @brief Has the periodic trigger capability for the triggered DMA channel (register bit CHCFG0[TRIG]). */ +#define FSL_FEATURE_DMAMUX_HAS_TRIG (1) + +/* ENET module features */ + +/* @brief Has buffer descriptor byte swapping (register bit field ECR[DBSWP]). */ +#define FSL_FEATURE_ENET_DMA_BIG_ENDIAN_ONLY (0) +/* @brief Has precision time protocol (IEEE 1588) support (register bit field ECR[EN1588], registers ATCR, ATVR, ATOFF, ATPER, ATCOR, ATINC, ATSTMP). */ +#define FSL_FEATURE_ENET_SUPPORT_PTP (1) +/* @brief Number of associated interrupt vectors. */ +#define FSL_FEATURE_ENET_INTERRUPT_COUNT (4) +/* @brief Has threshold for the number of frames in the receive FIFO (register bit field RSEM[STAT_SECTION_EMPTY]). */ +#define FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD (1) + +/* EWM module features */ + +/* @brief Has clock select (register CLKCTRL). */ +#define FSL_FEATURE_EWM_HAS_CLOCK_SELECT (0) +/* @brief Has clock prescaler (register CLKPRESCALER). */ +#define FSL_FEATURE_EWM_HAS_PRESCALER (0) + +/* FLEXBUS module features */ + +/* No feature definitions */ + +/* FLASH module features */ + +#if defined(CPU_MK64FN1M0CAJ12) || defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLL12) || defined(CPU_MK64FN1M0VLQ12) || \ + defined(CPU_MK64FN1M0VMD12) + /* @brief Is of type FTFA. */ + #define FSL_FEATURE_FLASH_IS_FTFA (0) + /* @brief Is of type FTFE. */ + #define FSL_FEATURE_FLASH_IS_FTFE (1) + /* @brief Is of type FTFL. */ + #define FSL_FEATURE_FLASH_IS_FTFL (0) + /* @brief Has flags indicating the status of the FlexRAM (register bits FCNFG[EEERDY], FCNFG[RAMRDY] and FCNFG[PFLSH]). */ + #define FSL_FEATURE_FLASH_HAS_FLEX_RAM_FLAGS (1) + /* @brief Has program flash swapping status flag (register bit FCNFG[SWAP]). */ + #define FSL_FEATURE_FLASH_HAS_PFLASH_SWAPPING_STATUS_FLAG (1) + /* @brief Has EEPROM region protection (register FEPROT). */ + #define FSL_FEATURE_FLASH_HAS_EEROM_REGION_PROTECTION (1) + /* @brief Has data flash region protection (register FDPROT). */ + #define FSL_FEATURE_FLASH_HAS_DATA_FLASH_REGION_PROTECTION (1) + /* @brief Has flash access control (registers XACCHn, SACCHn, where n is a number, FACSS and FACSN). */ + #define FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL (0) + /* @brief Has flash cache control in FMC module. */ + #define FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS (1) + /* @brief Has flash cache control in MCM module. */ + #define FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS (0) + /* @brief Has flash cache control in MSCM module. */ + #define FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS (0) + /* @brief Has prefetch speculation control in flash, such as kv5x. */ + #define FSL_FEATURE_FLASH_PREFETCH_SPECULATION_CONTROL_IN_FLASH (0) + /* @brief P-Flash flash size coding rule version, value 0 for K1 and K2, value 1 for K3. */ + #define FSL_FEATURE_FLASH_SIZE_ENCODING_RULE_VERSION (0) + /* @brief P-Flash start address. */ + #define FSL_FEATURE_FLASH_PFLASH_START_ADDRESS (0x00000000) + /* @brief P-Flash block count. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT (2) + /* @brief P-Flash block size. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE (524288) + /* @brief P-Flash sector size. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE (4096) + /* @brief P-Flash write unit size. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE (8) + /* @brief P-Flash data path width. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_DATA_PATH_WIDTH (16) + /* @brief P-Flash block swap feature. */ + #define FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP (1) + /* @brief P-Flash protection region count. */ + #define FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT (32) + /* @brief Has FlexNVM memory. */ + #define FSL_FEATURE_FLASH_HAS_FLEX_NVM (0) + /* @brief FlexNVM start address. (Valid only if FlexNVM is available.) */ + #define FSL_FEATURE_FLASH_FLEX_NVM_START_ADDRESS (0x00000000) + /* @brief FlexNVM block count. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_COUNT (0) + /* @brief FlexNVM block size. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SIZE (0) + /* @brief FlexNVM sector size. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SECTOR_SIZE (0) + /* @brief FlexNVM write unit size. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_WRITE_UNIT_SIZE (0) + /* @brief FlexNVM data path width. */ + #define FSL_FEATURE_FLASH_FLEX_BLOCK_DATA_PATH_WIDTH (0) + /* @brief Has FlexRAM memory. */ + #define FSL_FEATURE_FLASH_HAS_FLEX_RAM (1) + /* @brief FlexRAM start address. (Valid only if FlexRAM is available.) */ + #define FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS (0x14000000) + /* @brief FlexRAM size. */ + #define FSL_FEATURE_FLASH_FLEX_RAM_SIZE (4096) + /* @brief Has 0x00 Read 1s Block command. */ + #define FSL_FEATURE_FLASH_HAS_READ_1S_BLOCK_CMD (1) + /* @brief Has 0x01 Read 1s Section command. */ + #define FSL_FEATURE_FLASH_HAS_READ_1S_SECTION_CMD (1) + /* @brief Has 0x02 Program Check command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_CHECK_CMD (1) + /* @brief Has 0x03 Read Resource command. */ + #define FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD (1) + /* @brief Has 0x06 Program Longword command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_LONGWORD_CMD (0) + /* @brief Has 0x07 Program Phrase command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_PHRASE_CMD (1) + /* @brief Has 0x08 Erase Flash Block command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_FLASH_BLOCK_CMD (1) + /* @brief Has 0x09 Erase Flash Sector command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_FLASH_SECTOR_CMD (1) + /* @brief Has 0x0B Program Section command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD (1) + /* @brief Has 0x40 Read 1s All Blocks command. */ + #define FSL_FEATURE_FLASH_HAS_READ_1S_ALL_BLOCKS_CMD (1) + /* @brief Has 0x41 Read Once command. */ + #define FSL_FEATURE_FLASH_HAS_READ_ONCE_CMD (1) + /* @brief Has 0x43 Program Once command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_ONCE_CMD (1) + /* @brief Has 0x44 Erase All Blocks command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_CMD (1) + /* @brief Has 0x45 Verify Backdoor Access Key command. */ + #define FSL_FEATURE_FLASH_HAS_VERIFY_BACKDOOR_ACCESS_KEY_CMD (1) + /* @brief Has 0x46 Swap Control command. */ + #define FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD (1) + /* @brief Has 0x49 Erase All Blocks Unsecure command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD (0) + /* @brief Has 0x4A Read 1s All Execute-only Segments command. */ + #define FSL_FEATURE_FLASH_HAS_READ_1S_ALL_EXECUTE_ONLY_SEGMENTS_CMD (0) + /* @brief Has 0x4B Erase All Execute-only Segments command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_ALL_EXECUTE_ONLY_SEGMENTS_CMD (0) + /* @brief Has 0x80 Program Partition command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD (0) + /* @brief Has 0x81 Set FlexRAM Function command. */ + #define FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD (0) + /* @brief P-Flash Erase/Read 1st all block command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_CMD_ADDRESS_ALIGMENT (16) + /* @brief P-Flash Erase sector command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT (16) + /* @brief P-Flash Rrogram/Verify section command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT (16) + /* @brief P-Flash Read resource command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_RESOURCE_CMD_ADDRESS_ALIGMENT (8) + /* @brief P-Flash Program check command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_CHECK_CMD_ADDRESS_ALIGMENT (4) + /* @brief P-Flash Program check command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_SWAP_CONTROL_CMD_ADDRESS_ALIGMENT (16) + /* @brief FlexNVM Erase/Read 1st all block command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM Erase sector command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_SECTOR_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM Rrogram/Verify section command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_SECTION_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM Read resource command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_RESOURCE_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM Program check command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_CHECK_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM partition code 0000 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0001 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0010 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0011 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0100 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0101 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0110 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0111 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1000 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1001 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1010 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1011 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1100 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1101 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1110 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1111 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111 (0xFFFFFFFF) + /* @brief Emulated eeprom size code 0000 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0000 (0xFFFF) + /* @brief Emulated eeprom size code 0001 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0001 (0xFFFF) + /* @brief Emulated eeprom size code 0010 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0010 (0x1000) + /* @brief Emulated eeprom size code 0011 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0011 (0x0800) + /* @brief Emulated eeprom size code 0100 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0100 (0x0400) + /* @brief Emulated eeprom size code 0101 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0101 (0x0200) + /* @brief Emulated eeprom size code 0110 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0110 (0x0100) + /* @brief Emulated eeprom size code 0111 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0111 (0x0080) + /* @brief Emulated eeprom size code 1000 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1000 (0x0040) + /* @brief Emulated eeprom size code 1001 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1001 (0x0020) + /* @brief Emulated eeprom size code 1010 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1010 (0xFFFF) + /* @brief Emulated eeprom size code 1011 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1011 (0xFFFF) + /* @brief Emulated eeprom size code 1100 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1100 (0xFFFF) + /* @brief Emulated eeprom size code 1101 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1101 (0xFFFF) + /* @brief Emulated eeprom size code 1110 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1110 (0xFFFF) + /* @brief Emulated eeprom size code 1111 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1111 (0x0000) +#elif defined(CPU_MK64FX512VDC12) || defined(CPU_MK64FX512VLL12) || defined(CPU_MK64FX512VLQ12) || defined(CPU_MK64FX512VMD12) + /* @brief Is of type FTFA. */ + #define FSL_FEATURE_FLASH_IS_FTFA (0) + /* @brief Is of type FTFE. */ + #define FSL_FEATURE_FLASH_IS_FTFE (1) + /* @brief Is of type FTFL. */ + #define FSL_FEATURE_FLASH_IS_FTFL (0) + /* @brief Has flags indicating the status of the FlexRAM (register bits FCNFG[EEERDY], FCNFG[RAMRDY] and FCNFG[PFLSH]). */ + #define FSL_FEATURE_FLASH_HAS_FLEX_RAM_FLAGS (1) + /* @brief Has program flash swapping status flag (register bit FCNFG[SWAP]). */ + #define FSL_FEATURE_FLASH_HAS_PFLASH_SWAPPING_STATUS_FLAG (1) + /* @brief Has EEPROM region protection (register FEPROT). */ + #define FSL_FEATURE_FLASH_HAS_EEROM_REGION_PROTECTION (1) + /* @brief Has data flash region protection (register FDPROT). */ + #define FSL_FEATURE_FLASH_HAS_DATA_FLASH_REGION_PROTECTION (1) + /* @brief Has flash access control (registers XACCHn, SACCHn, where n is a number, FACSS and FACSN). */ + #define FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL (0) + /* @brief Has flash cache control in FMC module. */ + #define FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS (1) + /* @brief Has flash cache control in MCM module. */ + #define FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS (0) + /* @brief Has flash cache control in MSCM module. */ + #define FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS (0) + /* @brief Has prefetch speculation control in flash, such as kv5x. */ + #define FSL_FEATURE_FLASH_PREFETCH_SPECULATION_CONTROL_IN_FLASH (0) + /* @brief P-Flash flash size coding rule version, value 0 for K1 and K2, value 1 for K3. */ + #define FSL_FEATURE_FLASH_SIZE_ENCODING_RULE_VERSION (0) + /* @brief P-Flash start address. */ + #define FSL_FEATURE_FLASH_PFLASH_START_ADDRESS (0x00000000) + /* @brief P-Flash block count. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT (1) + /* @brief P-Flash block size. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE (524288) + /* @brief P-Flash sector size. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE (4096) + /* @brief P-Flash write unit size. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE (8) + /* @brief P-Flash data path width. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_DATA_PATH_WIDTH (16) + /* @brief P-Flash block swap feature. */ + #define FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP (0) + /* @brief P-Flash protection region count. */ + #define FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT (32) + /* @brief Has FlexNVM memory. */ + #define FSL_FEATURE_FLASH_HAS_FLEX_NVM (1) + /* @brief FlexNVM start address. (Valid only if FlexNVM is available.) */ + #define FSL_FEATURE_FLASH_FLEX_NVM_START_ADDRESS (0x10000000) + /* @brief FlexNVM block count. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_COUNT (1) + /* @brief FlexNVM block size. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SIZE (131072) + /* @brief FlexNVM sector size. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SECTOR_SIZE (4096) + /* @brief FlexNVM write unit size. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_WRITE_UNIT_SIZE (8) + /* @brief FlexNVM data path width. */ + #define FSL_FEATURE_FLASH_FLEX_BLOCK_DATA_PATH_WIDTH (16) + /* @brief Has FlexRAM memory. */ + #define FSL_FEATURE_FLASH_HAS_FLEX_RAM (1) + /* @brief FlexRAM start address. (Valid only if FlexRAM is available.) */ + #define FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS (0x14000000) + /* @brief FlexRAM size. */ + #define FSL_FEATURE_FLASH_FLEX_RAM_SIZE (4096) + /* @brief Has 0x00 Read 1s Block command. */ + #define FSL_FEATURE_FLASH_HAS_READ_1S_BLOCK_CMD (1) + /* @brief Has 0x01 Read 1s Section command. */ + #define FSL_FEATURE_FLASH_HAS_READ_1S_SECTION_CMD (1) + /* @brief Has 0x02 Program Check command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_CHECK_CMD (1) + /* @brief Has 0x03 Read Resource command. */ + #define FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD (1) + /* @brief Has 0x06 Program Longword command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_LONGWORD_CMD (0) + /* @brief Has 0x07 Program Phrase command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_PHRASE_CMD (1) + /* @brief Has 0x08 Erase Flash Block command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_FLASH_BLOCK_CMD (1) + /* @brief Has 0x09 Erase Flash Sector command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_FLASH_SECTOR_CMD (1) + /* @brief Has 0x0B Program Section command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD (1) + /* @brief Has 0x40 Read 1s All Blocks command. */ + #define FSL_FEATURE_FLASH_HAS_READ_1S_ALL_BLOCKS_CMD (1) + /* @brief Has 0x41 Read Once command. */ + #define FSL_FEATURE_FLASH_HAS_READ_ONCE_CMD (1) + /* @brief Has 0x43 Program Once command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_ONCE_CMD (1) + /* @brief Has 0x44 Erase All Blocks command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_CMD (1) + /* @brief Has 0x45 Verify Backdoor Access Key command. */ + #define FSL_FEATURE_FLASH_HAS_VERIFY_BACKDOOR_ACCESS_KEY_CMD (1) + /* @brief Has 0x46 Swap Control command. */ + #define FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD (0) + /* @brief Has 0x49 Erase All Blocks Unsecure command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD (0) + /* @brief Has 0x4A Read 1s All Execute-only Segments command. */ + #define FSL_FEATURE_FLASH_HAS_READ_1S_ALL_EXECUTE_ONLY_SEGMENTS_CMD (0) + /* @brief Has 0x4B Erase All Execute-only Segments command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_ALL_EXECUTE_ONLY_SEGMENTS_CMD (0) + /* @brief Has 0x80 Program Partition command. */ + #define FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD (1) + /* @brief Has 0x81 Set FlexRAM Function command. */ + #define FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD (1) + /* @brief P-Flash Erase/Read 1st all block command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_BLOCK_CMD_ADDRESS_ALIGMENT (16) + /* @brief P-Flash Erase sector command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT (16) + /* @brief P-Flash Rrogram/Verify section command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT (16) + /* @brief P-Flash Read resource command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_RESOURCE_CMD_ADDRESS_ALIGMENT (8) + /* @brief P-Flash Program check command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_CHECK_CMD_ADDRESS_ALIGMENT (4) + /* @brief P-Flash Program check command address alignment. */ + #define FSL_FEATURE_FLASH_PFLASH_SWAP_CONTROL_CMD_ADDRESS_ALIGMENT (0) + /* @brief FlexNVM Erase/Read 1st all block command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_CMD_ADDRESS_ALIGMENT (16) + /* @brief FlexNVM Erase sector command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_SECTOR_CMD_ADDRESS_ALIGMENT (16) + /* @brief FlexNVM Rrogram/Verify section command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_SECTION_CMD_ADDRESS_ALIGMENT (16) + /* @brief FlexNVM Read resource command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_RESOURCE_CMD_ADDRESS_ALIGMENT (8) + /* @brief FlexNVM Program check command address alignment. */ + #define FSL_FEATURE_FLASH_FLEX_NVM_CHECK_CMD_ADDRESS_ALIGMENT (4) + /* @brief FlexNVM partition code 0000 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0000 (0x00020000) + /* @brief FlexNVM partition code 0001 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0001 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0010 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0010 (0x0001C000) + /* @brief FlexNVM partition code 0011 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0011 (0x00018000) + /* @brief FlexNVM partition code 0100 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0100 (0x00010000) + /* @brief FlexNVM partition code 0101 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0101 (0x00000000) + /* @brief FlexNVM partition code 0110 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0110 (0xFFFFFFFF) + /* @brief FlexNVM partition code 0111 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_0111 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1000 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1000 (0x00000000) + /* @brief FlexNVM partition code 1001 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1001 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1010 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1010 (0x00004000) + /* @brief FlexNVM partition code 1011 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1011 (0x00008000) + /* @brief FlexNVM partition code 1100 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1100 (0x00010000) + /* @brief FlexNVM partition code 1101 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1101 (0x00020000) + /* @brief FlexNVM partition code 1110 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1110 (0xFFFFFFFF) + /* @brief FlexNVM partition code 1111 mapping to data flash size in bytes (0xFFFFFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_DFLASH_SIZE_FOR_DEPART_1111 (0x00020000) + /* @brief Emulated eeprom size code 0000 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0000 (0xFFFF) + /* @brief Emulated eeprom size code 0001 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0001 (0xFFFF) + /* @brief Emulated eeprom size code 0010 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0010 (0x1000) + /* @brief Emulated eeprom size code 0011 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0011 (0x0800) + /* @brief Emulated eeprom size code 0100 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0100 (0x0400) + /* @brief Emulated eeprom size code 0101 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0101 (0x0200) + /* @brief Emulated eeprom size code 0110 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0110 (0x0100) + /* @brief Emulated eeprom size code 0111 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_0111 (0x0080) + /* @brief Emulated eeprom size code 1000 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1000 (0x0040) + /* @brief Emulated eeprom size code 1001 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1001 (0x0020) + /* @brief Emulated eeprom size code 1010 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1010 (0xFFFF) + /* @brief Emulated eeprom size code 1011 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1011 (0xFFFF) + /* @brief Emulated eeprom size code 1100 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1100 (0xFFFF) + /* @brief Emulated eeprom size code 1101 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1101 (0xFFFF) + /* @brief Emulated eeprom size code 1110 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1110 (0xFFFF) + /* @brief Emulated eeprom size code 1111 mapping to emulated eeprom size in bytes (0xFFFF = reserved). */ + #define FSL_FEATURE_FLASH_FLEX_NVM_EEPROM_SIZE_FOR_EEESIZE_1111 (0x0000) +#endif /* defined(CPU_MK64FN1M0CAJ12) || defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLL12) || defined(CPU_MK64FN1M0VLQ12) || \ + defined(CPU_MK64FN1M0VMD12) */ + +/* FTM module features */ + +/* @brief Number of channels. */ +#define FSL_FEATURE_FTM_CHANNEL_COUNTn(x) \ + ((x) == FTM0 ? (8) : \ + ((x) == FTM1 ? (2) : \ + ((x) == FTM2 ? (2) : \ + ((x) == FTM3 ? (8) : (-1))))) +/* @brief Has counter reset by the selected input capture event (register bits C0SC[ICRST], C1SC[ICRST], ...). */ +#define FSL_FEATURE_FTM_HAS_COUNTER_RESET_BY_CAPTURE_EVENT (0) +/* @brief Has extended deadtime value. */ +#define FSL_FEATURE_FTM_HAS_EXTENDED_DEADTIME_VALUE (0) +/* @brief Enable pwm output for the module. */ +#define FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT (0) +/* @brief Has half-cycle reload for the module. */ +#define FSL_FEATURE_FTM_HAS_HALFCYCLE_RELOAD (0) +/* @brief Has reload interrupt. */ +#define FSL_FEATURE_FTM_HAS_RELOAD_INTERRUPT (0) +/* @brief Has reload initialization trigger. */ +#define FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER (0) +/* @brief Has DMA support, bitfield CnSC[DMA]. */ +#define FSL_FEATURE_FTM_HAS_DMA_SUPPORT (1) +/* @brief If channel 6 is used to generate channel trigger, bitfield EXTTRIG[CH6TRIG]. */ +#define FSL_FEATURE_FTM_HAS_CHANNEL6_TRIGGER (0) +/* @brief If channel 7 is used to generate channel trigger, bitfield EXTTRIG[CH7TRIG]. */ +#define FSL_FEATURE_FTM_HAS_CHANNEL7_TRIGGER (0) +/* @brief Has no QDCTRL. */ +#define FSL_FEATURE_FTM_HAS_NO_QDCTRL (0) + +/* GPIO module features */ + +/* @brief Has fast (single cycle) access capability via a dedicated memory region. */ +#define FSL_FEATURE_GPIO_HAS_FAST_GPIO (0) +/* @brief Has port input disable register (PIDR). */ +#define FSL_FEATURE_GPIO_HAS_INPUT_DISABLE (0) +/* @brief Has dedicated interrupt vector. */ +#define FSL_FEATURE_GPIO_HAS_PORT_INTERRUPT_VECTOR (1) + +/* I2C module features */ + +/* @brief Has System Management Bus support (registers SMB, A2, SLTL and SLTH). */ +#define FSL_FEATURE_I2C_HAS_SMBUS (1) +/* @brief Maximum supported baud rate in kilobit per second. */ +#define FSL_FEATURE_I2C_MAX_BAUD_KBPS (400) +/* @brief Is affected by errata with ID 6070 (repeat start cannot be generated if the F[MULT] bit field is set to a non-zero value). */ +#define FSL_FEATURE_I2C_HAS_ERRATA_6070 (0) +/* @brief Has DMA support (register bit C1[DMAEN]). */ +#define FSL_FEATURE_I2C_HAS_DMA_SUPPORT (1) +/* @brief Has I2C bus start and stop detection (register bits FLT[SSIE], FLT[STARTF] and FLT[STOPF]). */ +#define FSL_FEATURE_I2C_HAS_START_STOP_DETECT (1) +/* @brief Has I2C bus stop detection (register bits FLT[STOPIE] and FLT[STOPF]). */ +#define FSL_FEATURE_I2C_HAS_STOP_DETECT (0) +/* @brief Has I2C bus stop hold off (register bit FLT[SHEN]). */ +#define FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF (1) +/* @brief Maximum width of the glitch filter in number of bus clocks. */ +#define FSL_FEATURE_I2C_MAX_GLITCH_FILTER_WIDTH (15) +/* @brief Has control of the drive capability of the I2C pins. */ +#define FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION (1) +/* @brief Has double buffering support (register S2). */ +#define FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING (0) +/* @brief Has double buffer enable. */ +#define FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE (0) + +/* SAI module features */ + +/* @brief Receive/transmit FIFO size in item count (register bit fields TCSR[FRDE], TCSR[FRIE], TCSR[FRF], TCR1[TFW], RCSR[FRDE], RCSR[FRIE], RCSR[FRF], RCR1[RFW], registers TFRn, RFRn). */ +#define FSL_FEATURE_SAI_FIFO_COUNT (8) +/* @brief Receive/transmit channel number (register bit fields TCR3[TCE], RCR3[RCE], registers TDRn and RDRn). */ +#define FSL_FEATURE_SAI_CHANNEL_COUNT (2) +/* @brief Maximum words per frame (register bit fields TCR3[WDFL], TCR4[FRSZ], TMR[TWM], RCR3[WDFL], RCR4[FRSZ], RMR[RWM]). */ +#define FSL_FEATURE_SAI_MAX_WORDS_PER_FRAME (32) +/* @brief Has support of combining multiple data channel FIFOs into single channel FIFO (register bit fields TCR3[CFR], TCR4[FCOMB], TFR0[WCP], TFR1[WCP], RCR3[CFR], RCR4[FCOMB], RFR0[RCP], RFR1[RCP]). */ +#define FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE (0) +/* @brief Has packing of 8-bit and 16-bit data into each 32-bit FIFO word (register bit fields TCR4[FPACK], RCR4[FPACK]). */ +#define FSL_FEATURE_SAI_HAS_FIFO_PACKING (0) +/* @brief Configures when the SAI will continue transmitting after a FIFO error has been detected (register bit fields TCR4[FCONT], RCR4[FCONT]). */ +#define FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR (0) +/* @brief Configures if the frame sync is generated internally, a frame sync is only generated when the FIFO warning flag is clear or continuously (register bit fields TCR4[ONDEM], RCR4[ONDEM]). */ +#define FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE (0) +/* @brief Simplified bit clock source and asynchronous/synchronous mode selection (register bit fields TCR2[CLKMODE], RCR2[CLKMODE]), in comparison with the exclusively implemented TCR2[SYNC,BCS,BCI,MSEL], RCR2[SYNC,BCS,BCI,MSEL]. */ +#define FSL_FEATURE_SAI_HAS_CLOCKING_MODE (0) +/* @brief Has register for configuration of the MCLK divide ratio (register bit fields MDR[FRACT], MDR[DIVIDE]). */ +#define FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER (1) +/* @brief Ihe interrupt source number */ +#define FSL_FEATURE_SAI_INT_SOURCE_NUM (2) +/* @brief Has register of MCR. */ +#define FSL_FEATURE_SAI_HAS_MCR (1) +/* @brief Has register of MDR */ +#define FSL_FEATURE_SAI_HAS_MDR (1) + +/* LLWU module features */ + +/* @brief Maximum number of pins (maximal index plus one) connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN (16) +/* @brief Has pins 8-15 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_EXTERNAL_PIN_GROUP2 (1) +/* @brief Maximum number of internal modules connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE (8) +/* @brief Number of digital filters. */ +#define FSL_FEATURE_LLWU_HAS_PIN_FILTER (2) +/* @brief Has MF register. */ +#define FSL_FEATURE_LLWU_HAS_MF (0) +/* @brief Has PF register. */ +#define FSL_FEATURE_LLWU_HAS_PF (0) +/* @brief Has possibility to enable reset in low leakage power mode and enable digital filter for RESET pin (register LLWU_RST). */ +#define FSL_FEATURE_LLWU_HAS_RESET_ENABLE (1) +/* @brief Has no internal module wakeup flag register. */ +#define FSL_FEATURE_LLWU_HAS_NO_INTERNAL_MODULE_WAKEUP_FLAG_REG (0) +/* @brief Has external pin 0 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN0 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN0_GPIO_IDX (GPIOE_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN0_GPIO_PIN (1) +/* @brief Has external pin 1 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN1 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN1_GPIO_IDX (GPIOE_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN1_GPIO_PIN (2) +/* @brief Has external pin 2 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN2 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN2_GPIO_IDX (GPIOE_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN2_GPIO_PIN (4) +/* @brief Has external pin 3 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN3 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN3_GPIO_IDX (GPIOA_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN3_GPIO_PIN (4) +/* @brief Has external pin 4 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN4 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN4_GPIO_IDX (GPIOA_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN4_GPIO_PIN (13) +/* @brief Has external pin 5 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN5 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN5_GPIO_IDX (GPIOB_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN5_GPIO_PIN (0) +/* @brief Has external pin 6 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN6 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN6_GPIO_IDX (GPIOC_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN6_GPIO_PIN (1) +/* @brief Has external pin 7 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN7 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN7_GPIO_IDX (GPIOC_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN7_GPIO_PIN (3) +/* @brief Has external pin 8 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN8 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN8_GPIO_IDX (GPIOC_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN8_GPIO_PIN (4) +/* @brief Has external pin 9 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN9 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN9_GPIO_IDX (GPIOC_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN9_GPIO_PIN (5) +/* @brief Has external pin 10 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN10 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN10_GPIO_IDX (GPIOC_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN10_GPIO_PIN (6) +/* @brief Has external pin 11 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN11 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN11_GPIO_IDX (GPIOC_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN11_GPIO_PIN (11) +/* @brief Has external pin 12 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN12 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN12_GPIO_IDX (GPIOD_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN12_GPIO_PIN (0) +/* @brief Has external pin 13 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN13 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN13_GPIO_IDX (GPIOD_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN13_GPIO_PIN (2) +/* @brief Has external pin 14 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN14 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN14_GPIO_IDX (GPIOD_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN14_GPIO_PIN (4) +/* @brief Has external pin 15 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN15 (1) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN15_GPIO_IDX (GPIOD_IDX) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN15_GPIO_PIN (6) +/* @brief Has external pin 16 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN16 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN16_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN16_GPIO_PIN (0) +/* @brief Has external pin 17 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN17 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN17_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN17_GPIO_PIN (0) +/* @brief Has external pin 18 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN18 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN18_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN18_GPIO_PIN (0) +/* @brief Has external pin 19 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN19 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN19_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN19_GPIO_PIN (0) +/* @brief Has external pin 20 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN20 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN20_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN20_GPIO_PIN (0) +/* @brief Has external pin 21 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN21 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN21_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN21_GPIO_PIN (0) +/* @brief Has external pin 22 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN22 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN22_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN22_GPIO_PIN (0) +/* @brief Has external pin 23 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN23 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN23_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN23_GPIO_PIN (0) +/* @brief Has external pin 24 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN24 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN24_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN24_GPIO_PIN (0) +/* @brief Has external pin 25 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN25 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN25_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN25_GPIO_PIN (0) +/* @brief Has external pin 26 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN26 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN26_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN26_GPIO_PIN (0) +/* @brief Has external pin 27 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN27 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN27_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN27_GPIO_PIN (0) +/* @brief Has external pin 28 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN28 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN28_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN28_GPIO_PIN (0) +/* @brief Has external pin 29 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN29 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN29_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN29_GPIO_PIN (0) +/* @brief Has external pin 30 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN30 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN30_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN30_GPIO_PIN (0) +/* @brief Has external pin 31 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN31 (0) +/* @brief Index of port of external pin. */ +#define FSL_FEATURE_LLWU_PIN31_GPIO_IDX (0) +/* @brief Number of external pin port on specified port. */ +#define FSL_FEATURE_LLWU_PIN31_GPIO_PIN (0) +/* @brief Has internal module 0 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE0 (1) +/* @brief Has internal module 1 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE1 (1) +/* @brief Has internal module 2 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE2 (1) +/* @brief Has internal module 3 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE3 (1) +/* @brief Has internal module 4 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE4 (0) +/* @brief Has internal module 5 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE5 (1) +/* @brief Has internal module 6 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE6 (0) +/* @brief Has internal module 7 connected to LLWU device. */ +#define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE7 (1) +/* @brief Has Version ID Register (LLWU_VERID). */ +#define FSL_FEATURE_LLWU_HAS_VERID (0) +/* @brief Has Parameter Register (LLWU_PARAM). */ +#define FSL_FEATURE_LLWU_HAS_PARAM (0) +/* @brief Width of registers of the LLWU. */ +#define FSL_FEATURE_LLWU_REG_BITWIDTH (8) +/* @brief Has DMA Enable register (LLWU_DE). */ +#define FSL_FEATURE_LLWU_HAS_DMA_ENABLE_REG (0) + +/* LPTMR module features */ + +/* @brief Has shared interrupt handler with another LPTMR module. */ +#define FSL_FEATURE_LPTMR_HAS_SHARED_IRQ_HANDLER (0) +/* @brief Whether LPTMR counter is 32 bits width. */ +#define FSL_FEATURE_LPTMR_CNR_WIDTH_IS_32B (0) +/* @brief Has timer DMA request enable (register bit CSR[TDRE]). */ +#define FSL_FEATURE_LPTMR_HAS_CSR_TDRE (0) + +/* MCG module features */ + +/* @brief PRDIV base value (divider of register bit field [PRDIV] zero value). */ +#define FSL_FEATURE_MCG_PLL_PRDIV_BASE (1) +/* @brief Maximum PLL external reference divider value (max. value of register bit field C5[PRVDIV]). */ +#define FSL_FEATURE_MCG_PLL_PRDIV_MAX (24) +/* @brief VCO divider base value (multiply factor of register bit field C6[VDIV] zero value). */ +#define FSL_FEATURE_MCG_PLL_VDIV_BASE (24) +/* @brief PLL reference clock low range. OSCCLK/PLL_R. */ +#define FSL_FEATURE_MCG_PLL_REF_MIN (2000000) +/* @brief PLL reference clock high range. OSCCLK/PLL_R. */ +#define FSL_FEATURE_MCG_PLL_REF_MAX (4000000) +/* @brief The PLL clock is divided by 2 before VCO divider. */ +#define FSL_FEATURE_MCG_HAS_PLL_INTERNAL_DIV (0) +/* @brief FRDIV supports 1280. */ +#define FSL_FEATURE_MCG_FRDIV_SUPPORT_1280 (1) +/* @brief FRDIV supports 1536. */ +#define FSL_FEATURE_MCG_FRDIV_SUPPORT_1536 (1) +/* @brief MCGFFCLK divider. */ +#define FSL_FEATURE_MCG_FFCLK_DIV (1) +/* @brief Is PLL clock divided by 2 before MCG PLL/FLL clock selection in the SIM module. */ +#define FSL_FEATURE_MCG_HAS_PLL_EXTRA_DIV (0) +/* @brief Has 32kHz RTC external reference clock (register bits C8[LOCS1], C8[CME1], C8[LOCRE1] and RTC module are present). */ +#define FSL_FEATURE_MCG_HAS_RTC_32K (1) +/* @brief Has PLL1 external reference clock (registers C10, C11, C12, S2). */ +#define FSL_FEATURE_MCG_HAS_PLL1 (0) +/* @brief Has 48MHz internal oscillator. */ +#define FSL_FEATURE_MCG_HAS_IRC_48M (1) +/* @brief Has OSC1 external oscillator (registers C10, C11, C12, S2). */ +#define FSL_FEATURE_MCG_HAS_OSC1 (0) +/* @brief Has fast internal reference clock fine trim (register bit C2[FCFTRIM]). */ +#define FSL_FEATURE_MCG_HAS_FCFTRIM (1) +/* @brief Has PLL loss of lock reset (register bit C8[LOLRE]). */ +#define FSL_FEATURE_MCG_HAS_LOLRE (1) +/* @brief Has MCG OSC clock selection (register bit C7[OSCSEL]). */ +#define FSL_FEATURE_MCG_USE_OSCSEL (1) +/* @brief Has PLL external reference selection (register bits C5[PLLREFSEL0] and C11[PLLREFSEL1]). */ +#define FSL_FEATURE_MCG_USE_PLLREFSEL (0) +/* @brief TBD */ +#define FSL_FEATURE_MCG_USE_SYSTEM_CLOCK (0) +/* @brief Has phase-locked loop (PLL) (register C5 and bits C6[VDIV], C6[PLLS], C6[LOLIE0], S[PLLST], S[LOCK0], S[LOLS0]). */ +#define FSL_FEATURE_MCG_HAS_PLL (1) +/* @brief Has phase-locked loop (PLL) PRDIV (register C5[PRDIV]. */ +#define FSL_FEATURE_MCG_HAS_PLL_PRDIV (1) +/* @brief Has phase-locked loop (PLL) VDIV (register C6[VDIV]. */ +#define FSL_FEATURE_MCG_HAS_PLL_VDIV (1) +/* @brief PLL/OSC related register bit fields have PLL/OSC index in their name. */ +#define FSL_FEATURE_MCG_HAS_PLL_OSC_INDEX (0) +/* @brief Has frequency-locked loop (FLL) (register ATCVH, ATCVL and bits C1[IREFS], C1[FRDIV]). */ +#define FSL_FEATURE_MCG_HAS_FLL (1) +/* @brief Has PLL external to MCG (C9[PLL_CME], C9[PLL_LOCRE], C9[EXT_PLL_LOCS]). */ +#define FSL_FEATURE_MCG_HAS_EXTERNAL_PLL (0) +/* @brief Has crystal oscillator or external reference clock low power controls (register bits C2[HGO], C2[RANGE]). */ +#define FSL_FEATURE_MCG_HAS_EXT_REF_LOW_POWER_CONTROL (1) +/* @brief Has PLL/FLL selection as MCG output (register bit C6[PLLS]). */ +#define FSL_FEATURE_MCG_HAS_PLL_FLL_SELECTION (1) +/* @brief Has PLL output selection (PLL0/PLL1, PLL/external PLL) (register bit C11[PLLCS]). */ +#define FSL_FEATURE_MCG_HAS_PLL_OUTPUT_SELECTION (0) +/* @brief Has automatic trim machine (registers ATCVH, ATCVL and bits SC[ATMF], SC[ATMS], SC[ATME]). */ +#define FSL_FEATURE_MCG_HAS_AUTO_TRIM_MACHINE (1) +/* @brief Has external clock monitor (register bit C6[CME]). */ +#define FSL_FEATURE_MCG_HAS_EXTERNAL_CLOCK_MONITOR (1) +/* @brief Has low frequency internal reference clock (IRC) (registers LTRIMRNG, LFRIM, LSTRIM and bit MC[LIRC_DIV2]). */ +#define FSL_FEATURE_MCG_HAS_LOW_FREQ_IRC (0) +/* @brief Has high frequency internal reference clock (IRC) (registers HCTRIM, HTTRIM, HFTRIM and bit MC[HIRCEN]). */ +#define FSL_FEATURE_MCG_HAS_HIGH_FREQ_IRC (0) +/* @brief Has PEI mode or PBI mode. */ +#define FSL_FEATURE_MCG_HAS_PLL_INTERNAL_MODE (0) +/* @brief Reset clock mode is BLPI. */ +#define FSL_FEATURE_MCG_RESET_IS_BLPI (0) + +/* interrupt module features */ + +/* @brief Lowest interrupt request number. */ +#define FSL_FEATURE_INTERRUPT_IRQ_MIN (-14) +/* @brief Highest interrupt request number. */ +#define FSL_FEATURE_INTERRUPT_IRQ_MAX (85) + +/* OSC module features */ + +/* @brief Has OSC1 external oscillator. */ +#define FSL_FEATURE_OSC_HAS_OSC1 (0) +/* @brief Has OSC0 external oscillator. */ +#define FSL_FEATURE_OSC_HAS_OSC0 (0) +/* @brief Has OSC external oscillator (without index). */ +#define FSL_FEATURE_OSC_HAS_OSC (1) +/* @brief Number of OSC external oscillators. */ +#define FSL_FEATURE_OSC_OSC_COUNT (1) +/* @brief Has external reference clock divider (register bit field DIV[ERPS]). */ +#define FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER (0) + +/* PDB module features */ + +/* @brief Define the count of supporting ADC pre-trigger for each channel. */ +#define FSL_FEATURE_PDB_ADC_PRE_CHANNEL_COUNT (2) +/* @brief Has DAC support. */ +#define FSL_FEATURE_PDB_HAS_DAC (1) +/* @brief Has shared interrupt handler (has not individual interrupt handler for each channel). */ +#define FSL_FEATURE_PDB_HAS_SHARED_IRQ_HANDLER (0) + +/* PIT module features */ + +/* @brief Number of channels (related to number of registers LDVALn, CVALn, TCTRLn, TFLGn). */ +#define FSL_FEATURE_PIT_TIMER_COUNT (4) +/* @brief Has lifetime timer (related to existence of registers LTMR64L and LTMR64H). */ +#define FSL_FEATURE_PIT_HAS_LIFETIME_TIMER (0) +/* @brief Has chain mode (related to existence of register bit field TCTRLn[CHN]). */ +#define FSL_FEATURE_PIT_HAS_CHAIN_MODE (1) +/* @brief Has shared interrupt handler (has not individual interrupt handler for each channel). */ +#define FSL_FEATURE_PIT_HAS_SHARED_IRQ_HANDLER (0) +/* @brief Has timer enable control. */ +#define FSL_FEATURE_PIT_HAS_MDIS (1) + +/* PMC module features */ + +/* @brief Has Bandgap Enable In VLPx Operation support. */ +#define FSL_FEATURE_PMC_HAS_BGEN (1) +/* @brief Has Bandgap Buffer Enable. */ +#define FSL_FEATURE_PMC_HAS_BGBE (1) +/* @brief Has Bandgap Buffer Drive Select. */ +#define FSL_FEATURE_PMC_HAS_BGBDS (0) +/* @brief Has Low-Voltage Detect Voltage Select support. */ +#define FSL_FEATURE_PMC_HAS_LVDV (1) +/* @brief Has Low-Voltage Warning Voltage Select support. */ +#define FSL_FEATURE_PMC_HAS_LVWV (1) +/* @brief Has LPO. */ +#define FSL_FEATURE_PMC_HAS_LPO (0) +/* @brief Has VLPx option PMC_REGSC[VLPO]. */ +#define FSL_FEATURE_PMC_HAS_VLPO (0) +/* @brief Has acknowledge isolation support. */ +#define FSL_FEATURE_PMC_HAS_ACKISO (1) +/* @brief Has Regulator In Full Performance Mode Status Bit PMC_REGSC[REGFPM]. */ +#define FSL_FEATURE_PMC_HAS_REGFPM (0) +/* @brief Has Regulator In Run Regulation Status Bit PMC_REGSC[REGONS]. */ +#define FSL_FEATURE_PMC_HAS_REGONS (1) +/* @brief Has PMC_HVDSC1. */ +#define FSL_FEATURE_PMC_HAS_HVDSC1 (0) +/* @brief Has PMC_PARAM. */ +#define FSL_FEATURE_PMC_HAS_PARAM (0) +/* @brief Has PMC_VERID. */ +#define FSL_FEATURE_PMC_HAS_VERID (0) + +/* PORT module features */ + +/* @brief Has control lock (register bit PCR[LK]). */ +#define FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK (1) +/* @brief Has open drain control (register bit PCR[ODE]). */ +#define FSL_FEATURE_PORT_HAS_OPEN_DRAIN (1) +/* @brief Has digital filter (registers DFER, DFCR and DFWR). */ +#define FSL_FEATURE_PORT_HAS_DIGITAL_FILTER (1) +/* @brief Has DMA request (register bit field PCR[IRQC] values). */ +#define FSL_FEATURE_PORT_HAS_DMA_REQUEST (1) +/* @brief Has pull resistor selection available. */ +#define FSL_FEATURE_PORT_HAS_PULL_SELECTION (1) +/* @brief Has pull resistor enable (register bit PCR[PE]). */ +#define FSL_FEATURE_PORT_HAS_PULL_ENABLE (1) +/* @brief Has slew rate control (register bit PCR[SRE]). */ +#define FSL_FEATURE_PORT_HAS_SLEW_RATE (1) +/* @brief Has passive filter (register bit field PCR[PFE]). */ +#define FSL_FEATURE_PORT_HAS_PASSIVE_FILTER (1) +/* @brief Has drive strength control (register bit PCR[DSE]). */ +#define FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH (1) +/* @brief Has separate drive strength register (HDRVE). */ +#define FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH_REGISTER (0) +/* @brief Has glitch filter (register IOFLT). */ +#define FSL_FEATURE_PORT_HAS_GLITCH_FILTER (0) +/* @brief Defines width of PCR[MUX] field. */ +#define FSL_FEATURE_PORT_PCR_MUX_WIDTH (3) +/* @brief Has dedicated interrupt vector. */ +#define FSL_FEATURE_PORT_HAS_INTERRUPT_VECTOR (1) +/* @brief Has multiple pin IRQ configuration (register GICLR and GICHR). */ +#define FSL_FEATURE_PORT_HAS_MULTIPLE_IRQ_CONFIG (0) +/* @brief Defines whether PCR[IRQC] bit-field has flag states. */ +#define FSL_FEATURE_PORT_HAS_IRQC_FLAG (0) +/* @brief Defines whether PCR[IRQC] bit-field has trigger states. */ +#define FSL_FEATURE_PORT_HAS_IRQC_TRIGGER (0) + +/* RCM module features */ + +/* @brief Has Loss-of-Lock Reset support. */ +#define FSL_FEATURE_RCM_HAS_LOL (1) +/* @brief Has Loss-of-Clock Reset support. */ +#define FSL_FEATURE_RCM_HAS_LOC (1) +/* @brief Has JTAG generated Reset support. */ +#define FSL_FEATURE_RCM_HAS_JTAG (1) +/* @brief Has EzPort generated Reset support. */ +#define FSL_FEATURE_RCM_HAS_EZPORT (1) +/* @brief Has bit-field indicating EZP_MS_B pin state during last reset. */ +#define FSL_FEATURE_RCM_HAS_EZPMS (1) +/* @brief Has boot ROM configuration, MR[BOOTROM], FM[FORCEROM] */ +#define FSL_FEATURE_RCM_HAS_BOOTROM (0) +/* @brief Has sticky system reset status register RCM_SSRS0 and RCM_SSRS1. */ +#define FSL_FEATURE_RCM_HAS_SSRS (0) +/* @brief Has Version ID Register (RCM_VERID). */ +#define FSL_FEATURE_RCM_HAS_VERID (0) +/* @brief Has Parameter Register (RCM_PARAM). */ +#define FSL_FEATURE_RCM_HAS_PARAM (0) +/* @brief Has Reset Interrupt Enable Register RCM_SRIE. */ +#define FSL_FEATURE_RCM_HAS_SRIE (0) +/* @brief Width of registers of the RCM. */ +#define FSL_FEATURE_RCM_REG_WIDTH (8) +/* @brief Has Core 1 generated Reset support RCM_SRS[CORE1] */ +#define FSL_FEATURE_RCM_HAS_CORE1 (0) +/* @brief Has MDM-AP system reset support RCM_SRS1[MDM_AP] */ +#define FSL_FEATURE_RCM_HAS_MDM_AP (1) +/* @brief Has wakeup reset feature. Register bit SRS[WAKEUP]. */ +#define FSL_FEATURE_RCM_HAS_WAKEUP (1) + +/* RTC module features */ + +#if defined(CPU_MK64FN1M0CAJ12) || defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLL12) || defined(CPU_MK64FN1M0VLQ12) || \ + defined(CPU_MK64FX512VDC12) || defined(CPU_MK64FX512VLL12) || defined(CPU_MK64FX512VLQ12) + /* @brief Has wakeup pin. */ + #define FSL_FEATURE_RTC_HAS_WAKEUP_PIN (1) + /* @brief Has wakeup pin selection (bit field CR[WPS]). */ + #define FSL_FEATURE_RTC_HAS_WAKEUP_PIN_SELECTION (1) + /* @brief Has low power features (registers MER, MCLR and MCHR). */ + #define FSL_FEATURE_RTC_HAS_MONOTONIC (0) + /* @brief Has read/write access control (registers WAR and RAR). */ + #define FSL_FEATURE_RTC_HAS_ACCESS_CONTROL (1) + /* @brief Has security features (registers TTSR, MER, MCLR and MCHR). */ + #define FSL_FEATURE_RTC_HAS_SECURITY (1) + /* @brief Has RTC_CLKIN available. */ + #define FSL_FEATURE_RTC_HAS_RTC_CLKIN (0) + /* @brief Has prescaler adjust for LPO. */ + #define FSL_FEATURE_RTC_HAS_LPO_ADJUST (0) + /* @brief Has Clock Pin Enable field. */ + #define FSL_FEATURE_RTC_HAS_CPE (0) + /* @brief Has Timer Seconds Interrupt Configuration field. */ + #define FSL_FEATURE_RTC_HAS_TSIC (0) + /* @brief Has OSC capacitor setting RTC_CR[SC2P ~ SC16P] */ + #define FSL_FEATURE_RTC_HAS_OSC_SCXP (1) + /* @brief Has Tamper Interrupt Register (register TIR). */ + #define FSL_FEATURE_RTC_HAS_TIR (0) + /* @brief Has Tamper Pin Interrupt Enable (bitfield TIR[TPIE]). */ + #define FSL_FEATURE_RTC_HAS_TIR_TPIE (0) + /* @brief Has Security Interrupt Enable (bitfield TIR[SIE]). */ + #define FSL_FEATURE_RTC_HAS_TIR_SIE (0) + /* @brief Has Loss of Clock Interrupt Enable (bitfield TIR[LCIE]). */ + #define FSL_FEATURE_RTC_HAS_TIR_LCIE (0) + /* @brief Has Tamper Interrupt Detect Flag (bitfield SR[TIDF]). */ + #define FSL_FEATURE_RTC_HAS_SR_TIDF (0) + /* @brief Has Tamper Detect Register (register TDR). */ + #define FSL_FEATURE_RTC_HAS_TDR (0) + /* @brief Has Tamper Pin Flag (bitfield TDR[TPF]). */ + #define FSL_FEATURE_RTC_HAS_TDR_TPF (0) + /* @brief Has Security Tamper Flag (bitfield TDR[STF]). */ + #define FSL_FEATURE_RTC_HAS_TDR_STF (0) + /* @brief Has Loss of Clock Tamper Flag (bitfield TDR[LCTF]). */ + #define FSL_FEATURE_RTC_HAS_TDR_LCTF (0) + /* @brief Has Tamper Time Seconds Register (register TTSR). */ + #define FSL_FEATURE_RTC_HAS_TTSR (0) + /* @brief Has Pin Configuration Register (register PCR). */ + #define FSL_FEATURE_RTC_HAS_PCR (0) +#elif defined(CPU_MK64FN1M0VMD12) || defined(CPU_MK64FX512VMD12) + /* @brief Has wakeup pin. */ + #define FSL_FEATURE_RTC_HAS_WAKEUP_PIN (1) + /* @brief Has wakeup pin selection (bit field CR[WPS]). */ + #define FSL_FEATURE_RTC_HAS_WAKEUP_PIN_SELECTION (1) + /* @brief Has low power features (registers MER, MCLR and MCHR). */ + #define FSL_FEATURE_RTC_HAS_MONOTONIC (0) + /* @brief Has read/write access control (registers WAR and RAR). */ + #define FSL_FEATURE_RTC_HAS_ACCESS_CONTROL (1) + /* @brief Has security features (registers TTSR, MER, MCLR and MCHR). */ + #define FSL_FEATURE_RTC_HAS_SECURITY (0) + /* @brief Has RTC_CLKIN available. */ + #define FSL_FEATURE_RTC_HAS_RTC_CLKIN (0) + /* @brief Has prescaler adjust for LPO. */ + #define FSL_FEATURE_RTC_HAS_LPO_ADJUST (0) + /* @brief Has Clock Pin Enable field. */ + #define FSL_FEATURE_RTC_HAS_CPE (0) + /* @brief Has Timer Seconds Interrupt Configuration field. */ + #define FSL_FEATURE_RTC_HAS_TSIC (0) + /* @brief Has OSC capacitor setting RTC_CR[SC2P ~ SC16P] */ + #define FSL_FEATURE_RTC_HAS_OSC_SCXP (1) + /* @brief Has Tamper Interrupt Register (register TIR). */ + #define FSL_FEATURE_RTC_HAS_TIR (0) + /* @brief Has Tamper Pin Interrupt Enable (bitfield TIR[TPIE]). */ + #define FSL_FEATURE_RTC_HAS_TIR_TPIE (0) + /* @brief Has Security Interrupt Enable (bitfield TIR[SIE]). */ + #define FSL_FEATURE_RTC_HAS_TIR_SIE (0) + /* @brief Has Loss of Clock Interrupt Enable (bitfield TIR[LCIE]). */ + #define FSL_FEATURE_RTC_HAS_TIR_LCIE (0) + /* @brief Has Tamper Interrupt Detect Flag (bitfield SR[TIDF]). */ + #define FSL_FEATURE_RTC_HAS_SR_TIDF (0) + /* @brief Has Tamper Detect Register (register TDR). */ + #define FSL_FEATURE_RTC_HAS_TDR (0) + /* @brief Has Tamper Pin Flag (bitfield TDR[TPF]). */ + #define FSL_FEATURE_RTC_HAS_TDR_TPF (0) + /* @brief Has Security Tamper Flag (bitfield TDR[STF]). */ + #define FSL_FEATURE_RTC_HAS_TDR_STF (0) + /* @brief Has Loss of Clock Tamper Flag (bitfield TDR[LCTF]). */ + #define FSL_FEATURE_RTC_HAS_TDR_LCTF (0) + /* @brief Has Tamper Time Seconds Register (register TTSR). */ + #define FSL_FEATURE_RTC_HAS_TTSR (0) + /* @brief Has Pin Configuration Register (register PCR). */ + #define FSL_FEATURE_RTC_HAS_PCR (0) +#endif /* defined(CPU_MK64FN1M0CAJ12) || defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLL12) || defined(CPU_MK64FN1M0VLQ12) || \ + defined(CPU_MK64FX512VDC12) || defined(CPU_MK64FX512VLL12) || defined(CPU_MK64FX512VLQ12) */ + +/* SDHC module features */ + +/* @brief Has external DMA support (register bit VENDOR[EXTDMAEN]). */ +#define FSL_FEATURE_SDHC_HAS_EXTERNAL_DMA_SUPPORT (1) +/* @brief Has support of 3.0V voltage (register bit HTCAPBLT[VS30]). */ +#define FSL_FEATURE_SDHC_HAS_V300_SUPPORT (0) +/* @brief Has support of 1.8V voltage (register bit HTCAPBLT[VS18]). */ +#define FSL_FEATURE_SDHC_HAS_V180_SUPPORT (0) + +/* SIM module features */ + +/* @brief Has USB FS divider. */ +#define FSL_FEATURE_SIM_USBFS_USE_SPECIAL_DIVIDER (0) +/* @brief Is PLL clock divided by 2 before MCG PLL/FLL clock selection. */ +#define FSL_FEATURE_SIM_PLLCLK_USE_SPECIAL_DIVIDER (0) +/* @brief Has RAM size specification (register bit field SOPT1[RAMSIZE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_RAMSIZE (1) +/* @brief Has 32k oscillator clock output (register bit SOPT1[OSC32KOUT]). */ +#define FSL_FEATURE_SIM_OPT_HAS_OSC32K_OUT (0) +/* @brief Has 32k oscillator clock selection (register bit field SOPT1[OSC32KSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_OSC32K_SELECTION (1) +/* @brief 32k oscillator clock selection width (width of register bit field SOPT1[OSC32KSEL]). */ +#define FSL_FEATURE_SIM_OPT_OSC32K_SELECTION_WIDTH (2) +/* @brief Has RTC clock output selection (register bit SOPT2[RTCCLKOUTSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_RTC_CLOCK_OUT_SELECTION (1) +/* @brief Has USB voltage regulator (register bits SOPT1[USBVSTBY], SOPT1[USBSSTBY], SOPT1[USBREGEN], SOPT1CFG[URWE], SOPT1CFG[UVSWE], SOPT1CFG[USSWE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR (1) +/* @brief USB has integrated PHY (register bits USBPHYCTL[USBVREGSEL], USBPHYCTL[USBVREGPD], USBPHYCTL[USB3VOUTTRG], USBPHYCTL[USBDISILIM], SOPT2[USBSLSRC], SOPT2[USBREGEN]). */ +#define FSL_FEATURE_SIM_OPT_HAS_USB_PHY (0) +/* @brief Has PTD7 pad drive strength control (register bit SOPT2[PTD7PAD]). */ +#define FSL_FEATURE_SIM_OPT_HAS_PTD7PAD (1) +/* @brief Has FlexBus security level selection (register bit SOPT2[FBSL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FBSL (1) +/* @brief Has number of FlexBus hold cycle before FlexBus can release bus (register bit SOPT6[PCR]). */ +#define FSL_FEATURE_SIM_OPT_HAS_PCR (0) +/* @brief Has number of NFC hold cycle in case of FlexBus request (register bit SOPT6[MCC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_MCC (0) +/* @brief Has UART open drain enable (register bits UARTnODE, where n is a number, in register SOPT5). */ +#define FSL_FEATURE_SIM_OPT_HAS_ODE (0) +/* @brief Number of LPUART modules (number of register bits LPUARTn, where n is a number, in register SCGC5). */ +#define FSL_FEATURE_SIM_OPT_LPUART_COUNT (0) +/* @brief Number of UART modules (number of register bits UARTn, where n is a number, in register SCGC4). */ +#define FSL_FEATURE_SIM_OPT_UART_COUNT (4) +/* @brief Has UART0 open drain enable (register bit SOPT5[UART0ODE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART0_ODE (0) +/* @brief Has UART1 open drain enable (register bit SOPT5[UART1ODE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART1_ODE (0) +/* @brief Has UART2 open drain enable (register bit SOPT5[UART2ODE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART2_ODE (0) +/* @brief Has LPUART0 open drain enable (register bit SOPT5[LPUART0ODE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART0_ODE (0) +/* @brief Has LPUART1 open drain enable (register bit SOPT5[LPUART1ODE]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART1_ODE (0) +/* @brief Has CMT/UART pad drive strength control (register bit SOPT2[CMTUARTPAD]). */ +#define FSL_FEATURE_SIM_OPT_HAS_CMTUARTPAD (0) +/* @brief Has LPUART0 transmit data source selection (register bit SOPT5[LPUART0TXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART0_TX_SRC (0) +/* @brief Has LPUART0 receive data source selection (register bit SOPT5[LPUART0RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART0_RX_SRC (0) +/* @brief Has LPUART1 transmit data source selection (register bit SOPT5[LPUART1TXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART1_TX_SRC (0) +/* @brief Has LPUART1 receive data source selection (register bit SOPT5[LPUART1RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART1_RX_SRC (0) +/* @brief Has UART0 transmit data source selection (register bit SOPT5[UART0TXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART0_TX_SRC (1) +/* @brief UART0 transmit data source selection width (width of register bit SOPT5[UART0TXSRC]). */ +#define FSL_FEATURE_SIM_OPT_UART0_TX_SRC_WIDTH (2) +/* @brief Has UART0 receive data source selection (register bit SOPT5[UART0RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART0_RX_SRC (1) +/* @brief UART0 receive data source selection width (width of register bit SOPT5[UART0RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_UART0_RX_SRC_WIDTH (2) +/* @brief Has UART1 transmit data source selection (register bit SOPT5[UART1TXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART1_TX_SRC (1) +/* @brief Has UART1 receive data source selection (register bit SOPT5[UART1RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART1_RX_SRC (1) +/* @brief UART1 receive data source selection width (width of register bit SOPT5[UART1RXSRC]). */ +#define FSL_FEATURE_SIM_OPT_UART1_RX_SRC_WIDTH (2) +/* @brief Has FTM module(s) configuration. */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM (1) +/* @brief Number of FTM modules. */ +#define FSL_FEATURE_SIM_OPT_FTM_COUNT (4) +/* @brief Number of FTM triggers with selectable source. */ +#define FSL_FEATURE_SIM_OPT_FTM_TRIGGER_COUNT (2) +/* @brief Has FTM0 triggers source selection (register bits SOPT4[FTM0TRGnSRC], where n is a number). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM0_TRIGGER (1) +/* @brief Has FTM3 triggers source selection (register bits SOPT4[FTM3TRGnSRC], where n is a number). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM3_TRIGGER (1) +/* @brief Has FTM1 channel 0 input capture source selection (register bit SOPT4[FTM1CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM1_CHANNELS (1) +/* @brief Has FTM2 channel 0 input capture source selection (register bit SOPT4[FTM2CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM2_CHANNELS (1) +/* @brief Has FTM3 channel 0 input capture source selection (register bit SOPT4[FTM3CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM3_CHANNELS (0) +/* @brief Has FTM2 channel 1 input capture source selection (register bit SOPT4[FTM2CH1SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM2_CHANNEL1 (0) +/* @brief Number of configurable FTM0 fault detection input (number of register bits SOPT4[FTM0FLTn], where n is a number starting from zero). */ +#define FSL_FEATURE_SIM_OPT_FTM0_FAULT_COUNT (3) +/* @brief Number of configurable FTM1 fault detection input (number of register bits SOPT4[FTM1FLTn], where n is a number starting from zero). */ +#define FSL_FEATURE_SIM_OPT_FTM1_FAULT_COUNT (1) +/* @brief Number of configurable FTM2 fault detection input (number of register bits SOPT4[FTM2FLTn], where n is a number starting from zero). */ +#define FSL_FEATURE_SIM_OPT_FTM2_FAULT_COUNT (1) +/* @brief Number of configurable FTM3 fault detection input (number of register bits SOPT4[FTM3FLTn], where n is a number starting from zero). */ +#define FSL_FEATURE_SIM_OPT_FTM3_FAULT_COUNT (1) +/* @brief Has FTM hardware trigger 0 software synchronization (register bit SOPT8[FTMnSYNCBIT], where n is a module instance index). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM_TRIGGER_SYNC (0) +/* @brief Has FTM channels output source selection (register bit SOPT8[FTMxOCHnSRC], where x is a module instance index and n is a channel index). */ +#define FSL_FEATURE_SIM_OPT_HAS_FTM_CHANNELS_OUTPUT_SRC (0) +/* @brief Has TPM module(s) configuration. */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM (0) +/* @brief The highest TPM module index. */ +#define FSL_FEATURE_SIM_OPT_MAX_TPM_INDEX (0) +/* @brief Has TPM module with index 0. */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM0 (0) +/* @brief Has TPM0 clock selection (register bit field SOPT4[TPM0CLKSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM0_CLK_SEL (0) +/* @brief Is TPM channels configuration in the SOPT4 (not SOPT9) register (register bits TPMnCH0SRC, TPMnCLKSEL, where n is a module instance index). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM_CHANNELS_CONFIG_IN_SOPT4_REG (0) +/* @brief Has TPM1 channel 0 input capture source selection (register bit field SOPT4[TPM1CH0SRC] or SOPT9[TPM1CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM1_CH0_SRC_SELECTION (0) +/* @brief Has TPM1 clock selection (register bit field SOPT4[TPM1CLKSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM1_CLK_SEL (0) +/* @brief TPM1 channel 0 input capture source selection width (width of register bit field SOPT4[TPM1CH0SRC] or SOPT9[TPM1CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_TPM1_CH0_SRC_SELECTION_WIDTH (0) +/* @brief Has TPM2 channel 0 input capture source selection (register bit field SOPT4[TPM2CH0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM2_CH0_SRC_SELECTION (0) +/* @brief Has TPM2 clock selection (register bit field SOPT4[TPM2CLKSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPM2_CLK_SEL (0) +/* @brief Has PLL/FLL clock selection (register bit field SOPT2[PLLFLLSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_PLL_FLL_SELECTION (1) +/* @brief PLL/FLL clock selection width (width of register bit field SOPT2[PLLFLLSEL]). */ +#define FSL_FEATURE_SIM_OPT_PLL_FLL_SELECTION_WIDTH (1) +/* @brief Has NFC clock source selection (register bit SOPT2[NFCSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_NFCSRC (0) +/* @brief Has eSDHC clock source selection (register bit SOPT2[ESDHCSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_ESDHCSRC (0) +/* @brief Has SDHC clock source selection (register bit SOPT2[SDHCSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_SDHCSRC (1) +/* @brief Has LCDC clock source selection (register bits SOPT2[LCDCSRC], SOPT2[LCDC_CLKSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LCDCSRC (0) +/* @brief Has ENET timestamp clock source selection (register bit SOPT2[TIMESRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TIMESRC (1) +/* @brief Has ENET RMII clock source selection (register bit SOPT2[RMIISRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_RMIISRC (1) +/* @brief Has USB clock source selection (register bit SOPT2[USBSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_USBSRC (1) +/* @brief Has USB FS clock source selection (register bit SOPT2[USBFSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_USBFSRC (0) +/* @brief Has USB HS clock source selection (register bit SOPT2[USBHSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_USBHSRC (0) +/* @brief Has LPUART clock source selection (register bit SOPT2[LPUARTSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUARTSRC (0) +/* @brief Has LPUART0 clock source selection (register bit SOPT2[LPUART0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART0SRC (0) +/* @brief Has LPUART1 clock source selection (register bit SOPT2[LPUART1SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_LPUART1SRC (0) +/* @brief Has FLEXIOSRC clock source selection (register bit SOPT2[FLEXIOSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_FLEXIOSRC (0) +/* @brief Has UART0 clock source selection (register bit SOPT2[UART0SRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_UART0SRC (0) +/* @brief Has TPM clock source selection (register bit SOPT2[TPMSRC]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TPMSRC (0) +/* @brief Has debug trace clock selection (register bit SOPT2[TRACECLKSEL]). */ +#define FSL_FEATURE_SIM_OPT_HAS_TRACE_CLKSEL (1) +/* @brief Number of ADC modules (register bits SOPT7[ADCnTRGSEL], SOPT7[ADCnPRETRGSEL], SOPT7[ADCnALTTRGSEL], where n is a module instance index). */ +#define FSL_FEATURE_SIM_OPT_ADC_COUNT (2) +/* @brief ADC0 alternate trigger enable width (width of bit field ADC0ALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_ADC0ALTTRGEN_WIDTH (1) +/* @brief ADC1 alternate trigger enable width (width of bit field ADC1ALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_ADC1ALTTRGEN_WIDTH (1) +/* @brief ADC2 alternate trigger enable width (width of bit field ADC2ALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_ADC2ALTTRGEN_WIDTH (0) +/* @brief ADC3 alternate trigger enable width (width of bit field ADC3ALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_ADC3ALTTRGEN_WIDTH (0) +/* @brief HSADC0 converter A alternate trigger enable width (width of bit field HSADC0AALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_HSADC0AALTTRGEN_WIDTH (0) +/* @brief HSADC1 converter A alternate trigger enable width (width of bit field HSADC1AALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_HSADC1AALTTRGEN_WIDTH (0) +/* @brief ADC converter A alternate trigger enable width (width of bit field ADCAALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_ADCAALTTRGEN_WIDTH (0) +/* @brief HSADC0 converter B alternate trigger enable width (width of bit field HSADC0BALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_HSADC0BALTTRGEN_WIDTH (0) +/* @brief HSADC1 converter B alternate trigger enable width (width of bit field HSADC1BALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_HSADC1BALTTRGEN_WIDTH (0) +/* @brief ADC converter B alternate trigger enable width (width of bit field ADCBALTTRGEN of register SOPT7). */ +#define FSL_FEATURE_SIM_OPT_ADCBALTTRGEN_WIDTH (0) +/* @brief Has clock 2 output divider (register bit field CLKDIV1[OUTDIV2]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_OUTDIV2 (1) +/* @brief Has clock 3 output divider (register bit field CLKDIV1[OUTDIV3]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_OUTDIV3 (1) +/* @brief Has clock 4 output divider (register bit field CLKDIV1[OUTDIV4]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_OUTDIV4 (1) +/* @brief Clock 4 output divider width (width of register bit field CLKDIV1[OUTDIV4]). */ +#define FSL_FEATURE_SIM_DIVIDER_OUTDIV4_WIDTH (4) +/* @brief Has clock 5 output divider (register bit field CLKDIV1[OUTDIV5]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_OUTDIV5 (0) +/* @brief Has USB clock divider (register bit field CLKDIV2[USBDIV] and CLKDIV2[USBFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_USBDIV (1) +/* @brief Has USB FS clock divider (register bit field CLKDIV2[USBFSDIV] and CLKDIV2[USBFSFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_USBFSDIV (0) +/* @brief Has USB HS clock divider (register bit field CLKDIV2[USBHSDIV] and CLKDIV2[USBHSFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_USBHSDIV (0) +/* @brief Has PLL/FLL clock divider (register bit field CLKDIV3[PLLFLLDIV] and CLKDIV3[PLLFLLFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_PLLFLLDIV (0) +/* @brief Has LCDC clock divider (register bit field CLKDIV3[LCDCDIV] and CLKDIV3[LCDCFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_LCDCDIV (0) +/* @brief Has trace clock divider (register bit field CLKDIV4[TRACEDIV] and CLKDIV4[TRACEFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_TRACEDIV (0) +/* @brief Has NFC clock divider (register bit field CLKDIV4[NFCDIV] and CLKDIV4[NFCFRAC]). */ +#define FSL_FEATURE_SIM_DIVIDER_HAS_NFCDIV (0) +/* @brief Has Kinetis family ID (register bit field SDID[FAMILYID]). */ +#define FSL_FEATURE_SIM_SDID_HAS_FAMILYID (1) +/* @brief Has Kinetis family ID (register bit field SDID[FAMID]). */ +#define FSL_FEATURE_SIM_SDID_HAS_FAMID (1) +/* @brief Has Kinetis sub-family ID (register bit field SDID[SUBFAMID]). */ +#define FSL_FEATURE_SIM_SDID_HAS_SUBFAMID (1) +/* @brief Has Kinetis series ID (register bit field SDID[SERIESID]). */ +#define FSL_FEATURE_SIM_SDID_HAS_SERIESID (1) +/* @brief Has device die ID (register bit field SDID[DIEID]). */ +#define FSL_FEATURE_SIM_SDID_HAS_DIEID (1) +/* @brief Has system SRAM size specifier (register bit field SDID[SRAMSIZE]). */ +#define FSL_FEATURE_SIM_SDID_HAS_SRAMSIZE (0) +/* @brief Has flash mode (register bit FCFG1[FLASHDOZE]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_FLASHDOZE (1) +/* @brief Has flash disable (register bit FCFG1[FLASHDIS]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_FLASHDIS (1) +/* @brief Has FTFE disable (register bit FCFG1[FTFDIS]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_FTFDIS (0) +/* @brief Has FlexNVM size specifier (register bit field FCFG1[NVMSIZE]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_NVMSIZE (1) +/* @brief Has EEPROM size specifier (register bit field FCFG1[EESIZE]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_EESIZE (1) +/* @brief Has FlexNVM partition (register bit field FCFG1[DEPART]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_DEPART (1) +/* @brief Maximum flash address block 0 address specifier (register bit field FCFG2[MAXADDR0]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_MAXADDR0 (1) +/* @brief Maximum flash address block 1 address specifier (register bit field FCFG2[MAXADDR1]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_MAXADDR1 (1) +/* @brief Maximum flash address block 0 or 1 address specifier (register bit field FCFG2[MAXADDR01]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_MAXADDR01 (0) +/* @brief Maximum flash address block 2 or 3 address specifier (register bit field FCFG2[MAXADDR23]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_MAXADDR23 (0) +/* @brief Has program flash availability specifier (register bit FCFG2[PFLSH]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_PFLSH (1) +/* @brief Has program flash swapping (register bit FCFG2[SWAPPFLSH]). */ +#define FSL_FEATURE_SIM_FCFG_HAS_PFLSH_SWAP (0) +/* @brief Has miscellanious control register (register MCR). */ +#define FSL_FEATURE_SIM_HAS_MISC_CONTROLS (0) +/* @brief Has COP watchdog (registers COPC and SRVCOP). */ +#define FSL_FEATURE_SIM_HAS_COP_WATCHDOG (0) +/* @brief Has COP watchdog stop (register bits COPC[COPSTPEN], COPC[COPDBGEN] and COPC[COPCLKSEL]). */ +#define FSL_FEATURE_SIM_HAS_COP_STOP (0) +/* @brief Has LLWU clock gate bit (e.g SIM_SCGC4). */ +#define FSL_FEATURE_SIM_HAS_SCGC_LLWU (0) + +/* SMC module features */ + +/* @brief Has partial stop option (register bit STOPCTRL[PSTOPO]). */ +#define FSL_FEATURE_SMC_HAS_PSTOPO (0) +/* @brief Has LPO power option (register bit STOPCTRL[LPOPO]). */ +#define FSL_FEATURE_SMC_HAS_LPOPO (0) +/* @brief Has POR power option (register bit STOPCTRL[PORPO] or VLLSCTRL[PORPO]). */ +#define FSL_FEATURE_SMC_HAS_PORPO (1) +/* @brief Has low power wakeup on interrupt (register bit PMCTRL[LPWUI]). */ +#define FSL_FEATURE_SMC_HAS_LPWUI (1) +/* @brief Has LLS or VLLS mode control (register bit STOPCTRL[LLSM]). */ +#define FSL_FEATURE_SMC_HAS_LLS_SUBMODE (0) +/* @brief Has VLLS mode control (register bit VLLSCTRL[VLLSM]). */ +#define FSL_FEATURE_SMC_USE_VLLSCTRL_REG (1) +/* @brief Has VLLS mode control (register bit STOPCTRL[VLLSM]). */ +#define FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM (0) +/* @brief Has RAM partition 2 power option (register bit STOPCTRL[RAM2PO]). */ +#define FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION (0) +/* @brief Has high speed run mode (register bit PMPROT[AHSRUN]). */ +#define FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE (0) +/* @brief Has low leakage stop mode (register bit PMPROT[ALLS]). */ +#define FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE (1) +/* @brief Has very low leakage stop mode (register bit PMPROT[AVLLS]). */ +#define FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE (1) +/* @brief Has stop submode. */ +#define FSL_FEATURE_SMC_HAS_SUB_STOP_MODE (1) +/* @brief Has stop submode 0(VLLS0). */ +#define FSL_FEATURE_SMC_HAS_STOP_SUBMODE0 (1) +/* @brief Has stop submode 1(VLLS1). */ +#define FSL_FEATURE_SMC_HAS_STOP_SUBMODE1 (1) +/* @brief Has stop submode 2(VLLS2). */ +#define FSL_FEATURE_SMC_HAS_STOP_SUBMODE2 (1) +/* @brief Has SMC_PARAM. */ +#define FSL_FEATURE_SMC_HAS_PARAM (0) +/* @brief Has SMC_VERID. */ +#define FSL_FEATURE_SMC_HAS_VERID (0) +/* @brief Has stop abort flag (register bit PMCTRL[STOPA]). */ +#define FSL_FEATURE_SMC_HAS_PMCTRL_STOPA (1) +/* @brief Has tamper reset (register bit SRS[TAMPER]). */ +#define FSL_FEATURE_SMC_HAS_SRS_TAMPER (0) +/* @brief Has security violation reset (register bit SRS[SECVIO]). */ +#define FSL_FEATURE_SMC_HAS_SRS_SECVIO (0) + +/* DSPI module features */ + +/* @brief Receive/transmit FIFO size in number of items. */ +#define FSL_FEATURE_DSPI_FIFO_SIZEn(x) \ + ((x) == SPI0 ? (4) : \ + ((x) == SPI1 ? (1) : \ + ((x) == SPI2 ? (1) : (-1)))) +/* @brief Maximum transfer data width in bits. */ +#define FSL_FEATURE_DSPI_MAX_DATA_WIDTH (16) +/* @brief Maximum number of chip select pins. (Reflects the width of register bit field PUSHR[PCS].) */ +#define FSL_FEATURE_DSPI_MAX_CHIP_SELECT_COUNT (6) +/* @brief Number of chip select pins. */ +#define FSL_FEATURE_DSPI_CHIP_SELECT_COUNT (6) +/* @brief Number of CTAR registers. */ +#define FSL_FEATURE_DSPI_CTAR_COUNT (2) +/* @brief Has chip select strobe capability on the PCS5 pin. */ +#define FSL_FEATURE_DSPI_HAS_CHIP_SELECT_STROBE (1) +/* @brief Has separated TXDATA and CMD FIFOs (register SREX). */ +#define FSL_FEATURE_DSPI_HAS_SEPARATE_TXDATA_CMD_FIFO (0) +/* @brief Has 16-bit data transfer support. */ +#define FSL_FEATURE_DSPI_16BIT_TRANSFERS (1) +/* @brief Has separate DMA RX and TX requests. */ +#define FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(x) \ + ((x) == SPI0 ? (1) : \ + ((x) == SPI1 ? (0) : \ + ((x) == SPI2 ? (0) : (-1)))) + +/* SYSMPU module features */ + +/* @brief Specifies number of descriptors available. */ +#define FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT (12) +/* @brief Has process identifier support. */ +#define FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER (1) +/* @brief Total number of MPU slave. */ +#define FSL_FEATURE_SYSMPU_SLAVE_COUNT (5) +/* @brief Total number of MPU master. */ +#define FSL_FEATURE_SYSMPU_MASTER_COUNT (6) + +/* SysTick module features */ + +/* @brief Systick has external reference clock. */ +#define FSL_FEATURE_SYSTICK_HAS_EXT_REF (0) +/* @brief Systick external reference clock is core clock divided by this value. */ +#define FSL_FEATURE_SYSTICK_EXT_REF_CORE_DIV (0) + +/* UART module features */ + +#if defined(CPU_MK64FN1M0CAJ12) || defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLQ12) || defined(CPU_MK64FN1M0VMD12) || \ + defined(CPU_MK64FX512VDC12) || defined(CPU_MK64FX512VLQ12) || defined(CPU_MK64FX512VMD12) + /* @brief Has receive FIFO overflow detection (bit field CFIFO[RXOFE]). */ + #define FSL_FEATURE_UART_HAS_IRQ_EXTENDED_FUNCTIONS (1) + /* @brief Has low power features (can be enabled in wait mode via register bit C1[DOZEEN] or CTRL[DOZEEN] if the registers are 32-bit wide). */ + #define FSL_FEATURE_UART_HAS_LOW_POWER_UART_SUPPORT (0) + /* @brief Has extended data register ED (or extra flags in the DATA register if the registers are 32-bit wide). */ + #define FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS (1) + /* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */ + #define FSL_FEATURE_UART_HAS_FIFO (1) + /* @brief Hardware flow control (RTS, CTS) is supported. */ + #define FSL_FEATURE_UART_HAS_MODEM_SUPPORT (1) + /* @brief Infrared (modulation) is supported. */ + #define FSL_FEATURE_UART_HAS_IR_SUPPORT (1) + /* @brief 2 bits long stop bit is available. */ + #define FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT (1) + /* @brief If 10-bit mode is supported. */ + #define FSL_FEATURE_UART_HAS_10BIT_DATA_SUPPORT (1) + /* @brief Baud rate fine adjustment is available. */ + #define FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT (1) + /* @brief Baud rate oversampling is available (has bit fields C4[OSR], C5[BOTHEDGE], C5[RESYNCDIS] or BAUD[OSR], BAUD[BOTHEDGE], BAUD[RESYNCDIS] if the registers are 32-bit wide). */ + #define FSL_FEATURE_UART_HAS_BAUD_RATE_OVER_SAMPLING_SUPPORT (0) + /* @brief Baud rate oversampling is available. */ + #define FSL_FEATURE_UART_HAS_RX_RESYNC_SUPPORT (0) + /* @brief Baud rate oversampling is available. */ + #define FSL_FEATURE_UART_HAS_BOTH_EDGE_SAMPLING_SUPPORT (0) + /* @brief Peripheral type. */ + #define FSL_FEATURE_UART_IS_SCI (0) + /* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */ + #define FSL_FEATURE_UART_FIFO_SIZEn(x) \ + ((x) == UART0 ? (8) : \ + ((x) == UART1 ? (8) : \ + ((x) == UART2 ? (1) : \ + ((x) == UART3 ? (1) : \ + ((x) == UART4 ? (1) : \ + ((x) == UART5 ? (1) : (-1))))))) + /* @brief Maximal data width without parity bit. */ + #define FSL_FEATURE_UART_MAX_DATA_WIDTH_WITH_NO_PARITY (9) + /* @brief Maximal data width with parity bit. */ + #define FSL_FEATURE_UART_MAX_DATA_WIDTH_WITH_PARITY (10) + /* @brief Supports two match addresses to filter incoming frames. */ + #define FSL_FEATURE_UART_HAS_ADDRESS_MATCHING (1) + /* @brief Has transmitter/receiver DMA enable bits C5[TDMAE]/C5[RDMAE] (or BAUD[TDMAE]/BAUD[RDMAE] if the registers are 32-bit wide). */ + #define FSL_FEATURE_UART_HAS_DMA_ENABLE (0) + /* @brief Has transmitter/receiver DMA select bits C4[TDMAS]/C4[RDMAS], resp. C5[TDMAS]/C5[RDMAS] if IS_SCI = 0. */ + #define FSL_FEATURE_UART_HAS_DMA_SELECT (1) + /* @brief Data character bit order selection is supported (bit field S2[MSBF] or STAT[MSBF] if the registers are 32-bit wide). */ + #define FSL_FEATURE_UART_HAS_BIT_ORDER_SELECT (1) + /* @brief Has smart card (ISO7816 protocol) support and no improved smart card support. */ + #define FSL_FEATURE_UART_HAS_SMART_CARD_SUPPORT (1) + /* @brief Has improved smart card (ISO7816 protocol) support. */ + #define FSL_FEATURE_UART_HAS_IMPROVED_SMART_CARD_SUPPORT (0) + /* @brief Has local operation network (CEA709.1-B protocol) support. */ + #define FSL_FEATURE_UART_HAS_LOCAL_OPERATION_NETWORK_SUPPORT (0) + /* @brief Has 32-bit registers (BAUD, STAT, CTRL, DATA, MATCH, MODIR) instead of 8-bit (BDH, BDL, C1, S1, D, etc.). */ + #define FSL_FEATURE_UART_HAS_32BIT_REGISTERS (0) + /* @brief Lin break detect available (has bit BDH[LBKDIE]). */ + #define FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT (1) + /* @brief UART stops in Wait mode available (has bit C1[UARTSWAI]). */ + #define FSL_FEATURE_UART_HAS_WAIT_MODE_OPERATION (1) + /* @brief Has separate DMA RX and TX requests. */ + #define FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(x) \ + ((x) == UART0 ? (1) : \ + ((x) == UART1 ? (1) : \ + ((x) == UART2 ? (1) : \ + ((x) == UART3 ? (1) : \ + ((x) == UART4 ? (0) : \ + ((x) == UART5 ? (0) : (-1))))))) +#elif defined(CPU_MK64FN1M0VLL12) || defined(CPU_MK64FX512VLL12) + /* @brief Has receive FIFO overflow detection (bit field CFIFO[RXOFE]). */ + #define FSL_FEATURE_UART_HAS_IRQ_EXTENDED_FUNCTIONS (1) + /* @brief Has low power features (can be enabled in wait mode via register bit C1[DOZEEN] or CTRL[DOZEEN] if the registers are 32-bit wide). */ + #define FSL_FEATURE_UART_HAS_LOW_POWER_UART_SUPPORT (0) + /* @brief Has extended data register ED (or extra flags in the DATA register if the registers are 32-bit wide). */ + #define FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS (1) + /* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */ + #define FSL_FEATURE_UART_HAS_FIFO (1) + /* @brief Hardware flow control (RTS, CTS) is supported. */ + #define FSL_FEATURE_UART_HAS_MODEM_SUPPORT (1) + /* @brief Infrared (modulation) is supported. */ + #define FSL_FEATURE_UART_HAS_IR_SUPPORT (1) + /* @brief 2 bits long stop bit is available. */ + #define FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT (1) + /* @brief If 10-bit mode is supported. */ + #define FSL_FEATURE_UART_HAS_10BIT_DATA_SUPPORT (1) + /* @brief Baud rate fine adjustment is available. */ + #define FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT (1) + /* @brief Baud rate oversampling is available (has bit fields C4[OSR], C5[BOTHEDGE], C5[RESYNCDIS] or BAUD[OSR], BAUD[BOTHEDGE], BAUD[RESYNCDIS] if the registers are 32-bit wide). */ + #define FSL_FEATURE_UART_HAS_BAUD_RATE_OVER_SAMPLING_SUPPORT (0) + /* @brief Baud rate oversampling is available. */ + #define FSL_FEATURE_UART_HAS_RX_RESYNC_SUPPORT (0) + /* @brief Baud rate oversampling is available. */ + #define FSL_FEATURE_UART_HAS_BOTH_EDGE_SAMPLING_SUPPORT (0) + /* @brief Peripheral type. */ + #define FSL_FEATURE_UART_IS_SCI (0) + /* @brief Capacity (number of entries) of the transmit/receive FIFO (or zero if no FIFO is available). */ + #define FSL_FEATURE_UART_FIFO_SIZEn(x) \ + ((x) == UART0 ? (8) : \ + ((x) == UART1 ? (8) : \ + ((x) == UART2 ? (1) : \ + ((x) == UART3 ? (1) : \ + ((x) == UART4 ? (1) : (-1)))))) + /* @brief Maximal data width without parity bit. */ + #define FSL_FEATURE_UART_MAX_DATA_WIDTH_WITH_NO_PARITY (9) + /* @brief Maximal data width with parity bit. */ + #define FSL_FEATURE_UART_MAX_DATA_WIDTH_WITH_PARITY (10) + /* @brief Supports two match addresses to filter incoming frames. */ + #define FSL_FEATURE_UART_HAS_ADDRESS_MATCHING (1) + /* @brief Has transmitter/receiver DMA enable bits C5[TDMAE]/C5[RDMAE] (or BAUD[TDMAE]/BAUD[RDMAE] if the registers are 32-bit wide). */ + #define FSL_FEATURE_UART_HAS_DMA_ENABLE (0) + /* @brief Has transmitter/receiver DMA select bits C4[TDMAS]/C4[RDMAS], resp. C5[TDMAS]/C5[RDMAS] if IS_SCI = 0. */ + #define FSL_FEATURE_UART_HAS_DMA_SELECT (1) + /* @brief Data character bit order selection is supported (bit field S2[MSBF] or STAT[MSBF] if the registers are 32-bit wide). */ + #define FSL_FEATURE_UART_HAS_BIT_ORDER_SELECT (1) + /* @brief Has smart card (ISO7816 protocol) support and no improved smart card support. */ + #define FSL_FEATURE_UART_HAS_SMART_CARD_SUPPORT (1) + /* @brief Has improved smart card (ISO7816 protocol) support. */ + #define FSL_FEATURE_UART_HAS_IMPROVED_SMART_CARD_SUPPORT (0) + /* @brief Has local operation network (CEA709.1-B protocol) support. */ + #define FSL_FEATURE_UART_HAS_LOCAL_OPERATION_NETWORK_SUPPORT (0) + /* @brief Has 32-bit registers (BAUD, STAT, CTRL, DATA, MATCH, MODIR) instead of 8-bit (BDH, BDL, C1, S1, D, etc.). */ + #define FSL_FEATURE_UART_HAS_32BIT_REGISTERS (0) + /* @brief Lin break detect available (has bit BDH[LBKDIE]). */ + #define FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT (1) + /* @brief UART stops in Wait mode available (has bit C1[UARTSWAI]). */ + #define FSL_FEATURE_UART_HAS_WAIT_MODE_OPERATION (1) + /* @brief Has separate DMA RX and TX requests. */ + #define FSL_FEATURE_UART_HAS_SEPARATE_DMA_RX_TX_REQn(x) \ + ((x) == UART0 ? (1) : \ + ((x) == UART1 ? (1) : \ + ((x) == UART2 ? (1) : \ + ((x) == UART3 ? (1) : \ + ((x) == UART4 ? (0) : (-1)))))) +#endif /* defined(CPU_MK64FN1M0CAJ12) || defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLQ12) || defined(CPU_MK64FN1M0VMD12) || \ + defined(CPU_MK64FX512VDC12) || defined(CPU_MK64FX512VLQ12) || defined(CPU_MK64FX512VMD12) */ + +/* USB module features */ + +/* @brief KHCI module instance count */ +#define FSL_FEATURE_USB_KHCI_COUNT (1) +/* @brief HOST mode enabled */ +#define FSL_FEATURE_USB_KHCI_HOST_ENABLED (1) +/* @brief OTG mode enabled */ +#define FSL_FEATURE_USB_KHCI_OTG_ENABLED (1) +/* @brief Size of the USB dedicated RAM */ +#define FSL_FEATURE_USB_KHCI_USB_RAM (0) +/* @brief Has KEEP_ALIVE_CTRL register */ +#define FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED (0) +/* @brief Has the Dynamic SOF threshold compare support */ +#define FSL_FEATURE_USB_KHCI_DYNAMIC_SOF_THRESHOLD_COMPARE_ENABLED (0) +/* @brief Has the VBUS detect support */ +#define FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED (0) +/* @brief Has the IRC48M module clock support */ +#define FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED (1) +/* @brief Number of endpoints supported */ +#define FSL_FEATURE_USB_ENDPT_COUNT (16) +/* @brief Has STALL_IL/OL_DIS registers */ +#define FSL_FEATURE_USB_KHCI_HAS_STALL_LOW (0) +/* @brief Has STALL_IH/OH_DIS registers */ +#define FSL_FEATURE_USB_KHCI_HAS_STALL_HIGH (0) + +/* VREF module features */ + +/* @brief Has chop oscillator (bit TRM[CHOPEN]) */ +#define FSL_FEATURE_VREF_HAS_CHOP_OSC (1) +/* @brief Has second order curvature compensation (bit SC[ICOMPEN]) */ +#define FSL_FEATURE_VREF_HAS_COMPENSATION (1) +/* @brief If high/low buffer mode supported */ +#define FSL_FEATURE_VREF_MODE_LV_TYPE (1) +/* @brief Module has also low reference (registers VREFL/VREFH) */ +#define FSL_FEATURE_VREF_HAS_LOW_REFERENCE (0) +/* @brief Has VREF_TRM4. */ +#define FSL_FEATURE_VREF_HAS_TRM4 (0) + +/* WDOG module features */ + +/* @brief Watchdog is available. */ +#define FSL_FEATURE_WDOG_HAS_WATCHDOG (1) +/* @brief Has Wait mode support. */ +#define FSL_FEATURE_WDOG_HAS_WAITEN (1) + +#endif /* _MK64F12_FEATURES_H_ */ + diff --git a/device/fsl_device_registers.h b/device/fsl_device_registers.h new file mode 100644 index 0000000..562a5b9 --- /dev/null +++ b/device/fsl_device_registers.h @@ -0,0 +1,36 @@ +/* + * Copyright 2014-2016 Freescale Semiconductor, Inc. + * Copyright 2016-2018 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __FSL_DEVICE_REGISTERS_H__ +#define __FSL_DEVICE_REGISTERS_H__ + +/* + * Include the cpu specific register header files. + * + * The CPU macro should be declared in the project or makefile. + */ +#if (defined(CPU_MK64FN1M0CAJ12) || defined(CPU_MK64FN1M0VDC12) || defined(CPU_MK64FN1M0VLL12) || \ + defined(CPU_MK64FN1M0VLQ12) || defined(CPU_MK64FN1M0VMD12) || defined(CPU_MK64FX512VDC12) || \ + defined(CPU_MK64FX512VLL12) || defined(CPU_MK64FX512VLQ12) || defined(CPU_MK64FX512VMD12)) + +#define K64F12_SERIES + +/* CMSIS-style register definitions */ +#include "MK64F12.h" +/* CPU specific feature definitions */ +#include "MK64F12_features.h" + +#else + #error "No valid CPU defined!" +#endif + +#endif /* __FSL_DEVICE_REGISTERS_H__ */ + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/device/system_MK64F12.c b/device/system_MK64F12.c new file mode 100644 index 0000000..14534e9 --- /dev/null +++ b/device/system_MK64F12.c @@ -0,0 +1,302 @@ +/* +** ################################################################### +** Processors: MK64FN1M0CAJ12 +** MK64FN1M0VDC12 +** MK64FN1M0VLL12 +** MK64FN1M0VLQ12 +** MK64FN1M0VMD12 +** MK64FX512VDC12 +** MK64FX512VLL12 +** MK64FX512VLQ12 +** MK64FX512VMD12 +** +** Compilers: Keil ARM C/C++ Compiler +** Freescale C/C++ for Embedded ARM +** GNU C Compiler +** IAR ANSI C/C++ Compiler for ARM +** MCUXpresso Compiler +** +** Reference manual: K64P144M120SF5RM, Rev.2, January 2014 +** Version: rev. 2.9, 2016-03-21 +** Build: b180801 +** +** Abstract: +** Provides a system configuration function and a global variable that +** contains the system frequency. It configures the device and initializes +** the oscillator (PLL) that is part of the microcontroller device. +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2018 NXP +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** Revisions: +** - rev. 1.0 (2013-08-12) +** Initial version. +** - rev. 2.0 (2013-10-29) +** Register accessor macros added to the memory map. +** Symbols for Processor Expert memory map compatibility added to the memory map. +** Startup file for gcc has been updated according to CMSIS 3.2. +** System initialization updated. +** MCG - registers updated. +** PORTA, PORTB, PORTC, PORTE - registers for digital filter removed. +** - rev. 2.1 (2013-10-30) +** Definition of BITBAND macros updated to support peripherals with 32-bit acces disabled. +** - rev. 2.2 (2013-12-09) +** DMA - EARS register removed. +** AIPS0, AIPS1 - MPRA register updated. +** - rev. 2.3 (2014-01-24) +** Update according to reference manual rev. 2 +** ENET, MCG, MCM, SIM, USB - registers updated +** - rev. 2.4 (2014-02-10) +** The declaration of clock configurations has been moved to separate header file system_MK64F12.h +** Update of SystemInit() and SystemCoreClockUpdate() functions. +** - rev. 2.5 (2014-02-10) +** The declaration of clock configurations has been moved to separate header file system_MK64F12.h +** Update of SystemInit() and SystemCoreClockUpdate() functions. +** Module access macro module_BASES replaced by module_BASE_PTRS. +** - rev. 2.6 (2014-08-28) +** Update of system files - default clock configuration changed. +** Update of startup files - possibility to override DefaultISR added. +** - rev. 2.7 (2014-10-14) +** Interrupt INT_LPTimer renamed to INT_LPTMR0, interrupt INT_Watchdog renamed to INT_WDOG_EWM. +** - rev. 2.8 (2015-02-19) +** Renamed interrupt vector LLW to LLWU. +** - rev. 2.9 (2016-03-21) +** Added MK64FN1M0CAJ12 part. +** GPIO - renamed port instances: PTx -> GPIOx. +** +** ################################################################### +*/ + +/*! + * @file MK64F12 + * @version 2.9 + * @date 2016-03-21 + * @brief Device specific configuration file for MK64F12 (implementation file) + * + * Provides a system configuration function and a global variable that contains + * the system frequency. It configures the device and initializes the oscillator + * (PLL) that is part of the microcontroller device. + */ + +#include +#include "fsl_device_registers.h" +#include "MK64F12.h" + + +/*---------------------------------------------------------------------------- + Define clock source values + *----------------------------------------------------------------------------*/ +#define CLOCK_SETUP 1 + +#if (CLOCK_SETUP == 1) + #define CPU_XTAL0_CLK_HZ SYS_FREQ_OSC + #define CPU_XTAL32k_CLK_HZ 32768u /* Value of the external 32k crystal or oscillator clock frequency in Hz */ + #define CPU_INT_SLOW_CLK_HZ 32768u /* Value of the slow internal oscillator clock frequency in Hz */ + #define CPU_INT_FAST_CLK_HZ 4000000u /* Value of the fast internal oscillator clock frequency in Hz */ + + #undef DEFAULT_SYSTEM_CLOCK + #define DEFAULT_SYSTEM_CLOCK 120000000u /* Default System clock value */ +#endif //CLOCK_SETUP == 1 + +uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK; + + +/* ---------------------------------------------------------------------------- + -- SystemInit() + ---------------------------------------------------------------------------- */ + +void SystemInit (void) { +#if ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) + SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2)); /* set CP10, CP11 Full Access */ +#endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */ +#if (DISABLE_WDOG) + /* WDOG->UNLOCK: WDOGUNLOCK=0xC520 */ + WDOG->UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xC520); /* Key 1 */ + /* WDOG->UNLOCK: WDOGUNLOCK=0xD928 */ + WDOG->UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xD928); /* Key 2 */ + /* WDOG->STCTRLH: ?=0,DISTESTWDOG=0,BYTESEL=0,TESTSEL=0,TESTWDOG=0,?=0,?=1,WAITEN=1,STOPEN=1,DBGEN=0,ALLOWUPDATE=1,WINEN=0,IRQRSTEN=0,CLKSRC=1,WDOGEN=0 */ + WDOG->STCTRLH = WDOG_STCTRLH_BYTESEL(0x00) | + WDOG_STCTRLH_WAITEN_MASK | + WDOG_STCTRLH_STOPEN_MASK | + WDOG_STCTRLH_ALLOWUPDATE_MASK | + WDOG_STCTRLH_CLKSRC_MASK | + 0x0100U; +#endif /* (DISABLE_WDOG) */ + + SystemInitHook(); + + /* System clock initialization */ +#if (CLOCK_SETUP == 1) + /* SIM_SCGC5: PORTA=1 */ + SIM->SCGC5 |= (uint32_t)0x0200UL; /* Enable clock gate for ports to enable pin routing */ + /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=1,OUTDIV3=3,OUTDIV4=5,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ + SIM->CLKDIV1 = (uint32_t)0x01350000UL; /* Update system prescalers */ + /* SIM_SOPT2: PLLFLLSEL=1 */ + SIM->SOPT2 = (uint32_t)((SIM->SOPT2 & (uint32_t)~0x00020000UL) | (uint32_t)0x00010000UL); /* Select PLL 0 as a clock source for various peripherals */ + /* SIM_SOPT1: OSC32KSEL=0 */ + SIM->SOPT1 &= (uint32_t)~0x00080000UL; /* System oscillator drives 32 kHz clock for various peripherals */ + /* SIM_SCGC1: OSC1=1 */ + SIM->SCGC1 |= (uint32_t)0x20UL; + /* PORTA_PCR18: ISF=0,MUX=0 */ + PORTA->PCR[18] &= (uint32_t)~0x01000700UL; + /* Switch to FBE Mode */ + /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ + OSC->CR = (uint8_t)0x80U; + /* OSC1_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ + //OSC1->CR = (uint8_t)0x80U; + /* MCG_C7: OSCSEL=0 */ + MCG->C7 &= (uint8_t)~(uint8_t)0x01U; + /* MCG_C2: LOCRE0=0,??=0,RANGE0=1,HGO0=0,EREFS0=1,LP=0,IRCS=0 */ + MCG->C2 = (uint8_t)0x14U; + /* MCG_C1: CLKS=2,FRDIV=4,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ + MCG->C1 = (uint8_t)0xA2U; + /* MCG_C4: DMX32=0,DRST_DRS=0 */ + MCG->C4 &= (uint8_t)~(uint8_t)0xE0U; + /* MCG_C5: PLLREFSEL0=0,PLLCLKEN0=0,PLLSTEN0=0,??=0,??=0,PRDIV0=3 */ + MCG->C5 = (uint8_t)0x03U; + /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=6 */ + MCG->C6 = (uint8_t)0x06U; + /* MCG_C11: PLLREFSEL1=0,PLLCLKEN1=0,PLLSTEN1=0,PLLCS=0,??=0,PRDIV1=0 */ + //MCG->C11 = (uint8_t)0x00U; + /* MCG_C12: LOLIE1=0,??=0,CME2=0,VDIV1=0 */ + //MCG->C12 = (uint8_t)0x00U; + while((MCG->S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */ + } + while((MCG->S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ + } + /* Switch to PBE Mode */ + /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=6 */ + MCG->C6 = (uint8_t)0x46U; + while((MCG->S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ + } + while((MCG->S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until PLL locked */ + } + /* Switch to PEE Mode */ + /* MCG->C1: CLKS=0,FRDIV=5,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ + MCG->C1 = (uint8_t)0x2AU; + while((MCG->S & 0x0CU) != 0x0CU) {} /* Wait until output of the PLL is selected */ +#endif +} + +/* ---------------------------------------------------------------------------- + -- SystemCoreClockUpdate() + ---------------------------------------------------------------------------- */ + +void SystemCoreClockUpdate (void) { + uint32_t MCGOUTClock; /* Variable to store output clock frequency of the MCG module */ + uint16_t Divider; + + if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x00U) { + /* Output of FLL or PLL is selected */ + if ((MCG->C6 & MCG_C6_PLLS_MASK) == 0x00U) { + /* FLL is selected */ + if ((MCG->C1 & MCG_C1_IREFS_MASK) == 0x00U) { + /* External reference clock is selected */ + switch (MCG->C7 & MCG_C7_OSCSEL_MASK) { + case 0x00U: + MCGOUTClock = CPU_XTAL_CLK_HZ; /* System oscillator drives MCG clock */ + break; + case 0x01U: + MCGOUTClock = CPU_XTAL32k_CLK_HZ; /* RTC 32 kHz oscillator drives MCG clock */ + break; + case 0x02U: + default: + MCGOUTClock = CPU_INT_IRC_CLK_HZ; /* IRC 48MHz oscillator drives MCG clock */ + break; + } + if (((MCG->C2 & MCG_C2_RANGE_MASK) != 0x00U) && ((MCG->C7 & MCG_C7_OSCSEL_MASK) != 0x01U)) { + switch (MCG->C1 & MCG_C1_FRDIV_MASK) { + case 0x38U: + Divider = 1536U; + break; + case 0x30U: + Divider = 1280U; + break; + default: + Divider = (uint16_t)(32LU << ((MCG->C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT)); + break; + } + } else {/* ((MCG->C2 & MCG_C2_RANGE_MASK) != 0x00U) */ + Divider = (uint16_t)(1LU << ((MCG->C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT)); + } + MCGOUTClock = (MCGOUTClock / Divider); /* Calculate the divided FLL reference clock */ + } else { /* (!((MCG->C1 & MCG_C1_IREFS_MASK) == 0x00U)) */ + MCGOUTClock = CPU_INT_SLOW_CLK_HZ; /* The slow internal reference clock is selected */ + } /* (!((MCG->C1 & MCG_C1_IREFS_MASK) == 0x00U)) */ + /* Select correct multiplier to calculate the MCG output clock */ + switch (MCG->C4 & (MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) { + case 0x00U: + MCGOUTClock *= 640U; + break; + case 0x20U: + MCGOUTClock *= 1280U; + break; + case 0x40U: + MCGOUTClock *= 1920U; + break; + case 0x60U: + MCGOUTClock *= 2560U; + break; + case 0x80U: + MCGOUTClock *= 732U; + break; + case 0xA0U: + MCGOUTClock *= 1464U; + break; + case 0xC0U: + MCGOUTClock *= 2197U; + break; + case 0xE0U: + MCGOUTClock *= 2929U; + break; + default: + break; + } + } else { /* (!((MCG->C6 & MCG_C6_PLLS_MASK) == 0x00U)) */ + /* PLL is selected */ + Divider = (((uint16_t)MCG->C5 & MCG_C5_PRDIV0_MASK) + 0x01U); + MCGOUTClock = (uint32_t)(CPU_XTAL_CLK_HZ / Divider); /* Calculate the PLL reference clock */ + Divider = (((uint16_t)MCG->C6 & MCG_C6_VDIV0_MASK) + 24U); + MCGOUTClock *= Divider; /* Calculate the MCG output clock */ + } /* (!((MCG->C6 & MCG_C6_PLLS_MASK) == 0x00U)) */ + } else if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x40U) { + /* Internal reference clock is selected */ + if ((MCG->C2 & MCG_C2_IRCS_MASK) == 0x00U) { + MCGOUTClock = CPU_INT_SLOW_CLK_HZ; /* Slow internal reference clock selected */ + } else { /* (!((MCG->C2 & MCG_C2_IRCS_MASK) == 0x00U)) */ + Divider = (uint16_t)(0x01LU << ((MCG->SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT)); + MCGOUTClock = (uint32_t) (CPU_INT_FAST_CLK_HZ / Divider); /* Fast internal reference clock selected */ + } /* (!((MCG->C2 & MCG_C2_IRCS_MASK) == 0x00U)) */ + } else if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80U) { + /* External reference clock is selected */ + switch (MCG->C7 & MCG_C7_OSCSEL_MASK) { + case 0x00U: + MCGOUTClock = CPU_XTAL_CLK_HZ; /* System oscillator drives MCG clock */ + break; + case 0x01U: + MCGOUTClock = CPU_XTAL32k_CLK_HZ; /* RTC 32 kHz oscillator drives MCG clock */ + break; + case 0x02U: + default: + MCGOUTClock = CPU_INT_IRC_CLK_HZ; /* IRC 48MHz oscillator drives MCG clock */ + break; + } + } else { /* (!((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80U)) */ + /* Reserved value */ + return; + } /* (!((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80U)) */ + SystemCoreClock = (MCGOUTClock / (0x01U + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT))); +} + +/* ---------------------------------------------------------------------------- + -- SystemInitHook() + ---------------------------------------------------------------------------- */ + +__attribute__ ((weak)) void SystemInitHook (void) { + /* Void implementation of the weak function. */ +} diff --git a/device/system_MK64F12.h b/device/system_MK64F12.h new file mode 100644 index 0000000..533733a --- /dev/null +++ b/device/system_MK64F12.h @@ -0,0 +1,164 @@ +/* +** ################################################################### +** Processors: MK64FN1M0CAJ12 +** MK64FN1M0VDC12 +** MK64FN1M0VLL12 +** MK64FN1M0VLQ12 +** MK64FN1M0VMD12 +** MK64FX512VDC12 +** MK64FX512VLL12 +** MK64FX512VLQ12 +** MK64FX512VMD12 +** +** Compilers: Keil ARM C/C++ Compiler +** Freescale C/C++ for Embedded ARM +** GNU C Compiler +** IAR ANSI C/C++ Compiler for ARM +** MCUXpresso Compiler +** +** Reference manual: K64P144M120SF5RM, Rev.2, January 2014 +** Version: rev. 2.9, 2016-03-21 +** Build: b180801 +** +** Abstract: +** Provides a system configuration function and a global variable that +** contains the system frequency. It configures the device and initializes +** the oscillator (PLL) that is part of the microcontroller device. +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2018 NXP +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** Revisions: +** - rev. 1.0 (2013-08-12) +** Initial version. +** - rev. 2.0 (2013-10-29) +** Register accessor macros added to the memory map. +** Symbols for Processor Expert memory map compatibility added to the memory map. +** Startup file for gcc has been updated according to CMSIS 3.2. +** System initialization updated. +** MCG - registers updated. +** PORTA, PORTB, PORTC, PORTE - registers for digital filter removed. +** - rev. 2.1 (2013-10-30) +** Definition of BITBAND macros updated to support peripherals with 32-bit acces disabled. +** - rev. 2.2 (2013-12-09) +** DMA - EARS register removed. +** AIPS0, AIPS1 - MPRA register updated. +** - rev. 2.3 (2014-01-24) +** Update according to reference manual rev. 2 +** ENET, MCG, MCM, SIM, USB - registers updated +** - rev. 2.4 (2014-02-10) +** The declaration of clock configurations has been moved to separate header file system_MK64F12.h +** Update of SystemInit() and SystemCoreClockUpdate() functions. +** - rev. 2.5 (2014-02-10) +** The declaration of clock configurations has been moved to separate header file system_MK64F12.h +** Update of SystemInit() and SystemCoreClockUpdate() functions. +** Module access macro module_BASES replaced by module_BASE_PTRS. +** - rev. 2.6 (2014-08-28) +** Update of system files - default clock configuration changed. +** Update of startup files - possibility to override DefaultISR added. +** - rev. 2.7 (2014-10-14) +** Interrupt INT_LPTimer renamed to INT_LPTMR0, interrupt INT_Watchdog renamed to INT_WDOG_EWM. +** - rev. 2.8 (2015-02-19) +** Renamed interrupt vector LLW to LLWU. +** - rev. 2.9 (2016-03-21) +** Added MK64FN1M0CAJ12 part. +** GPIO - renamed port instances: PTx -> GPIOx. +** +** ################################################################### +*/ + +/*! + * @file MK64F12 + * @version 2.9 + * @date 2016-03-21 + * @brief Device specific configuration file for MK64F12 (header file) + * + * Provides a system configuration function and a global variable that contains + * the system frequency. It configures the device and initializes the oscillator + * (PLL) that is part of the microcontroller device. + */ + +#ifndef _SYSTEM_MK64F12_H_ +#define _SYSTEM_MK64F12_H_ /**< Symbol preventing repeated inclusion */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +#ifndef DISABLE_WDOG + #define DISABLE_WDOG 1 +#endif + +/* Define clock source values */ + +#define CPU_XTAL_CLK_HZ 16000000u /* Value of the external crystal or oscillator clock frequency in Hz */ +#define CPU_XTAL32k_CLK_HZ 32768u /* Value of the external 32k crystal or oscillator clock frequency in Hz */ +#define CPU_INT_SLOW_CLK_HZ 32768u /* Value of the slow internal oscillator clock frequency in Hz */ +#define CPU_INT_FAST_CLK_HZ 4000000u /* Value of the fast internal oscillator clock frequency in Hz */ +#define CPU_INT_IRC_CLK_HZ 48000000u /* Value of the 48M internal oscillator clock frequency in Hz */ + +/* RTC oscillator setting */ +/* RTC_CR: SC2P=0,SC4P=0,SC8P=0,SC16P=0,CLKO=1,OSCE=1,WPS=0,UM=0,SUP=0,WPE=0,SWR=0 */ +#define SYSTEM_RTC_CR_VALUE 0x0300U /* RTC_CR */ + +/* Low power mode enable */ +/* SMC_PMPROT: AVLP=1,ALLS=1,AVLLS=1 */ +#define SYSTEM_SMC_PMPROT_VALUE 0x2AU /* SMC_PMPROT */ + +#define DEFAULT_SYSTEM_CLOCK 20971520u /* Default System clock value */ + + +/** + * @brief System clock frequency (core clock) + * + * The system clock frequency supplied to the SysTick timer and the processor + * core clock. This variable can be used by the user application to setup the + * SysTick timer or configure other parameters. It may also be used by debugger to + * query the frequency of the debug timer or configure the trace clock speed + * SystemCoreClock is initialized with a correct predefined value. + */ +extern uint32_t SystemCoreClock; + +/** + * @brief Setup the microcontroller system. + * + * Typically this function configures the oscillator (PLL) that is part of the + * microcontroller device. For systems with variable clock speed it also updates + * the variable SystemCoreClock. SystemInit is called from startup_device file. + */ +void SystemInit (void); + +/** + * @brief Updates the SystemCoreClock variable. + * + * It must be called whenever the core clock is changed during program + * execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates + * the current core clock. + */ +void SystemCoreClockUpdate (void); + +/** + * @brief SystemInit function hook. + * + * This weak function allows to call specific initialization code during the + * SystemInit() execution.This can be used when an application specific code needs + * to be called as close to the reset entry as possible (for example the Multicore + * Manager MCMGR_EarlyInit() function call). + * NOTE: No global r/w variables can be used in this hook function because the + * initialization of these variables happens after this function. + */ +void SystemInitHook (void); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYSTEM_MK64F12_H_ */ diff --git a/drivers/fsl_clock.c b/drivers/fsl_clock.c new file mode 100644 index 0000000..4fff390 --- /dev/null +++ b/drivers/fsl_clock.c @@ -0,0 +1,2266 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright (c) 2016 - 2017 , NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_clock.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.clock" +#endif + +/* Macro definition remap workaround. */ +#if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK))) +#define MCG_C2_EREFS0_MASK MCG_C2_EREFS_MASK +#endif +#if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK))) +#define MCG_C2_HGO0_MASK MCG_C2_HGO_MASK +#endif +#if (defined(MCG_C2_RANGE_MASK) && !(defined(MCG_C2_RANGE0_MASK))) +#define MCG_C2_RANGE0_MASK MCG_C2_RANGE_MASK +#endif +#if (defined(MCG_C6_CME_MASK) && !(defined(MCG_C6_CME0_MASK))) +#define MCG_C6_CME0_MASK MCG_C6_CME_MASK +#endif + +/* PLL fixed multiplier when there is not PRDIV and VDIV. */ +#define PLL_FIXED_MULT (375U) +/* Max frequency of the reference clock used for internal clock trim. */ +#define TRIM_REF_CLK_MIN (8000000U) +/* Min frequency of the reference clock used for internal clock trim. */ +#define TRIM_REF_CLK_MAX (16000000U) +/* Max trim value of fast internal reference clock. */ +#define TRIM_FIRC_MAX (5000000U) +/* Min trim value of fast internal reference clock. */ +#define TRIM_FIRC_MIN (3000000U) +/* Max trim value of fast internal reference clock. */ +#define TRIM_SIRC_MAX (39063U) +/* Min trim value of fast internal reference clock. */ +#define TRIM_SIRC_MIN (31250U) + +#define MCG_S_IRCST_VAL ((MCG->S & MCG_S_IRCST_MASK) >> MCG_S_IRCST_SHIFT) +#define MCG_S_CLKST_VAL ((MCG->S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) +#define MCG_S_IREFST_VAL ((MCG->S & MCG_S_IREFST_MASK) >> MCG_S_IREFST_SHIFT) +#define MCG_S_PLLST_VAL ((MCG->S & MCG_S_PLLST_MASK) >> MCG_S_PLLST_SHIFT) +#define MCG_C1_FRDIV_VAL ((MCG->C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT) +#define MCG_C2_LP_VAL ((MCG->C2 & MCG_C2_LP_MASK) >> MCG_C2_LP_SHIFT) +#define MCG_C2_RANGE_VAL ((MCG->C2 & MCG_C2_RANGE_MASK) >> MCG_C2_RANGE_SHIFT) +#define MCG_SC_FCRDIV_VAL ((MCG->SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT) +#define MCG_S2_PLLCST_VAL ((MCG->S2 & MCG_S2_PLLCST_MASK) >> MCG_S2_PLLCST_SHIFT) +#define MCG_C7_OSCSEL_VAL ((MCG->C7 & MCG_C7_OSCSEL_MASK) >> MCG_C7_OSCSEL_SHIFT) +#define MCG_C4_DMX32_VAL ((MCG->C4 & MCG_C4_DMX32_MASK) >> MCG_C4_DMX32_SHIFT) +#define MCG_C4_DRST_DRS_VAL ((MCG->C4 & MCG_C4_DRST_DRS_MASK) >> MCG_C4_DRST_DRS_SHIFT) +#define MCG_C7_PLL32KREFSEL_VAL ((MCG->C7 & MCG_C7_PLL32KREFSEL_MASK) >> MCG_C7_PLL32KREFSEL_SHIFT) +#define MCG_C5_PLLREFSEL0_VAL ((MCG->C5 & MCG_C5_PLLREFSEL0_MASK) >> MCG_C5_PLLREFSEL0_SHIFT) +#define MCG_C11_PLLREFSEL1_VAL ((MCG->C11 & MCG_C11_PLLREFSEL1_MASK) >> MCG_C11_PLLREFSEL1_SHIFT) +#define MCG_C11_PRDIV1_VAL ((MCG->C11 & MCG_C11_PRDIV1_MASK) >> MCG_C11_PRDIV1_SHIFT) +#define MCG_C12_VDIV1_VAL ((MCG->C12 & MCG_C12_VDIV1_MASK) >> MCG_C12_VDIV1_SHIFT) +#define MCG_C5_PRDIV0_VAL ((MCG->C5 & MCG_C5_PRDIV0_MASK) >> MCG_C5_PRDIV0_SHIFT) +#define MCG_C6_VDIV0_VAL ((MCG->C6 & MCG_C6_VDIV0_MASK) >> MCG_C6_VDIV0_SHIFT) + +#define OSC_MODE_MASK (MCG_C2_EREFS0_MASK | MCG_C2_HGO0_MASK | MCG_C2_RANGE0_MASK) + +#define SIM_CLKDIV1_OUTDIV1_VAL ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT) +#define SIM_CLKDIV1_OUTDIV2_VAL ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV2_MASK) >> SIM_CLKDIV1_OUTDIV2_SHIFT) +#define SIM_CLKDIV1_OUTDIV3_VAL ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV3_MASK) >> SIM_CLKDIV1_OUTDIV3_SHIFT) +#define SIM_CLKDIV1_OUTDIV4_VAL ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT) +#define SIM_SOPT1_OSC32KSEL_VAL ((SIM->SOPT1 & SIM_SOPT1_OSC32KSEL_MASK) >> SIM_SOPT1_OSC32KSEL_SHIFT) +#define SIM_SOPT2_PLLFLLSEL_VAL ((SIM->SOPT2 & SIM_SOPT2_PLLFLLSEL_MASK) >> SIM_SOPT2_PLLFLLSEL_SHIFT) + +/* MCG_S_CLKST definition. */ +enum _mcg_clkout_stat +{ + kMCG_ClkOutStatFll, /* FLL. */ + kMCG_ClkOutStatInt, /* Internal clock. */ + kMCG_ClkOutStatExt, /* External clock. */ + kMCG_ClkOutStatPll /* PLL. */ +}; + +/* MCG_S_PLLST definition. */ +enum _mcg_pllst +{ + kMCG_PllstFll, /* FLL is used. */ + kMCG_PllstPll /* PLL is used. */ +}; + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Slow internal reference clock frequency. */ +static uint32_t s_slowIrcFreq = 32768U; +/* Fast internal reference clock frequency. */ +static uint32_t s_fastIrcFreq = 4000000U; + +/* External XTAL0 (OSC0) clock frequency. */ +volatile uint32_t g_xtal0Freq; +/* External XTAL32K clock frequency. */ +volatile uint32_t g_xtal32Freq; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get the MCG external reference clock frequency. + * + * Get the current MCG external reference clock frequency in Hz. It is + * the frequency select by MCG_C7[OSCSEL]. This is an internal function. + * + * @return MCG external reference clock frequency in Hz. + */ +static uint32_t CLOCK_GetMcgExtClkFreq(void); + +/*! + * @brief Get the MCG FLL external reference clock frequency. + * + * Get the current MCG FLL external reference clock frequency in Hz. It is + * the frequency after by MCG_C1[FRDIV]. This is an internal function. + * + * @return MCG FLL external reference clock frequency in Hz. + */ +static uint32_t CLOCK_GetFllExtRefClkFreq(void); + +/*! + * @brief Get the MCG FLL reference clock frequency. + * + * Get the current MCG FLL reference clock frequency in Hz. It is + * the frequency select by MCG_C1[IREFS]. This is an internal function. + * + * @return MCG FLL reference clock frequency in Hz. + */ +static uint32_t CLOCK_GetFllRefClkFreq(void); + +/*! + * @brief Get the frequency of clock selected by MCG_C2[IRCS]. + * + * This clock's two output: + * 1. MCGOUTCLK when MCG_S[CLKST]=0. + * 2. MCGIRCLK when MCG_C1[IRCLKEN]=1. + * + * @return The frequency in Hz. + */ +static uint32_t CLOCK_GetInternalRefClkSelectFreq(void); + +/*! + * @brief Get the MCG PLL/PLL0 reference clock frequency. + * + * Get the current MCG PLL/PLL0 reference clock frequency in Hz. + * This is an internal function. + * + * @return MCG PLL/PLL0 reference clock frequency in Hz. + */ +static uint32_t CLOCK_GetPll0RefFreq(void); + +/*! + * @brief Calculate the RANGE value base on crystal frequency. + * + * To setup external crystal oscillator, must set the register bits RANGE + * base on the crystal frequency. This function returns the RANGE base on the + * input frequency. This is an internal function. + * + * @param freq Crystal frequency in Hz. + * @return The RANGE value. + */ +static uint8_t CLOCK_GetOscRangeFromFreq(uint32_t freq); + +#ifndef MCG_USER_CONFIG_FLL_STABLE_DELAY_EN +/*! + * @brief Delay function to wait FLL stable. + * + * Delay function to wait FLL stable in FEI mode or FEE mode, should wait at least + * 1ms. Every time changes FLL setting, should wait this time for FLL stable. + */ +static void CLOCK_FllStableDelay(void); +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ + +#ifndef MCG_USER_CONFIG_FLL_STABLE_DELAY_EN +static void CLOCK_FllStableDelay(void) +{ + /* + Should wait at least 1ms. Because in these modes, the core clock is 100MHz + at most, so this function could obtain the 1ms delay. + */ + volatile uint32_t i = 30000U; + while (i--) + { + __NOP(); + } +} +#else /* With MCG_USER_CONFIG_FLL_STABLE_DELAY_EN defined. */ +/* Once user defines the MCG_USER_CONFIG_FLL_STABLE_DELAY_EN to use their own delay function, he has to + * create his own CLOCK_FllStableDelay() function in application code. Since the clock functions in this + * file would call the CLOCK_FllStableDelay() regardless how it is defined. + */ +extern void CLOCK_FllStableDelay(void); +#endif /* MCG_USER_CONFIG_FLL_STABLE_DELAY_EN */ + +static uint32_t CLOCK_GetMcgExtClkFreq(void) +{ + uint32_t freq; + + switch (MCG_C7_OSCSEL_VAL) + { + case 0U: + /* Please call CLOCK_SetXtal0Freq base on board setting before using OSC0 clock. */ + assert(g_xtal0Freq); + freq = g_xtal0Freq; + break; + case 1U: + /* Please call CLOCK_SetXtal32Freq base on board setting before using XTAL32K/RTC_CLKIN clock. */ + assert(g_xtal32Freq); + freq = g_xtal32Freq; + break; + case 2U: + freq = MCG_INTERNAL_IRC_48M; + break; + default: + freq = 0U; + break; + } + + return freq; +} + +static uint32_t CLOCK_GetFllExtRefClkFreq(void) +{ + /* FllExtRef = McgExtRef / FllExtRefDiv */ + uint8_t frdiv; + uint8_t range; + uint8_t oscsel; + + uint32_t freq = CLOCK_GetMcgExtClkFreq(); + + if (!freq) + { + return freq; + } + + frdiv = MCG_C1_FRDIV_VAL; + freq >>= frdiv; + + range = MCG_C2_RANGE_VAL; + oscsel = MCG_C7_OSCSEL_VAL; + + /* + When should use divider 32, 64, 128, 256, 512, 1024, 1280, 1536. + 1. MCG_C7[OSCSEL] selects IRC48M. + 2. MCG_C7[OSCSEL] selects OSC0 and MCG_C2[RANGE] is not 0. + */ + if (((0U != range) && (kMCG_OscselOsc == oscsel)) || (kMCG_OscselIrc == oscsel)) + { + switch (frdiv) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + freq >>= 5u; + break; + case 6: + /* 64*20=1280 */ + freq /= 20u; + break; + case 7: + /* 128*12=1536 */ + freq /= 12u; + break; + default: + freq = 0u; + break; + } + } + + return freq; +} + +static uint32_t CLOCK_GetInternalRefClkSelectFreq(void) +{ + if (kMCG_IrcSlow == MCG_S_IRCST_VAL) + { + /* Slow internal reference clock selected*/ + return s_slowIrcFreq; + } + else + { + /* Fast internal reference clock selected*/ + return s_fastIrcFreq >> MCG_SC_FCRDIV_VAL; + } +} + +static uint32_t CLOCK_GetFllRefClkFreq(void) +{ + /* If use external reference clock. */ + if (kMCG_FllSrcExternal == MCG_S_IREFST_VAL) + { + return CLOCK_GetFllExtRefClkFreq(); + } + /* If use internal reference clock. */ + else + { + return s_slowIrcFreq; + } +} + +static uint32_t CLOCK_GetPll0RefFreq(void) +{ + /* MCG external reference clock. */ + return CLOCK_GetMcgExtClkFreq(); +} + +static uint8_t CLOCK_GetOscRangeFromFreq(uint32_t freq) +{ + uint8_t range; + + if (freq <= 39063U) + { + range = 0U; + } + else if (freq <= 8000000U) + { + range = 1U; + } + else + { + range = 2U; + } + + return range; +} + +/*! + * brief Get the OSC0 external reference clock frequency (OSC0ERCLK). + * + * return Clock frequency in Hz. + */ +uint32_t CLOCK_GetOsc0ErClkFreq(void) +{ + if (OSC0->CR & OSC_CR_ERCLKEN_MASK) + { + /* Please call CLOCK_SetXtal0Freq base on board setting before using OSC0 clock. */ + assert(g_xtal0Freq); + return g_xtal0Freq; + } + else + { + return 0U; + } +} + +/*! + * brief Get the external reference 32K clock frequency (ERCLK32K). + * + * return Clock frequency in Hz. + */ +uint32_t CLOCK_GetEr32kClkFreq(void) +{ + uint32_t freq; + + switch (SIM_SOPT1_OSC32KSEL_VAL) + { + case 0U: /* OSC 32k clock */ + freq = (CLOCK_GetOsc0ErClkFreq() == 32768U) ? 32768U : 0U; + break; + case 2U: /* RTC 32k clock */ + /* Please call CLOCK_SetXtal32Freq base on board setting before using XTAL32K/RTC_CLKIN clock. */ + assert(g_xtal32Freq); + freq = g_xtal32Freq; + break; + case 3U: /* LPO clock */ + freq = LPO_CLK_FREQ; + break; + default: + freq = 0U; + break; + } + return freq; +} + +/*! + * brief Get the output clock frequency selected by SIM[PLLFLLSEL]. + * + * return Clock frequency in Hz. + */ +uint32_t CLOCK_GetPllFllSelClkFreq(void) +{ + uint32_t freq; + + switch (SIM_SOPT2_PLLFLLSEL_VAL) + { + case 0U: /* FLL. */ + freq = CLOCK_GetFllFreq(); + break; + case 1U: /* PLL. */ + freq = CLOCK_GetPll0Freq(); + break; + case 3U: /* MCG IRC48M. */ + freq = MCG_INTERNAL_IRC_48M; + break; + default: + freq = 0U; + break; + } + + return freq; +} + +/*! + * brief Get the platform clock frequency. + * + * return Clock frequency in Hz. + */ +uint32_t CLOCK_GetPlatClkFreq(void) +{ + return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); +} + +/*! + * brief Get the flash clock frequency. + * + * return Clock frequency in Hz. + */ +uint32_t CLOCK_GetFlashClkFreq(void) +{ + return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV4_VAL + 1); +} + +/*! + * brief Get the flexbus clock frequency. + * + * return Clock frequency in Hz. + */ +uint32_t CLOCK_GetFlexBusClkFreq(void) +{ + return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV3_VAL + 1); +} + +/*! + * brief Get the bus clock frequency. + * + * return Clock frequency in Hz. + */ +uint32_t CLOCK_GetBusClkFreq(void) +{ + return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV2_VAL + 1); +} + +/*! + * brief Get the core clock or system clock frequency. + * + * return Clock frequency in Hz. + */ +uint32_t CLOCK_GetCoreSysClkFreq(void) +{ + return CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); +} + +/*! + * brief Gets the clock frequency for a specific clock name. + * + * This function checks the current clock configurations and then calculates + * the clock frequency for a specific clock name defined in clock_name_t. + * The MCG must be properly configured before using this function. + * + * param clockName Clock names defined in clock_name_t + * return Clock frequency value in Hertz + */ +uint32_t CLOCK_GetFreq(clock_name_t clockName) +{ + uint32_t freq; + + switch (clockName) + { + case kCLOCK_CoreSysClk: + case kCLOCK_PlatClk: + freq = CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV1_VAL + 1); + break; + case kCLOCK_BusClk: + freq = CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV2_VAL + 1); + break; + case kCLOCK_FlexBusClk: + freq = CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV3_VAL + 1); + break; + case kCLOCK_FlashClk: + freq = CLOCK_GetOutClkFreq() / (SIM_CLKDIV1_OUTDIV4_VAL + 1); + break; + case kCLOCK_PllFllSelClk: + freq = CLOCK_GetPllFllSelClkFreq(); + break; + case kCLOCK_Er32kClk: + freq = CLOCK_GetEr32kClkFreq(); + break; + case kCLOCK_Osc0ErClk: + freq = CLOCK_GetOsc0ErClkFreq(); + break; + case kCLOCK_McgFixedFreqClk: + freq = CLOCK_GetFixedFreqClkFreq(); + break; + case kCLOCK_McgInternalRefClk: + freq = CLOCK_GetInternalRefClkFreq(); + break; + case kCLOCK_McgFllClk: + freq = CLOCK_GetFllFreq(); + break; + case kCLOCK_McgPll0Clk: + freq = CLOCK_GetPll0Freq(); + break; + case kCLOCK_McgIrc48MClk: + freq = MCG_INTERNAL_IRC_48M; + break; + case kCLOCK_LpoClk: + freq = LPO_CLK_FREQ; + break; + default: + freq = 0U; + break; + } + + return freq; +} + +/*! + * brief Set the clock configure in SIM module. + * + * This function sets system layer clock settings in SIM module. + * + * param config Pointer to the configure structure. + */ +void CLOCK_SetSimConfig(sim_clock_config_t const *config) +{ + SIM->CLKDIV1 = config->clkdiv1; + CLOCK_SetPllFllSelClock(config->pllFllSel); + CLOCK_SetEr32kClock(config->er32kSrc); +} + +/*! brief Enable USB FS clock. + * + * param src USB FS clock source. + * param freq The frequency specified by src. + * retval true The clock is set successfully. + * retval false The clock source is invalid to get proper USB FS clock. + */ +bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq) +{ + bool ret = true; + + CLOCK_DisableClock(kCLOCK_Usbfs0); + + if (kCLOCK_UsbSrcExt == src) + { + SIM->SOPT2 &= ~SIM_SOPT2_USBSRC_MASK; + } + else + { + switch (freq) + { + case 120000000U: + SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(4) | SIM_CLKDIV2_USBFRAC(1); + break; + case 96000000U: + SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(1) | SIM_CLKDIV2_USBFRAC(0); + break; + case 72000000U: + SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(2) | SIM_CLKDIV2_USBFRAC(1); + break; + case 48000000U: + SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(0) | SIM_CLKDIV2_USBFRAC(0); + break; + default: + ret = false; + break; + } + + SIM->SOPT2 = ((SIM->SOPT2 & ~(SIM_SOPT2_PLLFLLSEL_MASK | SIM_SOPT2_USBSRC_MASK)) | (uint32_t)src); + } + + CLOCK_EnableClock(kCLOCK_Usbfs0); + + if (kCLOCK_UsbSrcIrc48M == src) + { + USB0->CLK_RECOVER_IRC_EN = 0x03U; + USB0->CLK_RECOVER_CTRL |= USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK; + } + return ret; +} + +/*! + * brief Gets the MCG output clock (MCGOUTCLK) frequency. + * + * This function gets the MCG output clock frequency in Hz based on the current MCG + * register value. + * + * return The frequency of MCGOUTCLK. + */ +uint32_t CLOCK_GetOutClkFreq(void) +{ + uint32_t mcgoutclk; + uint32_t clkst = MCG_S_CLKST_VAL; + + switch (clkst) + { + case kMCG_ClkOutStatPll: + mcgoutclk = CLOCK_GetPll0Freq(); + break; + case kMCG_ClkOutStatFll: + mcgoutclk = CLOCK_GetFllFreq(); + break; + case kMCG_ClkOutStatInt: + mcgoutclk = CLOCK_GetInternalRefClkSelectFreq(); + break; + case kMCG_ClkOutStatExt: + mcgoutclk = CLOCK_GetMcgExtClkFreq(); + break; + default: + mcgoutclk = 0U; + break; + } + return mcgoutclk; +} + +/*! + * brief Gets the MCG FLL clock (MCGFLLCLK) frequency. + * + * This function gets the MCG FLL clock frequency in Hz based on the current MCG + * register value. The FLL is enabled in FEI/FBI/FEE/FBE mode and + * disabled in low power state in other modes. + * + * return The frequency of MCGFLLCLK. + */ +uint32_t CLOCK_GetFllFreq(void) +{ + static const uint16_t fllFactorTable[4][2] = {{640, 732}, {1280, 1464}, {1920, 2197}, {2560, 2929}}; + + uint8_t drs, dmx32; + uint32_t freq; + + /* If FLL is not enabled currently, then return 0U. */ + if ((MCG->C2 & MCG_C2_LP_MASK) || (MCG->S & MCG_S_PLLST_MASK)) + { + return 0U; + } + + /* Get FLL reference clock frequency. */ + freq = CLOCK_GetFllRefClkFreq(); + if (!freq) + { + return freq; + } + + drs = MCG_C4_DRST_DRS_VAL; + dmx32 = MCG_C4_DMX32_VAL; + + return freq * fllFactorTable[drs][dmx32]; +} + +/*! + * brief Gets the MCG internal reference clock (MCGIRCLK) frequency. + * + * This function gets the MCG internal reference clock frequency in Hz based + * on the current MCG register value. + * + * return The frequency of MCGIRCLK. + */ +uint32_t CLOCK_GetInternalRefClkFreq(void) +{ + /* If MCGIRCLK is gated. */ + if (!(MCG->C1 & MCG_C1_IRCLKEN_MASK)) + { + return 0U; + } + + return CLOCK_GetInternalRefClkSelectFreq(); +} + +/*! + * brief Gets the MCG fixed frequency clock (MCGFFCLK) frequency. + * + * This function gets the MCG fixed frequency clock frequency in Hz based + * on the current MCG register value. + * + * return The frequency of MCGFFCLK. + */ +uint32_t CLOCK_GetFixedFreqClkFreq(void) +{ + uint32_t freq = CLOCK_GetFllRefClkFreq(); + + /* MCGFFCLK must be no more than MCGOUTCLK/8. */ + if ((freq) && (freq <= (CLOCK_GetOutClkFreq() / 8U))) + { + return freq; + } + else + { + return 0U; + } +} + +/*! + * brief Gets the MCG PLL0 clock (MCGPLL0CLK) frequency. + * + * This function gets the MCG PLL0 clock frequency in Hz based on the current MCG + * register value. + * + * return The frequency of MCGPLL0CLK. + */ +uint32_t CLOCK_GetPll0Freq(void) +{ + uint32_t mcgpll0clk; + + /* If PLL0 is not enabled, return 0. */ + if (!(MCG->S & MCG_S_LOCK0_MASK)) + { + return 0U; + } + + mcgpll0clk = CLOCK_GetPll0RefFreq(); + + /* + * Please call CLOCK_SetXtal0Freq base on board setting before using OSC0 clock. + * Please call CLOCK_SetXtal1Freq base on board setting before using OSC1 clock. + */ + assert(mcgpll0clk); + + mcgpll0clk /= (FSL_FEATURE_MCG_PLL_PRDIV_BASE + MCG_C5_PRDIV0_VAL); + mcgpll0clk *= (FSL_FEATURE_MCG_PLL_VDIV_BASE + MCG_C6_VDIV0_VAL); + + return mcgpll0clk; +} + +/*! + * brief Selects the MCG external reference clock. + * + * Selects the MCG external reference clock source, changes the MCG_C7[OSCSEL], + * and waits for the clock source to be stable. Because the external reference + * clock should not be changed in FEE/FBE/BLPE/PBE/PEE modes, do not call this function in these modes. + * + * param oscsel MCG external reference clock source, MCG_C7[OSCSEL]. + * retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source, + * the configuration should not be changed. Otherwise, a glitch occurs. + * retval kStatus_Success External reference clock set successfully. + */ +status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel) +{ + bool needDelay; + uint32_t i; + +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + /* If change MCG_C7[OSCSEL] and external reference clock is system clock source, return error. */ + if ((MCG_C7_OSCSEL_VAL != oscsel) && (!(MCG->S & MCG_S_IREFST_MASK))) + { + return kStatus_MCG_SourceUsed; + } +#endif /* MCG_CONFIG_CHECK_PARAM */ + + if (MCG_C7_OSCSEL_VAL != oscsel) + { + /* If change OSCSEL, need to delay, ERR009878. */ + needDelay = true; + } + else + { + needDelay = false; + } + + MCG->C7 = (MCG->C7 & ~MCG_C7_OSCSEL_MASK) | MCG_C7_OSCSEL(oscsel); + if (needDelay) + { + /* ERR009878 Delay at least 50 micro-seconds for external clock change valid. */ + i = 1500U; + while (i--) + { + __NOP(); + } + } + + return kStatus_Success; +} + +/*! + * brief Configures the Internal Reference clock (MCGIRCLK). + * + * This function sets the \c MCGIRCLK base on parameters. It also selects the IRC + * source. If the fast IRC is used, this function sets the fast IRC divider. + * This function also sets whether the \c MCGIRCLK is enabled in stop mode. + * Calling this function in FBI/PBI/BLPI modes may change the system clock. As a result, + * using the function in these modes it is not allowed. + * + * param enableMode MCGIRCLK enable mode, OR'ed value of ref _mcg_irclk_enable_mode. + * param ircs MCGIRCLK clock source, choose fast or slow. + * param fcrdiv Fast IRC divider setting (\c FCRDIV). + * retval kStatus_MCG_SourceUsed Because the internal reference clock is used as a clock source, + * the configuration should not be changed. Otherwise, a glitch occurs. + * retval kStatus_Success MCGIRCLK configuration finished successfully. + */ +status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv) +{ + uint32_t mcgOutClkState = MCG_S_CLKST_VAL; + mcg_irc_mode_t curIrcs = (mcg_irc_mode_t)MCG_S_IRCST_VAL; + uint8_t curFcrdiv = MCG_SC_FCRDIV_VAL; + +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + /* If MCGIRCLK is used as system clock source. */ + if (kMCG_ClkOutStatInt == mcgOutClkState) + { + /* If need to change MCGIRCLK source or driver, return error. */ + if (((kMCG_IrcFast == curIrcs) && (fcrdiv != curFcrdiv)) || (ircs != curIrcs)) + { + return kStatus_MCG_SourceUsed; + } + } +#endif + + /* If need to update the FCRDIV. */ + if (fcrdiv != curFcrdiv) + { + /* If fast IRC is in use currently, change to slow IRC. */ + if ((kMCG_IrcFast == curIrcs) && ((mcgOutClkState == kMCG_ClkOutStatInt) || (MCG->C1 & MCG_C1_IRCLKEN_MASK))) + { + MCG->C2 = ((MCG->C2 & ~MCG_C2_IRCS_MASK) | (MCG_C2_IRCS(kMCG_IrcSlow))); + while (MCG_S_IRCST_VAL != kMCG_IrcSlow) + { + } + } + /* Update FCRDIV. */ + MCG->SC = (MCG->SC & ~(MCG_SC_FCRDIV_MASK | MCG_SC_ATMF_MASK | MCG_SC_LOCS0_MASK)) | MCG_SC_FCRDIV(fcrdiv); + } + + /* Set internal reference clock selection. */ + MCG->C2 = (MCG->C2 & ~MCG_C2_IRCS_MASK) | (MCG_C2_IRCS(ircs)); + MCG->C1 = (MCG->C1 & ~(MCG_C1_IRCLKEN_MASK | MCG_C1_IREFSTEN_MASK)) | (uint8_t)enableMode; + + /* If MCGIRCLK is used, need to wait for MCG_S_IRCST. */ + if ((mcgOutClkState == kMCG_ClkOutStatInt) || (enableMode & kMCG_IrclkEnable)) + { + while (MCG_S_IRCST_VAL != ircs) + { + } + } + + return kStatus_Success; +} + +/*! + * brief Calculates the PLL divider setting for a desired output frequency. + * + * This function calculates the correct reference clock divider (\c PRDIV) and + * VCO divider (\c VDIV) to generate a desired PLL output frequency. It returns the + * closest frequency match with the corresponding \c PRDIV/VDIV + * returned from parameters. If a desired frequency is not valid, this function + * returns 0. + * + * param refFreq PLL reference clock frequency. + * param desireFreq Desired PLL output frequency. + * param prdiv PRDIV value to generate desired PLL frequency. + * param vdiv VDIV value to generate desired PLL frequency. + * return Closest frequency match that the PLL was able generate. + */ +uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv, uint8_t *vdiv) +{ + uint8_t ret_prdiv; /* PRDIV to return. */ + uint8_t ret_vdiv; /* VDIV to return. */ + uint8_t prdiv_min; /* Min PRDIV value to make reference clock in allowed range. */ + uint8_t prdiv_max; /* Max PRDIV value to make reference clock in allowed range. */ + uint8_t prdiv_cur; /* PRDIV value for iteration. */ + uint8_t vdiv_cur; /* VDIV value for iteration. */ + uint32_t ret_freq = 0U; /* PLL output frequency to return. */ + uint32_t diff = 0xFFFFFFFFU; /* Difference between desireFreq and return frequency. */ + uint32_t ref_div; /* Reference frequency after PRDIV. */ + + /* + Steps: + 1. Get allowed prdiv with such rules: + 1). refFreq / prdiv >= FSL_FEATURE_MCG_PLL_REF_MIN. + 2). refFreq / prdiv <= FSL_FEATURE_MCG_PLL_REF_MAX. + 2. For each allowed prdiv, there are two candidate vdiv values: + 1). (desireFreq / (refFreq / prdiv)). + 2). (desireFreq / (refFreq / prdiv)) + 1. + If could get the precise desired frequency, return current prdiv and + vdiv directly. Otherwise choose the one which is closer to desired + frequency. + */ + + /* Reference frequency is out of range. */ + if ((refFreq < FSL_FEATURE_MCG_PLL_REF_MIN) || + (refFreq > (FSL_FEATURE_MCG_PLL_REF_MAX * (FSL_FEATURE_MCG_PLL_PRDIV_MAX + FSL_FEATURE_MCG_PLL_PRDIV_BASE)))) + { + return 0U; + } + + /* refFreq/PRDIV must in a range. First get the allowed PRDIV range. */ + prdiv_max = refFreq / FSL_FEATURE_MCG_PLL_REF_MIN; + prdiv_min = (refFreq + FSL_FEATURE_MCG_PLL_REF_MAX - 1U) / FSL_FEATURE_MCG_PLL_REF_MAX; + + /* PRDIV traversal. */ + for (prdiv_cur = prdiv_max; prdiv_cur >= prdiv_min; prdiv_cur--) + { + /* Reference frequency after PRDIV. */ + ref_div = refFreq / prdiv_cur; + + vdiv_cur = desireFreq / ref_div; + + if ((vdiv_cur < FSL_FEATURE_MCG_PLL_VDIV_BASE - 1U) || (vdiv_cur > FSL_FEATURE_MCG_PLL_VDIV_BASE + 31U)) + { + /* No VDIV is available with this PRDIV. */ + continue; + } + + ret_freq = vdiv_cur * ref_div; + + if (vdiv_cur >= FSL_FEATURE_MCG_PLL_VDIV_BASE) + { + if (ret_freq == desireFreq) /* If desire frequency is got. */ + { + *prdiv = prdiv_cur - FSL_FEATURE_MCG_PLL_PRDIV_BASE; + *vdiv = vdiv_cur - FSL_FEATURE_MCG_PLL_VDIV_BASE; + return ret_freq; + } + /* New PRDIV/VDIV is closer. */ + if (diff > desireFreq - ret_freq) + { + diff = desireFreq - ret_freq; + ret_prdiv = prdiv_cur; + ret_vdiv = vdiv_cur; + } + } + vdiv_cur++; + if (vdiv_cur <= (FSL_FEATURE_MCG_PLL_VDIV_BASE + 31U)) + { + ret_freq += ref_div; + /* New PRDIV/VDIV is closer. */ + if (diff > ret_freq - desireFreq) + { + diff = ret_freq - desireFreq; + ret_prdiv = prdiv_cur; + ret_vdiv = vdiv_cur; + } + } + } + + if (0xFFFFFFFFU != diff) + { + /* PRDIV/VDIV found. */ + *prdiv = ret_prdiv - FSL_FEATURE_MCG_PLL_PRDIV_BASE; + *vdiv = ret_vdiv - FSL_FEATURE_MCG_PLL_VDIV_BASE; + ret_freq = (refFreq / ret_prdiv) * ret_vdiv; + return ret_freq; + } + else + { + /* No proper PRDIV/VDIV found. */ + return 0U; + } +} + +/*! + * brief Enables the PLL0 in FLL mode. + * + * This function sets us the PLL0 in FLL mode and reconfigures + * the PLL0. Ensure that the PLL reference + * clock is enabled before calling this function and that the PLL0 is not used as a clock source. + * The function CLOCK_CalcPllDiv gets the correct PLL + * divider values. + * + * param config Pointer to the configuration structure. + */ +void CLOCK_EnablePll0(mcg_pll_config_t const *config) +{ + assert(config); + + uint8_t mcg_c5 = 0U; + + mcg_c5 |= MCG_C5_PRDIV0(config->prdiv); + MCG->C5 = mcg_c5; /* Disable the PLL first. */ + + MCG->C6 = (MCG->C6 & ~MCG_C6_VDIV0_MASK) | MCG_C6_VDIV0(config->vdiv); + + /* Set enable mode. */ + MCG->C5 |= ((uint32_t)kMCG_PllEnableIndependent | (uint32_t)config->enableMode); + + /* Wait for PLL lock. */ + while (!(MCG->S & MCG_S_LOCK0_MASK)) + { + } +} + +/*! + * brief Sets the OSC0 clock monitor mode. + * + * This function sets the OSC0 clock monitor mode. See ref mcg_monitor_mode_t for details. + * + * param mode Monitor mode to set. + */ +void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode) +{ + /* Clear the previous flag, MCG_SC[LOCS0]. */ + MCG->SC &= ~MCG_SC_ATMF_MASK; + + if (kMCG_MonitorNone == mode) + { + MCG->C6 &= ~MCG_C6_CME0_MASK; + } + else + { + if (kMCG_MonitorInt == mode) + { + MCG->C2 &= ~MCG_C2_LOCRE0_MASK; + } + else + { + MCG->C2 |= MCG_C2_LOCRE0_MASK; + } + MCG->C6 |= MCG_C6_CME0_MASK; + } +} + +/*! + * brief Sets the RTC OSC clock monitor mode. + * + * This function sets the RTC OSC clock monitor mode. See ref mcg_monitor_mode_t for details. + * + * param mode Monitor mode to set. + */ +void CLOCK_SetRtcOscMonitorMode(mcg_monitor_mode_t mode) +{ + uint8_t mcg_c8 = MCG->C8; + + mcg_c8 &= ~(MCG_C8_CME1_MASK | MCG_C8_LOCRE1_MASK); + + if (kMCG_MonitorNone != mode) + { + if (kMCG_MonitorReset == mode) + { + mcg_c8 |= MCG_C8_LOCRE1_MASK; + } + mcg_c8 |= MCG_C8_CME1_MASK; + } + MCG->C8 = mcg_c8; +} + +/*! + * brief Sets the PLL0 clock monitor mode. + * + * This function sets the PLL0 clock monitor mode. See ref mcg_monitor_mode_t for details. + * + * param mode Monitor mode to set. + */ +void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode) +{ + uint8_t mcg_c8; + + /* Clear previous flag. */ + MCG->S = MCG_S_LOLS0_MASK; + + if (kMCG_MonitorNone == mode) + { + MCG->C6 &= ~MCG_C6_LOLIE0_MASK; + } + else + { + mcg_c8 = MCG->C8; + + mcg_c8 &= ~MCG_C8_LOCS1_MASK; + + if (kMCG_MonitorInt == mode) + { + mcg_c8 &= ~MCG_C8_LOLRE_MASK; + } + else + { + mcg_c8 |= MCG_C8_LOLRE_MASK; + } + MCG->C8 = mcg_c8; + MCG->C6 |= MCG_C6_LOLIE0_MASK; + } +} + +/*! + * brief Gets the MCG status flags. + * + * This function gets the MCG clock status flags. All status flags are + * returned as a logical OR of the enumeration ref _mcg_status_flags_t. To + * check a specific flag, compare the return value with the flag. + * + * Example: + * code + // To check the clock lost lock status of OSC0 and PLL0. + uint32_t mcgFlags; + + mcgFlags = CLOCK_GetStatusFlags(); + + if (mcgFlags & kMCG_Osc0LostFlag) + { + // OSC0 clock lock lost. Do something. + } + if (mcgFlags & kMCG_Pll0LostFlag) + { + // PLL0 clock lock lost. Do something. + } + endcode + * + * return Logical OR value of the ref _mcg_status_flags_t. + */ +uint32_t CLOCK_GetStatusFlags(void) +{ + uint32_t ret = 0U; + uint8_t mcg_s = MCG->S; + + if (MCG->SC & MCG_SC_LOCS0_MASK) + { + ret |= kMCG_Osc0LostFlag; + } + if (mcg_s & MCG_S_OSCINIT0_MASK) + { + ret |= kMCG_Osc0InitFlag; + } + if (MCG->C8 & MCG_C8_LOCS1_MASK) + { + ret |= kMCG_RtcOscLostFlag; + } + if (mcg_s & MCG_S_LOLS0_MASK) + { + ret |= kMCG_Pll0LostFlag; + } + if (mcg_s & MCG_S_LOCK0_MASK) + { + ret |= kMCG_Pll0LockFlag; + } + return ret; +} + +/*! + * brief Clears the MCG status flags. + * + * This function clears the MCG clock lock lost status. The parameter is a logical + * OR value of the flags to clear. See ref _mcg_status_flags_t. + * + * Example: + * code + // To clear the clock lost lock status flags of OSC0 and PLL0. + + CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag); + endcode + * + * param mask The status flags to clear. This is a logical OR of members of the + * enumeration ref _mcg_status_flags_t. + */ +void CLOCK_ClearStatusFlags(uint32_t mask) +{ + uint8_t reg; + + if (mask & kMCG_Osc0LostFlag) + { + MCG->SC &= ~MCG_SC_ATMF_MASK; + } + if (mask & kMCG_RtcOscLostFlag) + { + reg = MCG->C8; + MCG->C8 = reg; + } + if (mask & kMCG_Pll0LostFlag) + { + MCG->S = MCG_S_LOLS0_MASK; + } +} + +/*! + * brief Initializes the OSC0. + * + * This function initializes the OSC0 according to the board configuration. + * + * param config Pointer to the OSC0 configuration structure. + */ +void CLOCK_InitOsc0(osc_config_t const *config) +{ + uint8_t range = CLOCK_GetOscRangeFromFreq(config->freq); + + OSC_SetCapLoad(OSC0, config->capLoad); + OSC_SetExtRefClkConfig(OSC0, &config->oscerConfig); + + MCG->C2 = ((MCG->C2 & ~OSC_MODE_MASK) | MCG_C2_RANGE(range) | (uint8_t)config->workMode); + + if ((kOSC_ModeExt != config->workMode) && (OSC0->CR & OSC_CR_ERCLKEN_MASK)) + { + /* Wait for stable. */ + while (!(MCG->S & MCG_S_OSCINIT0_MASK)) + { + } + } +} + +/*! + * brief Deinitializes the OSC0. + * + * This function deinitializes the OSC0. + */ +void CLOCK_DeinitOsc0(void) +{ + OSC0->CR = 0U; + MCG->C2 &= ~OSC_MODE_MASK; +} + +/*! + * brief Auto trims the internal reference clock. + * + * This function trims the internal reference clock by using the external clock. If + * successful, it returns the kStatus_Success and the frequency after + * trimming is received in the parameter p actualFreq. If an error occurs, + * the error code is returned. + * + * param extFreq External clock frequency, which should be a bus clock. + * param desireFreq Frequency to trim to. + * param actualFreq Actual frequency after trimming. + * param atms Trim fast or slow internal reference clock. + * retval kStatus_Success ATM success. + * retval kStatus_MCG_AtmBusClockInvalid The bus clock is not in allowed range for the ATM. + * retval kStatus_MCG_AtmDesiredFreqInvalid MCGIRCLK could not be trimmed to the desired frequency. + * retval kStatus_MCG_AtmIrcUsed Could not trim because MCGIRCLK is used as a bus clock source. + * retval kStatus_MCG_AtmHardwareFail Hardware fails while trimming. + */ +status_t CLOCK_TrimInternalRefClk(uint32_t extFreq, uint32_t desireFreq, uint32_t *actualFreq, mcg_atm_select_t atms) +{ + uint32_t multi; /* extFreq / desireFreq */ + uint32_t actv; /* Auto trim value. */ + uint8_t mcg_sc; + + static const uint32_t trimRange[2][2] = { + /* Min Max */ + {TRIM_SIRC_MIN, TRIM_SIRC_MAX}, /* Slow IRC. */ + {TRIM_FIRC_MIN, TRIM_FIRC_MAX} /* Fast IRC. */ + }; + + if ((extFreq > TRIM_REF_CLK_MAX) || (extFreq < TRIM_REF_CLK_MIN)) + { + return kStatus_MCG_AtmBusClockInvalid; + } + + /* Check desired frequency range. */ + if ((desireFreq < trimRange[atms][0]) || (desireFreq > trimRange[atms][1])) + { + return kStatus_MCG_AtmDesiredFreqInvalid; + } + + /* + Make sure internal reference clock is not used to generate bus clock. + Here only need to check (MCG_S_IREFST == 1). + */ + if (MCG_S_IREFST(kMCG_FllSrcInternal) == (MCG->S & MCG_S_IREFST_MASK)) + { + return kStatus_MCG_AtmIrcUsed; + } + + multi = extFreq / desireFreq; + actv = multi * 21U; + + if (kMCG_AtmSel4m == atms) + { + actv *= 128U; + } + + /* Now begin to start trim. */ + MCG->ATCVL = (uint8_t)actv; + MCG->ATCVH = (uint8_t)(actv >> 8U); + + mcg_sc = MCG->SC; + mcg_sc &= ~(MCG_SC_ATMS_MASK | MCG_SC_LOCS0_MASK); + mcg_sc |= (MCG_SC_ATMF_MASK | MCG_SC_ATMS(atms)); + MCG->SC = (mcg_sc | MCG_SC_ATME_MASK); + + /* Wait for finished. */ + while (MCG->SC & MCG_SC_ATME_MASK) + { + } + + /* Error occurs? */ + if (MCG->SC & MCG_SC_ATMF_MASK) + { + /* Clear the failed flag. */ + MCG->SC = mcg_sc; + return kStatus_MCG_AtmHardwareFail; + } + + *actualFreq = extFreq / multi; + + if (kMCG_AtmSel4m == atms) + { + s_fastIrcFreq = *actualFreq; + } + else + { + s_slowIrcFreq = *actualFreq; + } + + return kStatus_Success; +} + +/*! + * brief Gets the current MCG mode. + * + * This function checks the MCG registers and determines the current MCG mode. + * + * return Current MCG mode or error code; See ref mcg_mode_t. + */ +mcg_mode_t CLOCK_GetMode(void) +{ + mcg_mode_t mode = kMCG_ModeError; + uint32_t clkst = MCG_S_CLKST_VAL; + uint32_t irefst = MCG_S_IREFST_VAL; + uint32_t lp = MCG_C2_LP_VAL; + uint32_t pllst = MCG_S_PLLST_VAL; + + /*------------------------------------------------------------------ + Mode and Registers + ____________________________________________________________________ + + Mode | CLKST | IREFST | PLLST | LP + ____________________________________________________________________ + + FEI | 00(FLL) | 1(INT) | 0(FLL) | X + ____________________________________________________________________ + + FEE | 00(FLL) | 0(EXT) | 0(FLL) | X + ____________________________________________________________________ + + FBE | 10(EXT) | 0(EXT) | 0(FLL) | 0(NORMAL) + ____________________________________________________________________ + + FBI | 01(INT) | 1(INT) | 0(FLL) | 0(NORMAL) + ____________________________________________________________________ + + BLPI | 01(INT) | 1(INT) | 0(FLL) | 1(LOW POWER) + ____________________________________________________________________ + + BLPE | 10(EXT) | 0(EXT) | X | 1(LOW POWER) + ____________________________________________________________________ + + PEE | 11(PLL) | 0(EXT) | 1(PLL) | X + ____________________________________________________________________ + + PBE | 10(EXT) | 0(EXT) | 1(PLL) | O(NORMAL) + ____________________________________________________________________ + + PBI | 01(INT) | 1(INT) | 1(PLL) | 0(NORMAL) + ____________________________________________________________________ + + PEI | 11(PLL) | 1(INT) | 1(PLL) | X + ____________________________________________________________________ + + ----------------------------------------------------------------------*/ + + switch (clkst) + { + case kMCG_ClkOutStatFll: + if (kMCG_FllSrcExternal == irefst) + { + mode = kMCG_ModeFEE; + } + else + { + mode = kMCG_ModeFEI; + } + break; + case kMCG_ClkOutStatInt: + if (lp) + { + mode = kMCG_ModeBLPI; + } + else + { + { + mode = kMCG_ModeFBI; + } + } + break; + case kMCG_ClkOutStatExt: + if (lp) + { + mode = kMCG_ModeBLPE; + } + else + { + if (kMCG_PllstPll == pllst) + { + mode = kMCG_ModePBE; + } + else + { + mode = kMCG_ModeFBE; + } + } + break; + case kMCG_ClkOutStatPll: + { + mode = kMCG_ModePEE; + } + break; + default: + break; + } + + return mode; +} + +/*! + * brief Sets the MCG to FEI mode. + * + * This function sets the MCG to FEI mode. If setting to FEI mode fails + * from the current mode, this function returns an error. + * + * param dmx32 DMX32 in FEI mode. + * param drs The DCO range selection. + * param fllStableDelay Delay function to ensure that the FLL is stable. Passing + * NULL does not cause a delay. + * retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * retval kStatus_Success Switched to the target mode successfully. + * note If p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed + * to a frequency above 32768 Hz. + */ +status_t CLOCK_SetFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) +{ + uint8_t mcg_c4; + bool change_drs = false; + +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + mcg_mode_t mode = CLOCK_GetMode(); + if (!((kMCG_ModeFEI == mode) || (kMCG_ModeFBI == mode) || (kMCG_ModeFBE == mode) || (kMCG_ModeFEE == mode))) + { + return kStatus_MCG_ModeUnreachable; + } +#endif + mcg_c4 = MCG->C4; + + /* + Errata: ERR007993 + Workaround: Invert MCG_C4[DMX32] or change MCG_C4[DRST_DRS] before + reference clock source changes, then reset to previous value after + reference clock changes. + */ + if (kMCG_FllSrcExternal == MCG_S_IREFST_VAL) + { + change_drs = true; + /* Change the LSB of DRST_DRS. */ + MCG->C4 ^= (1U << MCG_C4_DRST_DRS_SHIFT); + } + + /* Set CLKS and IREFS. */ + MCG->C1 = + ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK))) | (MCG_C1_CLKS(kMCG_ClkOutSrcOut) /* CLKS = 0 */ + | MCG_C1_IREFS(kMCG_FllSrcInternal)); /* IREFS = 1 */ + + /* Wait and check status. */ + while (kMCG_FllSrcInternal != MCG_S_IREFST_VAL) + { + } + + /* Errata: ERR007993 */ + if (change_drs) + { + MCG->C4 = mcg_c4; + } + + /* In FEI mode, the MCG_C4[DMX32] is set to 0U. */ + MCG->C4 = (mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DMX32(dmx32) | MCG_C4_DRST_DRS(drs)); + + /* Check MCG_S[CLKST] */ + while (kMCG_ClkOutStatFll != MCG_S_CLKST_VAL) + { + } + + /* Wait for FLL stable time. */ + if (fllStableDelay) + { + fllStableDelay(); + } + + return kStatus_Success; +} + +/*! + * brief Sets the MCG to FEE mode. + * + * This function sets the MCG to FEE mode. If setting to FEE mode fails + * from the current mode, this function returns an error. + * + * param frdiv FLL reference clock divider setting, FRDIV. + * param dmx32 DMX32 in FEE mode. + * param drs The DCO range selection. + * param fllStableDelay Delay function to make sure FLL is stable. Passing + * NULL does not cause a delay. + * + * retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_SetFeeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) +{ + uint8_t mcg_c4; + bool change_drs = false; + +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + mcg_mode_t mode = CLOCK_GetMode(); + if (!((kMCG_ModeFEE == mode) || (kMCG_ModeFBI == mode) || (kMCG_ModeFBE == mode) || (kMCG_ModeFEI == mode))) + { + return kStatus_MCG_ModeUnreachable; + } +#endif + mcg_c4 = MCG->C4; + + /* + Errata: ERR007993 + Workaround: Invert MCG_C4[DMX32] or change MCG_C4[DRST_DRS] before + reference clock source changes, then reset to previous value after + reference clock changes. + */ + if (kMCG_FllSrcInternal == MCG_S_IREFST_VAL) + { + change_drs = true; + /* Change the LSB of DRST_DRS. */ + MCG->C4 ^= (1U << MCG_C4_DRST_DRS_SHIFT); + } + + /* Set CLKS and IREFS. */ + MCG->C1 = ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK)) | + (MCG_C1_CLKS(kMCG_ClkOutSrcOut) /* CLKS = 0 */ + | MCG_C1_FRDIV(frdiv) /* FRDIV */ + | MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */ + + /* If use external crystal as clock source, wait for it stable. */ + if (MCG_C7_OSCSEL(kMCG_OscselOsc) == (MCG->C7 & MCG_C7_OSCSEL_MASK)) + { + if (MCG->C2 & MCG_C2_EREFS_MASK) + { + while (!(MCG->S & MCG_S_OSCINIT0_MASK)) + { + } + } + } + + /* Wait and check status. */ + while (kMCG_FllSrcExternal != MCG_S_IREFST_VAL) + { + } + + /* Errata: ERR007993 */ + if (change_drs) + { + MCG->C4 = mcg_c4; + } + + /* Set DRS and DMX32. */ + mcg_c4 = ((mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DMX32(dmx32) | MCG_C4_DRST_DRS(drs))); + MCG->C4 = mcg_c4; + + /* Wait for DRST_DRS update. */ + while (MCG->C4 != mcg_c4) + { + } + + /* Check MCG_S[CLKST] */ + while (kMCG_ClkOutStatFll != MCG_S_CLKST_VAL) + { + } + + /* Wait for FLL stable time. */ + if (fllStableDelay) + { + fllStableDelay(); + } + + return kStatus_Success; +} + +/*! + * brief Sets the MCG to FBI mode. + * + * This function sets the MCG to FBI mode. If setting to FBI mode fails + * from the current mode, this function returns an error. + * + * param dmx32 DMX32 in FBI mode. + * param drs The DCO range selection. + * param fllStableDelay Delay function to make sure FLL is stable. If the FLL + * is not used in FBI mode, this parameter can be NULL. Passing + * NULL does not cause a delay. + * retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * retval kStatus_Success Switched to the target mode successfully. + * note If p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed + * to frequency above 32768 Hz. + */ +status_t CLOCK_SetFbiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) +{ + uint8_t mcg_c4; + bool change_drs = false; + +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + mcg_mode_t mode = CLOCK_GetMode(); + + if (!((kMCG_ModeFEE == mode) || (kMCG_ModeFBI == mode) || (kMCG_ModeFBE == mode) || (kMCG_ModeFEI == mode) || + (kMCG_ModeBLPI == mode))) + + { + return kStatus_MCG_ModeUnreachable; + } +#endif + + mcg_c4 = MCG->C4; + + MCG->C2 &= ~MCG_C2_LP_MASK; /* Disable lowpower. */ + + /* + Errata: ERR007993 + Workaround: Invert MCG_C4[DMX32] or change MCG_C4[DRST_DRS] before + reference clock source changes, then reset to previous value after + reference clock changes. + */ + if (kMCG_FllSrcExternal == MCG_S_IREFST_VAL) + { + change_drs = true; + /* Change the LSB of DRST_DRS. */ + MCG->C4 ^= (1U << MCG_C4_DRST_DRS_SHIFT); + } + + /* Set CLKS and IREFS. */ + MCG->C1 = + ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK)) | (MCG_C1_CLKS(kMCG_ClkOutSrcInternal) /* CLKS = 1 */ + | MCG_C1_IREFS(kMCG_FllSrcInternal))); /* IREFS = 1 */ + + /* Wait and check status. */ + while (kMCG_FllSrcInternal != MCG_S_IREFST_VAL) + { + } + + /* Errata: ERR007993 */ + if (change_drs) + { + MCG->C4 = mcg_c4; + } + + while (kMCG_ClkOutStatInt != MCG_S_CLKST_VAL) + { + } + + MCG->C4 = (mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DMX32(dmx32) | MCG_C4_DRST_DRS(drs)); + + /* Wait for FLL stable time. */ + if (fllStableDelay) + { + fllStableDelay(); + } + + return kStatus_Success; +} + +/*! + * brief Sets the MCG to FBE mode. + * + * This function sets the MCG to FBE mode. If setting to FBE mode fails + * from the current mode, this function returns an error. + * + * param frdiv FLL reference clock divider setting, FRDIV. + * param dmx32 DMX32 in FBE mode. + * param drs The DCO range selection. + * param fllStableDelay Delay function to make sure FLL is stable. If the FLL + * is not used in FBE mode, this parameter can be NULL. Passing NULL + * does not cause a delay. + * retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_SetFbeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) +{ + uint8_t mcg_c4; + bool change_drs = false; + +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + mcg_mode_t mode = CLOCK_GetMode(); + if (!((kMCG_ModeFEE == mode) || (kMCG_ModeFBI == mode) || (kMCG_ModeFBE == mode) || (kMCG_ModeFEI == mode) || + (kMCG_ModePBE == mode) || (kMCG_ModeBLPE == mode))) + { + return kStatus_MCG_ModeUnreachable; + } +#endif + + /* Change to FLL mode. */ + MCG->C6 &= ~MCG_C6_PLLS_MASK; + while (MCG->S & MCG_S_PLLST_MASK) + { + } + + /* Set LP bit to enable the FLL */ + MCG->C2 &= ~MCG_C2_LP_MASK; + + mcg_c4 = MCG->C4; + + /* + Errata: ERR007993 + Workaround: Invert MCG_C4[DMX32] or change MCG_C4[DRST_DRS] before + reference clock source changes, then reset to previous value after + reference clock changes. + */ + if (kMCG_FllSrcInternal == MCG_S_IREFST_VAL) + { + change_drs = true; + /* Change the LSB of DRST_DRS. */ + MCG->C4 ^= (1U << MCG_C4_DRST_DRS_SHIFT); + } + + /* Set CLKS and IREFS. */ + MCG->C1 = ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK)) | + (MCG_C1_CLKS(kMCG_ClkOutSrcExternal) /* CLKS = 2 */ + | MCG_C1_FRDIV(frdiv) /* FRDIV = frdiv */ + | MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */ + + /* If use external crystal as clock source, wait for it stable. */ + if (MCG_C7_OSCSEL(kMCG_OscselOsc) == (MCG->C7 & MCG_C7_OSCSEL_MASK)) + { + if (MCG->C2 & MCG_C2_EREFS_MASK) + { + while (!(MCG->S & MCG_S_OSCINIT0_MASK)) + { + } + } + } + + /* Wait for Reference clock Status bit to clear */ + while (kMCG_FllSrcExternal != MCG_S_IREFST_VAL) + { + } + + /* Errata: ERR007993 */ + if (change_drs) + { + MCG->C4 = mcg_c4; + } + + /* Set DRST_DRS and DMX32. */ + mcg_c4 = ((mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DMX32(dmx32) | MCG_C4_DRST_DRS(drs))); + + /* Wait for clock status bits to show clock source is ext ref clk */ + while (kMCG_ClkOutStatExt != MCG_S_CLKST_VAL) + { + } + + /* Wait for fll stable time. */ + if (fllStableDelay) + { + fllStableDelay(); + } + + return kStatus_Success; +} + +/*! + * brief Sets the MCG to BLPI mode. + * + * This function sets the MCG to BLPI mode. If setting to BLPI mode fails + * from the current mode, this function returns an error. + * + * retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_SetBlpiMode(void) +{ +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + if (MCG_S_CLKST_VAL != kMCG_ClkOutStatInt) + { + return kStatus_MCG_ModeUnreachable; + } +#endif /* MCG_CONFIG_CHECK_PARAM */ + + /* Set LP. */ + MCG->C2 |= MCG_C2_LP_MASK; + + return kStatus_Success; +} + +/*! + * brief Sets the MCG to BLPE mode. + * + * This function sets the MCG to BLPE mode. If setting to BLPE mode fails + * from the current mode, this function returns an error. + * + * retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_SetBlpeMode(void) +{ +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + if (MCG_S_CLKST_VAL != kMCG_ClkOutStatExt) + { + return kStatus_MCG_ModeUnreachable; + } +#endif + + /* Set LP bit to enter BLPE mode. */ + MCG->C2 |= MCG_C2_LP_MASK; + + return kStatus_Success; +} + +/*! + * brief Sets the MCG to PBE mode. + * + * This function sets the MCG to PBE mode. If setting to PBE mode fails + * from the current mode, this function returns an error. + * + * param pllcs The PLL selection, PLLCS. + * param config Pointer to the PLL configuration. + * retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * retval kStatus_Success Switched to the target mode successfully. + * + * note + * 1. The parameter \c pllcs selects the PLL. For platforms with + * only one PLL, the parameter pllcs is kept for interface compatibility. + * 2. The parameter \c config is the PLL configuration structure. On some + * platforms, it is possible to choose the external PLL directly, which renders the + * configuration structure not necessary. In this case, pass in NULL. + * For example: CLOCK_SetPbeMode(kMCG_OscselOsc, kMCG_PllClkSelExtPll, NULL); + */ +status_t CLOCK_SetPbeMode(mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config) +{ + assert(config); + + /* + This function is designed to change MCG to PBE mode from PEE/BLPE/FBE, + but with this workflow, the source mode could be all modes except PEI/PBI. + */ + MCG->C2 &= ~MCG_C2_LP_MASK; /* Disable lowpower. */ + + /* Change to use external clock first. */ + MCG->C1 = ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK)) | MCG_C1_CLKS(kMCG_ClkOutSrcExternal)); + + /* Wait for CLKST clock status bits to show clock source is ext ref clk */ + while ((MCG->S & (MCG_S_IREFST_MASK | MCG_S_CLKST_MASK)) != + (MCG_S_IREFST(kMCG_FllSrcExternal) | MCG_S_CLKST(kMCG_ClkOutStatExt))) + { + } + + /* Disable PLL first, then configure PLL. */ + MCG->C6 &= ~MCG_C6_PLLS_MASK; + while (MCG->S & MCG_S_PLLST_MASK) + { + } + + /* Configure the PLL. */ + { + CLOCK_EnablePll0(config); + } + + /* Change to PLL mode. */ + MCG->C6 |= MCG_C6_PLLS_MASK; + + /* Wait for PLL mode changed. */ + while (!(MCG->S & MCG_S_PLLST_MASK)) + { + } + + return kStatus_Success; +} + +/*! + * brief Sets the MCG to PEE mode. + * + * This function sets the MCG to PEE mode. + * + * retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * retval kStatus_Success Switched to the target mode successfully. + * + * note This function only changes the CLKS to use the PLL/FLL output. If the + * PRDIV/VDIV are different than in the PBE mode, set them up + * in PBE mode and wait. When the clock is stable, switch to PEE mode. + */ +status_t CLOCK_SetPeeMode(void) +{ +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + mcg_mode_t mode = CLOCK_GetMode(); + if (kMCG_ModePBE != mode) + { + return kStatus_MCG_ModeUnreachable; + } +#endif + + /* Change to use PLL/FLL output clock first. */ + MCG->C1 = (MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcOut); + + /* Wait for clock status bits to update */ + while (MCG_S_CLKST_VAL != kMCG_ClkOutStatPll) + { + } + + return kStatus_Success; +} + +/*! + * brief Switches the MCG to FBE mode from the external mode. + * + * This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly. + * The external clock is used as the system clock source and PLL is disabled. However, + * the FLL settings are not configured. This is a lite function with a small code size, which is useful + * during the mode switch. For example, to switch from PEE mode to FEI mode: + * + * code + * CLOCK_ExternalModeToFbeModeQuick(); + * CLOCK_SetFeiMode(...); + * endcode + * + * retval kStatus_Success Switched successfully. + * retval kStatus_MCG_ModeInvalid If the current mode is not an external mode, do not call this function. + */ +status_t CLOCK_ExternalModeToFbeModeQuick(void) +{ +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + if (MCG->S & MCG_S_IREFST_MASK) + { + return kStatus_MCG_ModeInvalid; + } +#endif /* MCG_CONFIG_CHECK_PARAM */ + + /* Disable low power */ + MCG->C2 &= ~MCG_C2_LP_MASK; + + MCG->C1 = ((MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcExternal)); + while (MCG_S_CLKST_VAL != kMCG_ClkOutStatExt) + { + } + + /* Disable PLL. */ + MCG->C6 &= ~MCG_C6_PLLS_MASK; + while (MCG->S & MCG_S_PLLST_MASK) + { + } + + return kStatus_Success; +} + +/*! + * brief Switches the MCG to FBI mode from internal modes. + * + * This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly. + * The MCGIRCLK is used as the system clock source and PLL is disabled. However, + * FLL settings are not configured. This is a lite function with a small code size, which is useful + * during the mode switch. For example, to switch from PEI mode to FEE mode: + * + * code + * CLOCK_InternalModeToFbiModeQuick(); + * CLOCK_SetFeeMode(...); + * endcode + * + * retval kStatus_Success Switched successfully. + * retval kStatus_MCG_ModeInvalid If the current mode is not an internal mode, do not call this function. + */ +status_t CLOCK_InternalModeToFbiModeQuick(void) +{ +#if (defined(MCG_CONFIG_CHECK_PARAM) && MCG_CONFIG_CHECK_PARAM) + if (!(MCG->S & MCG_S_IREFST_MASK)) + { + return kStatus_MCG_ModeInvalid; + } +#endif + + /* Disable low power */ + MCG->C2 &= ~MCG_C2_LP_MASK; + + MCG->C1 = ((MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcInternal)); + while (MCG_S_CLKST_VAL != kMCG_ClkOutStatInt) + { + } + + return kStatus_Success; +} + +/*! + * brief Sets the MCG to FEI mode during system boot up. + * + * This function sets the MCG to FEI mode from the reset mode. It can also be used to + * set up MCG during system boot up. + * + * param dmx32 DMX32 in FEI mode. + * param drs The DCO range selection. + * param fllStableDelay Delay function to ensure that the FLL is stable. + * + * retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * retval kStatus_Success Switched to the target mode successfully. + * note If p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed + * to frequency above 32768 Hz. + */ +status_t CLOCK_BootToFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) +{ + return CLOCK_SetFeiMode(dmx32, drs, fllStableDelay); +} + +/*! + * brief Sets the MCG to FEE mode during system bootup. + * + * This function sets MCG to FEE mode from the reset mode. It can also be used to + * set up the MCG during system boot up. + * + * param oscsel OSC clock select, OSCSEL. + * param frdiv FLL reference clock divider setting, FRDIV. + * param dmx32 DMX32 in FEE mode. + * param drs The DCO range selection. + * param fllStableDelay Delay function to ensure that the FLL is stable. + * + * retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_BootToFeeMode( + mcg_oscsel_t oscsel, uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) +{ + CLOCK_SetExternalRefClkConfig(oscsel); + + return CLOCK_SetFeeMode(frdiv, dmx32, drs, fllStableDelay); +} + +/*! + * brief Sets the MCG to BLPI mode during system boot up. + * + * This function sets the MCG to BLPI mode from the reset mode. It can also be used to + * set up the MCG during system boot up. + * + * param fcrdiv Fast IRC divider, FCRDIV. + * param ircs The internal reference clock to select, IRCS. + * param ircEnableMode The MCGIRCLK enable mode, OR'ed value of ref _mcg_irclk_enable_mode. + * + * retval kStatus_MCG_SourceUsed Could not change MCGIRCLK setting. + * retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode) +{ + /* If reset mode is FEI mode, set MCGIRCLK and always success. */ + CLOCK_SetInternalRefClkConfig(ircEnableMode, ircs, fcrdiv); + + /* If reset mode is not BLPI, first enter FBI mode. */ + MCG->C1 = (MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcInternal); + while (MCG_S_CLKST_VAL != kMCG_ClkOutStatInt) + { + } + + /* Enter BLPI mode. */ + MCG->C2 |= MCG_C2_LP_MASK; + + return kStatus_Success; +} + +/*! + * brief Sets the MCG to BLPE mode during system boot up. + * + * This function sets the MCG to BLPE mode from the reset mode. It can also be used to + * set up the MCG during system boot up. + * + * param oscsel OSC clock select, MCG_C7[OSCSEL]. + * + * retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel) +{ + CLOCK_SetExternalRefClkConfig(oscsel); + + /* Set to FBE mode. */ + MCG->C1 = + ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK)) | (MCG_C1_CLKS(kMCG_ClkOutSrcExternal) /* CLKS = 2 */ + | MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */ + + /* If use external crystal as clock source, wait for it stable. */ + if (MCG_C7_OSCSEL(kMCG_OscselOsc) == (MCG->C7 & MCG_C7_OSCSEL_MASK)) + { + if (MCG->C2 & MCG_C2_EREFS_MASK) + { + while (!(MCG->S & MCG_S_OSCINIT0_MASK)) + { + } + } + } + + /* Wait for MCG_S[CLKST] and MCG_S[IREFST]. */ + while ((MCG->S & (MCG_S_IREFST_MASK | MCG_S_CLKST_MASK)) != + (MCG_S_IREFST(kMCG_FllSrcExternal) | MCG_S_CLKST(kMCG_ClkOutStatExt))) + { + } + + /* In FBE now, start to enter BLPE. */ + MCG->C2 |= MCG_C2_LP_MASK; + + return kStatus_Success; +} + +/*! + * brief Sets the MCG to PEE mode during system boot up. + * + * This function sets the MCG to PEE mode from reset mode. It can also be used to + * set up the MCG during system boot up. + * + * param oscsel OSC clock select, MCG_C7[OSCSEL]. + * param pllcs The PLL selection, PLLCS. + * param config Pointer to the PLL configuration. + * + * retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_BootToPeeMode(mcg_oscsel_t oscsel, mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config) +{ + assert(config); + + CLOCK_SetExternalRefClkConfig(oscsel); + + CLOCK_SetPbeMode(pllcs, config); + + /* Change to use PLL output clock. */ + MCG->C1 = (MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcOut); + while (MCG_S_CLKST_VAL != kMCG_ClkOutStatPll) + { + } + + return kStatus_Success; +} + +/* + The transaction matrix. It defines the path for mode switch, the row is for + current mode and the column is target mode. + For example, switch from FEI to PEE: + 1. Current mode FEI, next mode is mcgModeMatrix[FEI][PEE] = FBE, so swith to FBE. + 2. Current mode FBE, next mode is mcgModeMatrix[FBE][PEE] = PBE, so swith to PBE. + 3. Current mode PBE, next mode is mcgModeMatrix[PBE][PEE] = PEE, so swith to PEE. + Thus the MCG mode has changed from FEI to PEE. + */ +static const mcg_mode_t mcgModeMatrix[8][8] = { + {kMCG_ModeFEI, kMCG_ModeFBI, kMCG_ModeFBI, kMCG_ModeFEE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, + kMCG_ModeFBE}, /* FEI */ + {kMCG_ModeFEI, kMCG_ModeFBI, kMCG_ModeBLPI, kMCG_ModeFEE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, + kMCG_ModeFBE}, /* FBI */ + {kMCG_ModeFBI, kMCG_ModeFBI, kMCG_ModeBLPI, kMCG_ModeFBI, kMCG_ModeFBI, kMCG_ModeFBI, kMCG_ModeFBI, + kMCG_ModeFBI}, /* BLPI */ + {kMCG_ModeFEI, kMCG_ModeFBI, kMCG_ModeFBI, kMCG_ModeFEE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, + kMCG_ModeFBE}, /* FEE */ + {kMCG_ModeFEI, kMCG_ModeFBI, kMCG_ModeFBI, kMCG_ModeFEE, kMCG_ModeFBE, kMCG_ModeBLPE, kMCG_ModePBE, + kMCG_ModePBE}, /* FBE */ + {kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeBLPE, kMCG_ModePBE, + kMCG_ModePBE}, /* BLPE */ + {kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeFBE, kMCG_ModeBLPE, kMCG_ModePBE, + kMCG_ModePEE}, /* PBE */ + {kMCG_ModePBE, kMCG_ModePBE, kMCG_ModePBE, kMCG_ModePBE, kMCG_ModePBE, kMCG_ModePBE, kMCG_ModePBE, + kMCG_ModePBE} /* PEE */ + /* FEI FBI BLPI FEE FBE BLPE PBE PEE */ +}; + +/*! + * brief Sets the MCG to a target mode. + * + * This function sets MCG to a target mode defined by the configuration + * structure. If switching to the target mode fails, this function + * chooses the correct path. + * + * param config Pointer to the target MCG mode configuration structure. + * return Return kStatus_Success if switched successfully; Otherwise, it returns an error code #_mcg_status. + * + * note If the external clock is used in the target mode, ensure that it is + * enabled. For example, if the OSC0 is used, set up OSC0 correctly before calling this + * function. + */ +status_t CLOCK_SetMcgConfig(const mcg_config_t *config) +{ + mcg_mode_t next_mode; + status_t status = kStatus_Success; + + mcg_pll_clk_select_t pllcs = kMCG_PllClkSelPll0; + + /* If need to change external clock, MCG_C7[OSCSEL]. */ + if (MCG_C7_OSCSEL_VAL != config->oscsel) + { + /* If external clock is in use, change to FEI first. */ + if (kMCG_FllSrcExternal == MCG_S_IREFST_VAL) + { + CLOCK_ExternalModeToFbeModeQuick(); + CLOCK_SetFeiMode(config->dmx32, config->drs, NULL); + } + + CLOCK_SetExternalRefClkConfig(config->oscsel); + } + + /* Re-configure MCGIRCLK, if MCGIRCLK is used as system clock source, then change to FEI/PEI first. */ + if (MCG_S_CLKST_VAL == kMCG_ClkOutStatInt) + { + MCG->C2 &= ~MCG_C2_LP_MASK; /* Disable lowpower. */ + + { + CLOCK_SetFeiMode(config->dmx32, config->drs, CLOCK_FllStableDelay); + } + } + + /* Configure MCGIRCLK. */ + CLOCK_SetInternalRefClkConfig(config->irclkEnableMode, config->ircs, config->fcrdiv); + + next_mode = CLOCK_GetMode(); + + do + { + next_mode = mcgModeMatrix[next_mode][config->mcgMode]; + + switch (next_mode) + { + case kMCG_ModeFEI: + status = CLOCK_SetFeiMode(config->dmx32, config->drs, CLOCK_FllStableDelay); + break; + case kMCG_ModeFEE: + status = CLOCK_SetFeeMode(config->frdiv, config->dmx32, config->drs, CLOCK_FllStableDelay); + break; + case kMCG_ModeFBI: + status = CLOCK_SetFbiMode(config->dmx32, config->drs, NULL); + break; + case kMCG_ModeFBE: + status = CLOCK_SetFbeMode(config->frdiv, config->dmx32, config->drs, NULL); + break; + case kMCG_ModeBLPI: + status = CLOCK_SetBlpiMode(); + break; + case kMCG_ModeBLPE: + status = CLOCK_SetBlpeMode(); + break; + case kMCG_ModePBE: + /* If target mode is not PBE or PEE, then only need to set CLKS = EXT here. */ + if ((kMCG_ModePEE == config->mcgMode) || (kMCG_ModePBE == config->mcgMode)) + { + { + status = CLOCK_SetPbeMode(pllcs, &config->pll0Config); + } + } + else + { + MCG->C1 = ((MCG->C1 & ~MCG_C1_CLKS_MASK) | MCG_C1_CLKS(kMCG_ClkOutSrcExternal)); + while (MCG_S_CLKST_VAL != kMCG_ClkOutStatExt) + { + } + } + break; + case kMCG_ModePEE: + status = CLOCK_SetPeeMode(); + break; + default: + break; + } + if (kStatus_Success != status) + { + return status; + } + } while (next_mode != config->mcgMode); + + if (config->pll0Config.enableMode & kMCG_PllEnableIndependent) + { + CLOCK_EnablePll0(&config->pll0Config); + } + else + { + MCG->C5 &= ~(uint32_t)kMCG_PllEnableIndependent; + } + return kStatus_Success; +} diff --git a/drivers/fsl_clock.h b/drivers/fsl_clock.h new file mode 100644 index 0000000..13ac8fa --- /dev/null +++ b/drivers/fsl_clock.h @@ -0,0 +1,1546 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright (c) 2016 - 2017 , NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FSL_CLOCK_H_ +#define _FSL_CLOCK_H_ + +#include "fsl_common.h" + +/*! @addtogroup clock */ +/*! @{ */ + +/*! @file */ + +/******************************************************************************* + * Configurations + ******************************************************************************/ + +/*! @brief Configures whether to check a parameter in a function. + * + * Some MCG settings must be changed with conditions, for example: + * 1. MCGIRCLK settings, such as the source, divider, and the trim value should not change when + * MCGIRCLK is used as a system clock source. + * 2. MCG_C7[OSCSEL] should not be changed when the external reference clock is used + * as a system clock source. For example, in FBE/BLPE/PBE modes. + * 3. The users should only switch between the supported clock modes. + * + * MCG functions check the parameter and MCG status before setting, if not allowed + * to change, the functions return error. The parameter checking increases code size, + * if code size is a critical requirement, change #MCG_CONFIG_CHECK_PARAM to 0 to + * disable parameter checking. + */ +#ifndef MCG_CONFIG_CHECK_PARAM +#define MCG_CONFIG_CHECK_PARAM 0U +#endif + +/*! @brief Configure whether driver controls clock + * + * When set to 0, peripheral drivers will enable clock in initialize function + * and disable clock in de-initialize function. When set to 1, peripheral + * driver will not control the clock, application could control the clock out of + * the driver. + * + * @note All drivers share this feature switcher. If it is set to 1, application + * should handle clock enable and disable for all drivers. + */ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)) +#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0 +#endif + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief CLOCK driver version 2.2.1. */ +#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 1)) +/*@}*/ + +/*! @brief External XTAL0 (OSC0) clock frequency. + * + * The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the + * function CLOCK_SetXtal0Freq to set the value in the clock driver. For example, + * if XTAL0 is 8 MHz: + * @code + * CLOCK_InitOsc0(...); // Set up the OSC0 + * CLOCK_SetXtal0Freq(80000000); // Set the XTAL0 value to the clock driver. + * @endcode + * + * This is important for the multicore platforms where only one core needs to set up the + * OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq + * to get a valid clock frequency. + */ +extern volatile uint32_t g_xtal0Freq; + +/*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency. + * + * The XTAL32/EXTAL32/RTC_CLKIN clock frequency in Hz. When the clock is set up, use the + * function CLOCK_SetXtal32Freq to set the value in the clock driver. + * + * This is important for the multicore platforms where only one core needs to set up + * the clock. All other cores need to call the CLOCK_SetXtal32Freq + * to get a valid clock frequency. + */ +extern volatile uint32_t g_xtal32Freq; + +/*! @brief IRC48M clock frequency in Hz. */ +#define MCG_INTERNAL_IRC_48M 48000000U + +#if (defined(OSC) && !(defined(OSC0))) +#define OSC0 OSC +#endif + +/*! @brief Clock ip name array for DMAMUX. */ +#define DMAMUX_CLOCKS \ + { \ + kCLOCK_Dmamux0 \ + } + +/*! @brief Clock ip name array for RTC. */ +#define RTC_CLOCKS \ + { \ + kCLOCK_Rtc0 \ + } + +/*! @brief Clock ip name array for ENET. */ +#define ENET_CLOCKS \ + { \ + kCLOCK_Enet0 \ + } + +/*! @brief Clock ip name array for PORT. */ +#define PORT_CLOCKS \ + { \ + kCLOCK_PortA, kCLOCK_PortB, kCLOCK_PortC, kCLOCK_PortD, kCLOCK_PortE \ + } + +/*! @brief Clock ip name array for SAI. */ +#define SAI_CLOCKS \ + { \ + kCLOCK_Sai0 \ + } + +/*! @brief Clock ip name array for FLEXBUS. */ +#define FLEXBUS_CLOCKS \ + { \ + kCLOCK_Flexbus0 \ + } + +/*! @brief Clock ip name array for EWM. */ +#define EWM_CLOCKS \ + { \ + kCLOCK_Ewm0 \ + } + +/*! @brief Clock ip name array for PIT. */ +#define PIT_CLOCKS \ + { \ + kCLOCK_Pit0 \ + } + +/*! @brief Clock ip name array for DSPI. */ +#define DSPI_CLOCKS \ + { \ + kCLOCK_Spi0, kCLOCK_Spi1, kCLOCK_Spi2 \ + } + +/*! @brief Clock ip name array for LPTMR. */ +#define LPTMR_CLOCKS \ + { \ + kCLOCK_Lptmr0 \ + } + +/*! @brief Clock ip name array for SDHC. */ +#define SDHC_CLOCKS \ + { \ + kCLOCK_Sdhc0 \ + } + +/*! @brief Clock ip name array for FTM. */ +#define FTM_CLOCKS \ + { \ + kCLOCK_Ftm0, kCLOCK_Ftm1, kCLOCK_Ftm2, kCLOCK_Ftm3 \ + } + +/*! @brief Clock ip name array for EDMA. */ +#define EDMA_CLOCKS \ + { \ + kCLOCK_Dma0 \ + } + +/*! @brief Clock ip name array for FLEXCAN. */ +#define FLEXCAN_CLOCKS \ + { \ + kCLOCK_Flexcan0 \ + } + +/*! @brief Clock ip name array for DAC. */ +#define DAC_CLOCKS \ + { \ + kCLOCK_Dac0, kCLOCK_Dac1 \ + } + +/*! @brief Clock ip name array for ADC16. */ +#define ADC16_CLOCKS \ + { \ + kCLOCK_Adc0, kCLOCK_Adc1 \ + } + +/*! @brief Clock ip name array for MPU. */ +#define SYSMPU_CLOCKS \ + { \ + kCLOCK_Sysmpu0 \ + } + +/*! @brief Clock ip name array for VREF. */ +#define VREF_CLOCKS \ + { \ + kCLOCK_Vref0 \ + } + +/*! @brief Clock ip name array for CMT. */ +#define CMT_CLOCKS \ + { \ + kCLOCK_Cmt0 \ + } + +/*! @brief Clock ip name array for UART. */ +#define UART_CLOCKS \ + { \ + kCLOCK_Uart0, kCLOCK_Uart1, kCLOCK_Uart2, kCLOCK_Uart3, kCLOCK_Uart4, kCLOCK_Uart5 \ + } + +/*! @brief Clock ip name array for RNGA. */ +#define RNGA_CLOCKS \ + { \ + kCLOCK_Rnga0 \ + } + +/*! @brief Clock ip name array for CRC. */ +#define CRC_CLOCKS \ + { \ + kCLOCK_Crc0 \ + } + +/*! @brief Clock ip name array for I2C. */ +#define I2C_CLOCKS \ + { \ + kCLOCK_I2c0, kCLOCK_I2c1, kCLOCK_I2c2 \ + } + +/*! @brief Clock ip name array for PDB. */ +#define PDB_CLOCKS \ + { \ + kCLOCK_Pdb0 \ + } + +/*! @brief Clock ip name array for FTF. */ +#define FTF_CLOCKS \ + { \ + kCLOCK_Ftf0 \ + } + +/*! @brief Clock ip name array for CMP. */ +#define CMP_CLOCKS \ + { \ + kCLOCK_Cmp0, kCLOCK_Cmp1, kCLOCK_Cmp2 \ + } + +/*! + * @brief LPO clock frequency. + */ +#define LPO_CLK_FREQ 1000U + +/*! @brief Peripherals clock source definition. */ +#define SYS_CLK kCLOCK_CoreSysClk +#define BUS_CLK kCLOCK_BusClk + +#define I2C0_CLK_SRC BUS_CLK +#define I2C1_CLK_SRC BUS_CLK +#define I2C2_CLK_SRC BUS_CLK +#define DSPI0_CLK_SRC BUS_CLK +#define DSPI1_CLK_SRC BUS_CLK +#define DSPI2_CLK_SRC BUS_CLK +#define UART0_CLK_SRC SYS_CLK +#define UART1_CLK_SRC SYS_CLK +#define UART2_CLK_SRC BUS_CLK +#define UART3_CLK_SRC BUS_CLK +#define UART4_CLK_SRC BUS_CLK +#define UART5_CLK_SRC BUS_CLK + +/*! @brief Clock name used to get clock frequency. */ +typedef enum _clock_name +{ + + /* ----------------------------- System layer clock -------------------------------*/ + kCLOCK_CoreSysClk, /*!< Core/system clock */ + kCLOCK_PlatClk, /*!< Platform clock */ + kCLOCK_BusClk, /*!< Bus clock */ + kCLOCK_FlexBusClk, /*!< FlexBus clock */ + kCLOCK_FlashClk, /*!< Flash clock */ + kCLOCK_FastPeriphClk, /*!< Fast peripheral clock */ + kCLOCK_PllFllSelClk, /*!< The clock after SIM[PLLFLLSEL]. */ + + /* ---------------------------------- OSC clock -----------------------------------*/ + kCLOCK_Er32kClk, /*!< External reference 32K clock (ERCLK32K) */ + kCLOCK_Osc0ErClk, /*!< OSC0 external reference clock (OSC0ERCLK) */ + kCLOCK_Osc1ErClk, /*!< OSC1 external reference clock (OSC1ERCLK) */ + kCLOCK_Osc0ErClkUndiv, /*!< OSC0 external reference undivided clock(OSC0ERCLK_UNDIV). */ + + /* ----------------------------- MCG and MCG-Lite clock ---------------------------*/ + kCLOCK_McgFixedFreqClk, /*!< MCG fixed frequency clock (MCGFFCLK) */ + kCLOCK_McgInternalRefClk, /*!< MCG internal reference clock (MCGIRCLK) */ + kCLOCK_McgFllClk, /*!< MCGFLLCLK */ + kCLOCK_McgPll0Clk, /*!< MCGPLL0CLK */ + kCLOCK_McgPll1Clk, /*!< MCGPLL1CLK */ + kCLOCK_McgExtPllClk, /*!< EXT_PLLCLK */ + kCLOCK_McgPeriphClk, /*!< MCG peripheral clock (MCGPCLK) */ + kCLOCK_McgIrc48MClk, /*!< MCG IRC48M clock */ + + /* --------------------------------- Other clock ----------------------------------*/ + kCLOCK_LpoClk, /*!< LPO clock */ + +} clock_name_t; + +/*! @brief USB clock source definition. */ +typedef enum _clock_usb_src +{ + kCLOCK_UsbSrcPll0 = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(1U), /*!< Use PLL0. */ + kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(3U), /*!< Use IRC48M. */ + kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */ +} clock_usb_src_t; + +/*------------------------------------------------------------------------------ + + clock_gate_t definition: + + 31 16 0 + ----------------------------------------------------------------- + | SIM_SCGC register offset | control bit offset in SCGC | + ----------------------------------------------------------------- + + For example, the SDHC clock gate is controlled by SIM_SCGC3[17], the + SIM_SCGC3 offset in SIM is 0x1030, then kCLOCK_GateSdhc0 is defined as + + kCLOCK_GateSdhc0 = (0x1030 << 16) | 17; + +------------------------------------------------------------------------------*/ + +#define CLK_GATE_REG_OFFSET_SHIFT 16U +#define CLK_GATE_REG_OFFSET_MASK 0xFFFF0000U +#define CLK_GATE_BIT_SHIFT_SHIFT 0U +#define CLK_GATE_BIT_SHIFT_MASK 0x0000FFFFU + +#define CLK_GATE_DEFINE(reg_offset, bit_shift) \ + ((((reg_offset) << CLK_GATE_REG_OFFSET_SHIFT) & CLK_GATE_REG_OFFSET_MASK) | \ + (((bit_shift) << CLK_GATE_BIT_SHIFT_SHIFT) & CLK_GATE_BIT_SHIFT_MASK)) + +#define CLK_GATE_ABSTRACT_REG_OFFSET(x) (((x)&CLK_GATE_REG_OFFSET_MASK) >> CLK_GATE_REG_OFFSET_SHIFT) +#define CLK_GATE_ABSTRACT_BITS_SHIFT(x) (((x)&CLK_GATE_BIT_SHIFT_MASK) >> CLK_GATE_BIT_SHIFT_SHIFT) + +/*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */ +typedef enum _clock_ip_name +{ + kCLOCK_IpInvalid = 0U, + kCLOCK_I2c2 = CLK_GATE_DEFINE(0x1028U, 6U), + kCLOCK_Uart4 = CLK_GATE_DEFINE(0x1028U, 10U), + kCLOCK_Uart5 = CLK_GATE_DEFINE(0x1028U, 11U), + + kCLOCK_Enet0 = CLK_GATE_DEFINE(0x102CU, 0U), + kCLOCK_Dac0 = CLK_GATE_DEFINE(0x102CU, 12U), + kCLOCK_Dac1 = CLK_GATE_DEFINE(0x102CU, 13U), + + kCLOCK_Spi2 = CLK_GATE_DEFINE(0x1030U, 12U), + kCLOCK_Sdhc0 = CLK_GATE_DEFINE(0x1030U, 17U), + kCLOCK_Ftm3 = CLK_GATE_DEFINE(0x1030U, 25U), + kCLOCK_Adc1 = CLK_GATE_DEFINE(0x1030U, 27U), + + kCLOCK_Ewm0 = CLK_GATE_DEFINE(0x1034U, 1U), + kCLOCK_Cmt0 = CLK_GATE_DEFINE(0x1034U, 2U), + kCLOCK_I2c0 = CLK_GATE_DEFINE(0x1034U, 6U), + kCLOCK_I2c1 = CLK_GATE_DEFINE(0x1034U, 7U), + kCLOCK_Uart0 = CLK_GATE_DEFINE(0x1034U, 10U), + kCLOCK_Uart1 = CLK_GATE_DEFINE(0x1034U, 11U), + kCLOCK_Uart2 = CLK_GATE_DEFINE(0x1034U, 12U), + kCLOCK_Uart3 = CLK_GATE_DEFINE(0x1034U, 13U), + kCLOCK_Usbfs0 = CLK_GATE_DEFINE(0x1034U, 18U), + kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U), + kCLOCK_Cmp1 = CLK_GATE_DEFINE(0x1034U, 19U), + kCLOCK_Cmp2 = CLK_GATE_DEFINE(0x1034U, 19U), + kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U), + + kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U), + kCLOCK_PortA = CLK_GATE_DEFINE(0x1038U, 9U), + kCLOCK_PortB = CLK_GATE_DEFINE(0x1038U, 10U), + kCLOCK_PortC = CLK_GATE_DEFINE(0x1038U, 11U), + kCLOCK_PortD = CLK_GATE_DEFINE(0x1038U, 12U), + kCLOCK_PortE = CLK_GATE_DEFINE(0x1038U, 13U), + + kCLOCK_Ftf0 = CLK_GATE_DEFINE(0x103CU, 0U), + kCLOCK_Dmamux0 = CLK_GATE_DEFINE(0x103CU, 1U), + kCLOCK_Flexcan0 = CLK_GATE_DEFINE(0x103CU, 4U), + kCLOCK_Rnga0 = CLK_GATE_DEFINE(0x103CU, 9U), + kCLOCK_Spi0 = CLK_GATE_DEFINE(0x103CU, 12U), + kCLOCK_Spi1 = CLK_GATE_DEFINE(0x103CU, 13U), + kCLOCK_Sai0 = CLK_GATE_DEFINE(0x103CU, 15U), + kCLOCK_Crc0 = CLK_GATE_DEFINE(0x103CU, 18U), + kCLOCK_Usbdcd0 = CLK_GATE_DEFINE(0x103CU, 21U), + kCLOCK_Pdb0 = CLK_GATE_DEFINE(0x103CU, 22U), + kCLOCK_Pit0 = CLK_GATE_DEFINE(0x103CU, 23U), + kCLOCK_Ftm0 = CLK_GATE_DEFINE(0x103CU, 24U), + kCLOCK_Ftm1 = CLK_GATE_DEFINE(0x103CU, 25U), + kCLOCK_Ftm2 = CLK_GATE_DEFINE(0x103CU, 26U), + kCLOCK_Adc0 = CLK_GATE_DEFINE(0x103CU, 27U), + kCLOCK_Rtc0 = CLK_GATE_DEFINE(0x103CU, 29U), + + kCLOCK_Flexbus0 = CLK_GATE_DEFINE(0x1040U, 0U), + kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 1U), + kCLOCK_Sysmpu0 = CLK_GATE_DEFINE(0x1040U, 2U), +} clock_ip_name_t; + +/*!@brief SIM configuration structure for clock setting. */ +typedef struct _sim_clock_config +{ + uint8_t pllFllSel; /*!< PLL/FLL/IRC48M selection. */ + uint8_t er32kSrc; /*!< ERCLK32K source selection. */ + uint32_t clkdiv1; /*!< SIM_CLKDIV1. */ +} sim_clock_config_t; + +/*! @brief OSC work mode. */ +typedef enum _osc_mode +{ + kOSC_ModeExt = 0U, /*!< Use an external clock. */ +#if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK))) + kOSC_ModeOscLowPower = MCG_C2_EREFS_MASK, /*!< Oscillator low power. */ +#else + kOSC_ModeOscLowPower = MCG_C2_EREFS0_MASK, /*!< Oscillator low power. */ +#endif + kOSC_ModeOscHighGain = 0U +#if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK))) + | + MCG_C2_EREFS_MASK +#else + | + MCG_C2_EREFS0_MASK +#endif +#if (defined(MCG_C2_HGO_MASK) && !(defined(MCG_C2_HGO0_MASK))) + | + MCG_C2_HGO_MASK, /*!< Oscillator high gain. */ +#else + | + MCG_C2_HGO0_MASK, /*!< Oscillator high gain. */ +#endif +} osc_mode_t; + +/*! @brief Oscillator capacitor load setting.*/ +enum _osc_cap_load +{ + kOSC_Cap2P = OSC_CR_SC2P_MASK, /*!< 2 pF capacitor load */ + kOSC_Cap4P = OSC_CR_SC4P_MASK, /*!< 4 pF capacitor load */ + kOSC_Cap8P = OSC_CR_SC8P_MASK, /*!< 8 pF capacitor load */ + kOSC_Cap16P = OSC_CR_SC16P_MASK /*!< 16 pF capacitor load */ +}; + +/*! @brief OSCERCLK enable mode. */ +enum _oscer_enable_mode +{ + kOSC_ErClkEnable = OSC_CR_ERCLKEN_MASK, /*!< Enable. */ + kOSC_ErClkEnableInStop = OSC_CR_EREFSTEN_MASK /*!< Enable in stop mode. */ +}; + +/*! @brief OSC configuration for OSCERCLK. */ +typedef struct _oscer_config +{ + uint8_t enableMode; /*!< OSCERCLK enable mode. OR'ed value of @ref _oscer_enable_mode. */ + +} oscer_config_t; + +/*! + * @brief OSC Initialization Configuration Structure + * + * Defines the configuration data structure to initialize the OSC. + * When porting to a new board, set the following members + * according to the board setting: + * 1. freq: The external frequency. + * 2. workMode: The OSC module mode. + */ +typedef struct _osc_config +{ + uint32_t freq; /*!< External clock frequency. */ + uint8_t capLoad; /*!< Capacitor load setting. */ + osc_mode_t workMode; /*!< OSC work mode setting. */ + oscer_config_t oscerConfig; /*!< Configuration for OSCERCLK. */ +} osc_config_t; + +/*! @brief MCG FLL reference clock source select. */ +typedef enum _mcg_fll_src +{ + kMCG_FllSrcExternal, /*!< External reference clock is selected */ + kMCG_FllSrcInternal /*!< The slow internal reference clock is selected */ +} mcg_fll_src_t; + +/*! @brief MCG internal reference clock select */ +typedef enum _mcg_irc_mode +{ + kMCG_IrcSlow, /*!< Slow internal reference clock selected */ + kMCG_IrcFast /*!< Fast internal reference clock selected */ +} mcg_irc_mode_t; + +/*! @brief MCG DCO Maximum Frequency with 32.768 kHz Reference */ +typedef enum _mcg_dmx32 +{ + kMCG_Dmx32Default, /*!< DCO has a default range of 25% */ + kMCG_Dmx32Fine /*!< DCO is fine-tuned for maximum frequency with 32.768 kHz reference */ +} mcg_dmx32_t; + +/*! @brief MCG DCO range select */ +typedef enum _mcg_drs +{ + kMCG_DrsLow, /*!< Low frequency range */ + kMCG_DrsMid, /*!< Mid frequency range */ + kMCG_DrsMidHigh, /*!< Mid-High frequency range */ + kMCG_DrsHigh /*!< High frequency range */ +} mcg_drs_t; + +/*! @brief MCG PLL reference clock select */ +typedef enum _mcg_pll_ref_src +{ + kMCG_PllRefOsc0, /*!< Selects OSC0 as PLL reference clock */ + kMCG_PllRefOsc1 /*!< Selects OSC1 as PLL reference clock */ +} mcg_pll_ref_src_t; + +/*! @brief MCGOUT clock source. */ +typedef enum _mcg_clkout_src +{ + kMCG_ClkOutSrcOut, /*!< Output of the FLL is selected (reset default) */ + kMCG_ClkOutSrcInternal, /*!< Internal reference clock is selected */ + kMCG_ClkOutSrcExternal, /*!< External reference clock is selected */ +} mcg_clkout_src_t; + +/*! @brief MCG Automatic Trim Machine Select */ +typedef enum _mcg_atm_select +{ + kMCG_AtmSel32k, /*!< 32 kHz Internal Reference Clock selected */ + kMCG_AtmSel4m /*!< 4 MHz Internal Reference Clock selected */ +} mcg_atm_select_t; + +/*! @brief MCG OSC Clock Select */ +typedef enum _mcg_oscsel +{ + kMCG_OscselOsc, /*!< Selects System Oscillator (OSCCLK) */ + kMCG_OscselRtc, /*!< Selects 32 kHz RTC Oscillator */ + kMCG_OscselIrc /*!< Selects 48 MHz IRC Oscillator */ +} mcg_oscsel_t; + +/*! @brief MCG PLLCS select */ +typedef enum _mcg_pll_clk_select +{ + kMCG_PllClkSelPll0, /*!< PLL0 output clock is selected */ + kMCG_PllClkSelPll1 /* PLL1 output clock is selected */ +} mcg_pll_clk_select_t; + +/*! @brief MCG clock monitor mode. */ +typedef enum _mcg_monitor_mode +{ + kMCG_MonitorNone, /*!< Clock monitor is disabled. */ + kMCG_MonitorInt, /*!< Trigger interrupt when clock lost. */ + kMCG_MonitorReset /*!< System reset when clock lost. */ +} mcg_monitor_mode_t; + +/*! @brief MCG status. */ +enum _mcg_status +{ + kStatus_MCG_ModeUnreachable = MAKE_STATUS(kStatusGroup_MCG, 0), /*!< Can't switch to target mode. */ + kStatus_MCG_ModeInvalid = MAKE_STATUS(kStatusGroup_MCG, 1), /*!< Current mode invalid for the specific + function. */ + kStatus_MCG_AtmBusClockInvalid = MAKE_STATUS(kStatusGroup_MCG, 2), /*!< Invalid bus clock for ATM. */ + kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3), /*!< Invalid desired frequency for ATM. */ + kStatus_MCG_AtmIrcUsed = MAKE_STATUS(kStatusGroup_MCG, 4), /*!< IRC is used when using ATM. */ + kStatus_MCG_AtmHardwareFail = MAKE_STATUS(kStatusGroup_MCG, 5), /*!< Hardware fail occurs during ATM. */ + kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6) /*!< Can't change the clock source because + it is in use. */ +}; + +/*! @brief MCG status flags. */ +enum _mcg_status_flags_t +{ + kMCG_Osc0LostFlag = (1U << 0U), /*!< OSC0 lost. */ + kMCG_Osc0InitFlag = (1U << 1U), /*!< OSC0 crystal initialized. */ + kMCG_RtcOscLostFlag = (1U << 4U), /*!< RTC OSC lost. */ + kMCG_Pll0LostFlag = (1U << 5U), /*!< PLL0 lost. */ + kMCG_Pll0LockFlag = (1U << 6U), /*!< PLL0 locked. */ +}; + +/*! @brief MCG internal reference clock (MCGIRCLK) enable mode definition. */ +enum _mcg_irclk_enable_mode +{ + kMCG_IrclkEnable = MCG_C1_IRCLKEN_MASK, /*!< MCGIRCLK enable. */ + kMCG_IrclkEnableInStop = MCG_C1_IREFSTEN_MASK /*!< MCGIRCLK enable in stop mode. */ +}; + +/*! @brief MCG PLL clock enable mode definition. */ +enum _mcg_pll_enable_mode +{ + kMCG_PllEnableIndependent = MCG_C5_PLLCLKEN0_MASK, /*!< MCGPLLCLK enable independent of the + MCG clock mode. Generally, the PLL + is disabled in FLL modes + (FEI/FBI/FEE/FBE). Setting the PLL clock + enable independent, enables the + PLL in the FLL modes. */ + kMCG_PllEnableInStop = MCG_C5_PLLSTEN0_MASK /*!< MCGPLLCLK enable in STOP mode. */ +}; + +/*! @brief MCG mode definitions */ +typedef enum _mcg_mode +{ + kMCG_ModeFEI = 0U, /*!< FEI - FLL Engaged Internal */ + kMCG_ModeFBI, /*!< FBI - FLL Bypassed Internal */ + kMCG_ModeBLPI, /*!< BLPI - Bypassed Low Power Internal */ + kMCG_ModeFEE, /*!< FEE - FLL Engaged External */ + kMCG_ModeFBE, /*!< FBE - FLL Bypassed External */ + kMCG_ModeBLPE, /*!< BLPE - Bypassed Low Power External */ + kMCG_ModePBE, /*!< PBE - PLL Bypassed External */ + kMCG_ModePEE, /*!< PEE - PLL Engaged External */ + kMCG_ModeError /*!< Unknown mode */ +} mcg_mode_t; + +/*! @brief MCG PLL configuration. */ +typedef struct _mcg_pll_config +{ + uint8_t enableMode; /*!< Enable mode. OR'ed value of @ref _mcg_pll_enable_mode. */ + uint8_t prdiv; /*!< Reference divider PRDIV. */ + uint8_t vdiv; /*!< VCO divider VDIV. */ +} mcg_pll_config_t; + +/*! @brief MCG mode change configuration structure + * + * When porting to a new board, set the following members + * according to the board setting: + * 1. frdiv: If the FLL uses the external reference clock, set this + * value to ensure that the external reference clock divided by frdiv is + * in the 31.25 kHz to 39.0625 kHz range. + * 2. The PLL reference clock divider PRDIV: PLL reference clock frequency after + * PRDIV should be in the FSL_FEATURE_MCG_PLL_REF_MIN to + * FSL_FEATURE_MCG_PLL_REF_MAX range. + */ +typedef struct _mcg_config +{ + mcg_mode_t mcgMode; /*!< MCG mode. */ + + /* ----------------------- MCGIRCCLK settings ------------------------ */ + uint8_t irclkEnableMode; /*!< MCGIRCLK enable mode. */ + mcg_irc_mode_t ircs; /*!< Source, MCG_C2[IRCS]. */ + uint8_t fcrdiv; /*!< Divider, MCG_SC[FCRDIV]. */ + + /* ------------------------ MCG FLL settings ------------------------- */ + uint8_t frdiv; /*!< Divider MCG_C1[FRDIV]. */ + mcg_drs_t drs; /*!< DCO range MCG_C4[DRST_DRS]. */ + mcg_dmx32_t dmx32; /*!< MCG_C4[DMX32]. */ + mcg_oscsel_t oscsel; /*!< OSC select MCG_C7[OSCSEL]. */ + + /* ------------------------ MCG PLL settings ------------------------- */ + mcg_pll_config_t pll0Config; /*!< MCGPLL0CLK configuration. */ + +} mcg_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @brief Enable the clock for specific IP. + * + * @param name Which clock to enable, see \ref clock_ip_name_t. + */ +static inline void CLOCK_EnableClock(clock_ip_name_t name) +{ + uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name); + (*(volatile uint32_t *)regAddr) |= (1U << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name)); +} + +/*! + * @brief Disable the clock for specific IP. + * + * @param name Which clock to disable, see \ref clock_ip_name_t. + */ +static inline void CLOCK_DisableClock(clock_ip_name_t name) +{ + uint32_t regAddr = SIM_BASE + CLK_GATE_ABSTRACT_REG_OFFSET((uint32_t)name); + (*(volatile uint32_t *)regAddr) &= ~(1U << CLK_GATE_ABSTRACT_BITS_SHIFT((uint32_t)name)); +} + +/*! + * @brief Set ERCLK32K source. + * + * @param src The value to set ERCLK32K clock source. + */ +static inline void CLOCK_SetEr32kClock(uint32_t src) +{ + SIM->SOPT1 = ((SIM->SOPT1 & ~SIM_SOPT1_OSC32KSEL_MASK) | SIM_SOPT1_OSC32KSEL(src)); +} + +/*! + * @brief Set SDHC0 clock source. + * + * @param src The value to set SDHC0 clock source. + */ +static inline void CLOCK_SetSdhc0Clock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_SDHCSRC_MASK) | SIM_SOPT2_SDHCSRC(src)); +} + +/*! + * @brief Set enet timestamp clock source. + * + * @param src The value to set enet timestamp clock source. + */ +static inline void CLOCK_SetEnetTime0Clock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_TIMESRC_MASK) | SIM_SOPT2_TIMESRC(src)); +} + +/*! + * @brief Set RMII clock source. + * + * @param src The value to set RMII clock source. + */ +static inline void CLOCK_SetRmii0Clock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_RMIISRC_MASK) | SIM_SOPT2_RMIISRC(src)); +} + +/*! + * @brief Set debug trace clock source. + * + * @param src The value to set debug trace clock source. + */ +static inline void CLOCK_SetTraceClock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_TRACECLKSEL_MASK) | SIM_SOPT2_TRACECLKSEL(src)); +} + +/*! + * @brief Set PLLFLLSEL clock source. + * + * @param src The value to set PLLFLLSEL clock source. + */ +static inline void CLOCK_SetPllFllSelClock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_PLLFLLSEL_MASK) | SIM_SOPT2_PLLFLLSEL(src)); +} + +/*! + * @brief Set CLKOUT source. + * + * @param src The value to set CLKOUT source. + */ +static inline void CLOCK_SetClkOutClock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_CLKOUTSEL_MASK) | SIM_SOPT2_CLKOUTSEL(src)); +} + +/*! + * @brief Set RTC_CLKOUT source. + * + * @param src The value to set RTC_CLKOUT source. + */ +static inline void CLOCK_SetRtcClkOutClock(uint32_t src) +{ + SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_RTCCLKOUTSEL_MASK) | SIM_SOPT2_RTCCLKOUTSEL(src)); +} + +/*! @brief Enable USB FS clock. + * + * @param src USB FS clock source. + * @param freq The frequency specified by src. + * @retval true The clock is set successfully. + * @retval false The clock source is invalid to get proper USB FS clock. + */ +bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq); + +/*! @brief Disable USB FS clock. + * + * Disable USB FS clock. + */ +static inline void CLOCK_DisableUsbfs0Clock(void) +{ + CLOCK_DisableClock(kCLOCK_Usbfs0); +} + +/*! + * @brief System clock divider + * + * Set the SIM_CLKDIV1[OUTDIV1], SIM_CLKDIV1[OUTDIV2], SIM_CLKDIV1[OUTDIV3], SIM_CLKDIV1[OUTDIV4]. + * + * @param outdiv1 Clock 1 output divider value. + * + * @param outdiv2 Clock 2 output divider value. + * + * @param outdiv3 Clock 3 output divider value. + * + * @param outdiv4 Clock 4 output divider value. + */ +static inline void CLOCK_SetOutDiv(uint32_t outdiv1, uint32_t outdiv2, uint32_t outdiv3, uint32_t outdiv4) +{ + SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(outdiv1) | SIM_CLKDIV1_OUTDIV2(outdiv2) | SIM_CLKDIV1_OUTDIV3(outdiv3) | + SIM_CLKDIV1_OUTDIV4(outdiv4); +} + +/*! + * @brief Gets the clock frequency for a specific clock name. + * + * This function checks the current clock configurations and then calculates + * the clock frequency for a specific clock name defined in clock_name_t. + * The MCG must be properly configured before using this function. + * + * @param clockName Clock names defined in clock_name_t + * @return Clock frequency value in Hertz + */ +uint32_t CLOCK_GetFreq(clock_name_t clockName); + +/*! + * @brief Get the core clock or system clock frequency. + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetCoreSysClkFreq(void); + +/*! + * @brief Get the platform clock frequency. + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetPlatClkFreq(void); + +/*! + * @brief Get the bus clock frequency. + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetBusClkFreq(void); + +/*! + * @brief Get the flexbus clock frequency. + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetFlexBusClkFreq(void); + +/*! + * @brief Get the flash clock frequency. + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetFlashClkFreq(void); + +/*! + * @brief Get the output clock frequency selected by SIM[PLLFLLSEL]. + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetPllFllSelClkFreq(void); + +/*! + * @brief Get the external reference 32K clock frequency (ERCLK32K). + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetEr32kClkFreq(void); + +/*! + * @brief Get the OSC0 external reference clock frequency (OSC0ERCLK). + * + * @return Clock frequency in Hz. + */ +uint32_t CLOCK_GetOsc0ErClkFreq(void); + +/*! + * @brief Set the clock configure in SIM module. + * + * This function sets system layer clock settings in SIM module. + * + * @param config Pointer to the configure structure. + */ +void CLOCK_SetSimConfig(sim_clock_config_t const *config); + +/*! + * @brief Set the system clock dividers in SIM to safe value. + * + * The system level clocks (core clock, bus clock, flexbus clock and flash clock) + * must be in allowed ranges. During MCG clock mode switch, the MCG output clock + * changes then the system level clocks may be out of range. This function could + * be used before MCG mode change, to make sure system level clocks are in allowed + * range. + * + * @param config Pointer to the configure structure. + */ +static inline void CLOCK_SetSimSafeDivs(void) +{ + SIM->CLKDIV1 = 0x01240000U; +} + +/*! @name MCG frequency functions. */ +/*@{*/ + +/*! + * @brief Gets the MCG output clock (MCGOUTCLK) frequency. + * + * This function gets the MCG output clock frequency in Hz based on the current MCG + * register value. + * + * @return The frequency of MCGOUTCLK. + */ +uint32_t CLOCK_GetOutClkFreq(void); + +/*! + * @brief Gets the MCG FLL clock (MCGFLLCLK) frequency. + * + * This function gets the MCG FLL clock frequency in Hz based on the current MCG + * register value. The FLL is enabled in FEI/FBI/FEE/FBE mode and + * disabled in low power state in other modes. + * + * @return The frequency of MCGFLLCLK. + */ +uint32_t CLOCK_GetFllFreq(void); + +/*! + * @brief Gets the MCG internal reference clock (MCGIRCLK) frequency. + * + * This function gets the MCG internal reference clock frequency in Hz based + * on the current MCG register value. + * + * @return The frequency of MCGIRCLK. + */ +uint32_t CLOCK_GetInternalRefClkFreq(void); + +/*! + * @brief Gets the MCG fixed frequency clock (MCGFFCLK) frequency. + * + * This function gets the MCG fixed frequency clock frequency in Hz based + * on the current MCG register value. + * + * @return The frequency of MCGFFCLK. + */ +uint32_t CLOCK_GetFixedFreqClkFreq(void); + +/*! + * @brief Gets the MCG PLL0 clock (MCGPLL0CLK) frequency. + * + * This function gets the MCG PLL0 clock frequency in Hz based on the current MCG + * register value. + * + * @return The frequency of MCGPLL0CLK. + */ +uint32_t CLOCK_GetPll0Freq(void); + +/*@}*/ + +/*! @name MCG clock configuration. */ +/*@{*/ + +/*! + * @brief Enables or disables the MCG low power. + * + * Enabling the MCG low power disables the PLL and FLL in bypass modes. In other words, + * in FBE and PBE modes, enabling low power sets the MCG to BLPE mode. In FBI and + * PBI modes, enabling low power sets the MCG to BLPI mode. + * When disabling the MCG low power, the PLL or FLL are enabled based on MCG settings. + * + * @param enable True to enable MCG low power, false to disable MCG low power. + */ +static inline void CLOCK_SetLowPowerEnable(bool enable) +{ + if (enable) + { + MCG->C2 |= MCG_C2_LP_MASK; + } + else + { + MCG->C2 &= ~MCG_C2_LP_MASK; + } +} + +/*! + * @brief Configures the Internal Reference clock (MCGIRCLK). + * + * This function sets the \c MCGIRCLK base on parameters. It also selects the IRC + * source. If the fast IRC is used, this function sets the fast IRC divider. + * This function also sets whether the \c MCGIRCLK is enabled in stop mode. + * Calling this function in FBI/PBI/BLPI modes may change the system clock. As a result, + * using the function in these modes it is not allowed. + * + * @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode. + * @param ircs MCGIRCLK clock source, choose fast or slow. + * @param fcrdiv Fast IRC divider setting (\c FCRDIV). + * @retval kStatus_MCG_SourceUsed Because the internal reference clock is used as a clock source, + * the configuration should not be changed. Otherwise, a glitch occurs. + * @retval kStatus_Success MCGIRCLK configuration finished successfully. + */ +status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv); + +/*! + * @brief Selects the MCG external reference clock. + * + * Selects the MCG external reference clock source, changes the MCG_C7[OSCSEL], + * and waits for the clock source to be stable. Because the external reference + * clock should not be changed in FEE/FBE/BLPE/PBE/PEE modes, do not call this function in these modes. + * + * @param oscsel MCG external reference clock source, MCG_C7[OSCSEL]. + * @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source, + * the configuration should not be changed. Otherwise, a glitch occurs. + * @retval kStatus_Success External reference clock set successfully. + */ +status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel); + +/*! + * @brief Set the FLL external reference clock divider value. + * + * Sets the FLL external reference clock divider value, the register MCG_C1[FRDIV]. + * + * @param frdiv The FLL external reference clock divider value, MCG_C1[FRDIV]. + */ +static inline void CLOCK_SetFllExtRefDiv(uint8_t frdiv) +{ + MCG->C1 = (MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv); +} + +/*! + * @brief Enables the PLL0 in FLL mode. + * + * This function sets us the PLL0 in FLL mode and reconfigures + * the PLL0. Ensure that the PLL reference + * clock is enabled before calling this function and that the PLL0 is not used as a clock source. + * The function CLOCK_CalcPllDiv gets the correct PLL + * divider values. + * + * @param config Pointer to the configuration structure. + */ +void CLOCK_EnablePll0(mcg_pll_config_t const *config); + +/*! + * @brief Disables the PLL0 in FLL mode. + * + * This function disables the PLL0 in FLL mode. It should be used together with the + * @ref CLOCK_EnablePll0. + */ +static inline void CLOCK_DisablePll0(void) +{ + MCG->C5 &= ~(MCG_C5_PLLCLKEN0_MASK | MCG_C5_PLLSTEN0_MASK); +} + +/*! + * @brief Calculates the PLL divider setting for a desired output frequency. + * + * This function calculates the correct reference clock divider (\c PRDIV) and + * VCO divider (\c VDIV) to generate a desired PLL output frequency. It returns the + * closest frequency match with the corresponding \c PRDIV/VDIV + * returned from parameters. If a desired frequency is not valid, this function + * returns 0. + * + * @param refFreq PLL reference clock frequency. + * @param desireFreq Desired PLL output frequency. + * @param prdiv PRDIV value to generate desired PLL frequency. + * @param vdiv VDIV value to generate desired PLL frequency. + * @return Closest frequency match that the PLL was able generate. + */ +uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv, uint8_t *vdiv); + +/*@}*/ + +/*! @name MCG clock lock monitor functions. */ +/*@{*/ + +/*! + * @brief Sets the OSC0 clock monitor mode. + * + * This function sets the OSC0 clock monitor mode. See @ref mcg_monitor_mode_t for details. + * + * @param mode Monitor mode to set. + */ +void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode); + +/*! + * @brief Sets the RTC OSC clock monitor mode. + * + * This function sets the RTC OSC clock monitor mode. See @ref mcg_monitor_mode_t for details. + * + * @param mode Monitor mode to set. + */ +void CLOCK_SetRtcOscMonitorMode(mcg_monitor_mode_t mode); + +/*! + * @brief Sets the PLL0 clock monitor mode. + * + * This function sets the PLL0 clock monitor mode. See @ref mcg_monitor_mode_t for details. + * + * @param mode Monitor mode to set. + */ +void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode); + +/*! + * @brief Gets the MCG status flags. + * + * This function gets the MCG clock status flags. All status flags are + * returned as a logical OR of the enumeration @ref _mcg_status_flags_t. To + * check a specific flag, compare the return value with the flag. + * + * Example: + * @code + // To check the clock lost lock status of OSC0 and PLL0. + uint32_t mcgFlags; + + mcgFlags = CLOCK_GetStatusFlags(); + + if (mcgFlags & kMCG_Osc0LostFlag) + { + // OSC0 clock lock lost. Do something. + } + if (mcgFlags & kMCG_Pll0LostFlag) + { + // PLL0 clock lock lost. Do something. + } + @endcode + * + * @return Logical OR value of the @ref _mcg_status_flags_t. + */ +uint32_t CLOCK_GetStatusFlags(void); + +/*! + * @brief Clears the MCG status flags. + * + * This function clears the MCG clock lock lost status. The parameter is a logical + * OR value of the flags to clear. See @ref _mcg_status_flags_t. + * + * Example: + * @code + // To clear the clock lost lock status flags of OSC0 and PLL0. + + CLOCK_ClearStatusFlags(kMCG_Osc0LostFlag | kMCG_Pll0LostFlag); + @endcode + * + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration @ref _mcg_status_flags_t. + */ +void CLOCK_ClearStatusFlags(uint32_t mask); + +/*@}*/ + +/*! + * @name OSC configuration + * @{ + */ + +/*! + * @brief Configures the OSC external reference clock (OSCERCLK). + * + * This function configures the OSC external reference clock (OSCERCLK). + * This is an example to enable the OSCERCLK in normal and stop modes and also set + * the output divider to 1: + * + @code + oscer_config_t config = + { + .enableMode = kOSC_ErClkEnable | kOSC_ErClkEnableInStop, + .erclkDiv = 1U, + }; + + OSC_SetExtRefClkConfig(OSC, &config); + @endcode + * + * @param base OSC peripheral address. + * @param config Pointer to the configuration structure. + */ +static inline void OSC_SetExtRefClkConfig(OSC_Type *base, oscer_config_t const *config) +{ + uint8_t reg = base->CR; + + reg &= ~(OSC_CR_ERCLKEN_MASK | OSC_CR_EREFSTEN_MASK); + reg |= config->enableMode; + + base->CR = reg; +} + +/*! + * @brief Sets the capacitor load configuration for the oscillator. + * + * This function sets the specified capacitors configuration for the oscillator. + * This should be done in the early system level initialization function call + * based on the system configuration. + * + * @param base OSC peripheral address. + * @param capLoad OR'ed value for the capacitor load option, see \ref _osc_cap_load. + * + * Example: + @code + // To enable only 2 pF and 8 pF capacitor load, please use like this. + OSC_SetCapLoad(OSC, kOSC_Cap2P | kOSC_Cap8P); + @endcode + */ +static inline void OSC_SetCapLoad(OSC_Type *base, uint8_t capLoad) +{ + uint8_t reg = base->CR; + + reg &= ~(OSC_CR_SC2P_MASK | OSC_CR_SC4P_MASK | OSC_CR_SC8P_MASK | OSC_CR_SC16P_MASK); + reg |= capLoad; + + base->CR = reg; +} + +/*! + * @brief Initializes the OSC0. + * + * This function initializes the OSC0 according to the board configuration. + * + * @param config Pointer to the OSC0 configuration structure. + */ +void CLOCK_InitOsc0(osc_config_t const *config); + +/*! + * @brief Deinitializes the OSC0. + * + * This function deinitializes the OSC0. + */ +void CLOCK_DeinitOsc0(void); + +/* @} */ + +/*! + * @name External clock frequency + * @{ + */ + +/*! + * @brief Sets the XTAL0 frequency based on board settings. + * + * @param freq The XTAL0/EXTAL0 input clock frequency in Hz. + */ +static inline void CLOCK_SetXtal0Freq(uint32_t freq) +{ + g_xtal0Freq = freq; +} + +/*! + * @brief Sets the XTAL32/RTC_CLKIN frequency based on board settings. + * + * @param freq The XTAL32/EXTAL32/RTC_CLKIN input clock frequency in Hz. + */ +static inline void CLOCK_SetXtal32Freq(uint32_t freq) +{ + g_xtal32Freq = freq; +} +/* @} */ + +/*! + * @name MCG auto-trim machine. + * @{ + */ + +/*! + * @brief Auto trims the internal reference clock. + * + * This function trims the internal reference clock by using the external clock. If + * successful, it returns the kStatus_Success and the frequency after + * trimming is received in the parameter @p actualFreq. If an error occurs, + * the error code is returned. + * + * @param extFreq External clock frequency, which should be a bus clock. + * @param desireFreq Frequency to trim to. + * @param actualFreq Actual frequency after trimming. + * @param atms Trim fast or slow internal reference clock. + * @retval kStatus_Success ATM success. + * @retval kStatus_MCG_AtmBusClockInvalid The bus clock is not in allowed range for the ATM. + * @retval kStatus_MCG_AtmDesiredFreqInvalid MCGIRCLK could not be trimmed to the desired frequency. + * @retval kStatus_MCG_AtmIrcUsed Could not trim because MCGIRCLK is used as a bus clock source. + * @retval kStatus_MCG_AtmHardwareFail Hardware fails while trimming. + */ +status_t CLOCK_TrimInternalRefClk(uint32_t extFreq, uint32_t desireFreq, uint32_t *actualFreq, mcg_atm_select_t atms); +/* @} */ + +/*! @name MCG mode functions. */ +/*@{*/ + +/*! + * @brief Gets the current MCG mode. + * + * This function checks the MCG registers and determines the current MCG mode. + * + * @return Current MCG mode or error code; See @ref mcg_mode_t. + */ +mcg_mode_t CLOCK_GetMode(void); + +/*! + * @brief Sets the MCG to FEI mode. + * + * This function sets the MCG to FEI mode. If setting to FEI mode fails + * from the current mode, this function returns an error. + * + * @param dmx32 DMX32 in FEI mode. + * @param drs The DCO range selection. + * @param fllStableDelay Delay function to ensure that the FLL is stable. Passing + * NULL does not cause a delay. + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed + * to a frequency above 32768 Hz. + */ +status_t CLOCK_SetFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); + +/*! + * @brief Sets the MCG to FEE mode. + * + * This function sets the MCG to FEE mode. If setting to FEE mode fails + * from the current mode, this function returns an error. + * + * @param frdiv FLL reference clock divider setting, FRDIV. + * @param dmx32 DMX32 in FEE mode. + * @param drs The DCO range selection. + * @param fllStableDelay Delay function to make sure FLL is stable. Passing + * NULL does not cause a delay. + * + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_SetFeeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); + +/*! + * @brief Sets the MCG to FBI mode. + * + * This function sets the MCG to FBI mode. If setting to FBI mode fails + * from the current mode, this function returns an error. + * + * @param dmx32 DMX32 in FBI mode. + * @param drs The DCO range selection. + * @param fllStableDelay Delay function to make sure FLL is stable. If the FLL + * is not used in FBI mode, this parameter can be NULL. Passing + * NULL does not cause a delay. + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed + * to frequency above 32768 Hz. + */ +status_t CLOCK_SetFbiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); + +/*! + * @brief Sets the MCG to FBE mode. + * + * This function sets the MCG to FBE mode. If setting to FBE mode fails + * from the current mode, this function returns an error. + * + * @param frdiv FLL reference clock divider setting, FRDIV. + * @param dmx32 DMX32 in FBE mode. + * @param drs The DCO range selection. + * @param fllStableDelay Delay function to make sure FLL is stable. If the FLL + * is not used in FBE mode, this parameter can be NULL. Passing NULL + * does not cause a delay. + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_SetFbeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); + +/*! + * @brief Sets the MCG to BLPI mode. + * + * This function sets the MCG to BLPI mode. If setting to BLPI mode fails + * from the current mode, this function returns an error. + * + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_SetBlpiMode(void); + +/*! + * @brief Sets the MCG to BLPE mode. + * + * This function sets the MCG to BLPE mode. If setting to BLPE mode fails + * from the current mode, this function returns an error. + * + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_SetBlpeMode(void); + +/*! + * @brief Sets the MCG to PBE mode. + * + * This function sets the MCG to PBE mode. If setting to PBE mode fails + * from the current mode, this function returns an error. + * + * @param pllcs The PLL selection, PLLCS. + * @param config Pointer to the PLL configuration. + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + * + * @note + * 1. The parameter \c pllcs selects the PLL. For platforms with + * only one PLL, the parameter pllcs is kept for interface compatibility. + * 2. The parameter \c config is the PLL configuration structure. On some + * platforms, it is possible to choose the external PLL directly, which renders the + * configuration structure not necessary. In this case, pass in NULL. + * For example: CLOCK_SetPbeMode(kMCG_OscselOsc, kMCG_PllClkSelExtPll, NULL); + */ +status_t CLOCK_SetPbeMode(mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config); + +/*! + * @brief Sets the MCG to PEE mode. + * + * This function sets the MCG to PEE mode. + * + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + * + * @note This function only changes the CLKS to use the PLL/FLL output. If the + * PRDIV/VDIV are different than in the PBE mode, set them up + * in PBE mode and wait. When the clock is stable, switch to PEE mode. + */ +status_t CLOCK_SetPeeMode(void); + +/*! + * @brief Switches the MCG to FBE mode from the external mode. + * + * This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly. + * The external clock is used as the system clock source and PLL is disabled. However, + * the FLL settings are not configured. This is a lite function with a small code size, which is useful + * during the mode switch. For example, to switch from PEE mode to FEI mode: + * + * @code + * CLOCK_ExternalModeToFbeModeQuick(); + * CLOCK_SetFeiMode(...); + * @endcode + * + * @retval kStatus_Success Switched successfully. + * @retval kStatus_MCG_ModeInvalid If the current mode is not an external mode, do not call this function. + */ +status_t CLOCK_ExternalModeToFbeModeQuick(void); + +/*! + * @brief Switches the MCG to FBI mode from internal modes. + * + * This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly. + * The MCGIRCLK is used as the system clock source and PLL is disabled. However, + * FLL settings are not configured. This is a lite function with a small code size, which is useful + * during the mode switch. For example, to switch from PEI mode to FEE mode: + * + * @code + * CLOCK_InternalModeToFbiModeQuick(); + * CLOCK_SetFeeMode(...); + * @endcode + * + * @retval kStatus_Success Switched successfully. + * @retval kStatus_MCG_ModeInvalid If the current mode is not an internal mode, do not call this function. + */ +status_t CLOCK_InternalModeToFbiModeQuick(void); + +/*! + * @brief Sets the MCG to FEI mode during system boot up. + * + * This function sets the MCG to FEI mode from the reset mode. It can also be used to + * set up MCG during system boot up. + * + * @param dmx32 DMX32 in FEI mode. + * @param drs The DCO range selection. + * @param fllStableDelay Delay function to ensure that the FLL is stable. + * + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed + * to frequency above 32768 Hz. + */ +status_t CLOCK_BootToFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); + +/*! + * @brief Sets the MCG to FEE mode during system bootup. + * + * This function sets MCG to FEE mode from the reset mode. It can also be used to + * set up the MCG during system boot up. + * + * @param oscsel OSC clock select, OSCSEL. + * @param frdiv FLL reference clock divider setting, FRDIV. + * @param dmx32 DMX32 in FEE mode. + * @param drs The DCO range selection. + * @param fllStableDelay Delay function to ensure that the FLL is stable. + * + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_BootToFeeMode( + mcg_oscsel_t oscsel, uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); + +/*! + * @brief Sets the MCG to BLPI mode during system boot up. + * + * This function sets the MCG to BLPI mode from the reset mode. It can also be used to + * set up the MCG during system boot up. + * + * @param fcrdiv Fast IRC divider, FCRDIV. + * @param ircs The internal reference clock to select, IRCS. + * @param ircEnableMode The MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode. + * + * @retval kStatus_MCG_SourceUsed Could not change MCGIRCLK setting. + * @retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode); + +/*! + * @brief Sets the MCG to BLPE mode during system boot up. + * + * This function sets the MCG to BLPE mode from the reset mode. It can also be used to + * set up the MCG during system boot up. + * + * @param oscsel OSC clock select, MCG_C7[OSCSEL]. + * + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel); + +/*! + * @brief Sets the MCG to PEE mode during system boot up. + * + * This function sets the MCG to PEE mode from reset mode. It can also be used to + * set up the MCG during system boot up. + * + * @param oscsel OSC clock select, MCG_C7[OSCSEL]. + * @param pllcs The PLL selection, PLLCS. + * @param config Pointer to the PLL configuration. + * + * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. + * @retval kStatus_Success Switched to the target mode successfully. + */ +status_t CLOCK_BootToPeeMode(mcg_oscsel_t oscsel, mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config); + +/*! + * @brief Sets the MCG to a target mode. + * + * This function sets MCG to a target mode defined by the configuration + * structure. If switching to the target mode fails, this function + * chooses the correct path. + * + * @param config Pointer to the target MCG mode configuration structure. + * @return Return kStatus_Success if switched successfully; Otherwise, it returns an error code #_mcg_status. + * + * @note If the external clock is used in the target mode, ensure that it is + * enabled. For example, if the OSC0 is used, set up OSC0 correctly before calling this + * function. + */ +status_t CLOCK_SetMcgConfig(mcg_config_t const *config); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @} */ + +#endif /* _FSL_CLOCK_H_ */ diff --git a/drivers/fsl_common.c b/drivers/fsl_common.c new file mode 100644 index 0000000..39e78bc --- /dev/null +++ b/drivers/fsl_common.c @@ -0,0 +1,147 @@ +/* +* Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2018 NXP +* All rights reserved. +* +* +* SPDX-License-Identifier: BSD-3-Clause +*/ + +#include "fsl_common.h" +#define SDK_MEM_MAGIC_NUMBER 12345U + +typedef struct _mem_align_control_block +{ + uint16_t identifier; /*!< Identifier for the memory control block. */ + uint16_t offset; /*!< offset from aligned address to real address */ +} mem_align_cb_t; + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.common" +#endif + +#ifndef __GIC_PRIO_BITS +#if defined(ENABLE_RAM_VECTOR_TABLE) +uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler) +{ +/* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */ +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) + extern uint32_t Image$$VECTOR_ROM$$Base[]; + extern uint32_t Image$$VECTOR_RAM$$Base[]; + extern uint32_t Image$$RW_m_data$$Base[]; + +#define __VECTOR_TABLE Image$$VECTOR_ROM$$Base +#define __VECTOR_RAM Image$$VECTOR_RAM$$Base +#define __RAM_VECTOR_TABLE_SIZE (((uint32_t)Image$$RW_m_data$$Base - (uint32_t)Image$$VECTOR_RAM$$Base)) +#elif defined(__ICCARM__) + extern uint32_t __RAM_VECTOR_TABLE_SIZE[]; + extern uint32_t __VECTOR_TABLE[]; + extern uint32_t __VECTOR_RAM[]; +#elif defined(__GNUC__) + extern uint32_t __VECTOR_TABLE[]; + extern uint32_t __VECTOR_RAM[]; + extern uint32_t __RAM_VECTOR_TABLE_SIZE_BYTES[]; + uint32_t __RAM_VECTOR_TABLE_SIZE = (uint32_t)(__RAM_VECTOR_TABLE_SIZE_BYTES); +#endif /* defined(__CC_ARM) || defined(__ARMCC_VERSION) */ + uint32_t n; + uint32_t ret; + uint32_t irqMaskValue; + + irqMaskValue = DisableGlobalIRQ(); + if (SCB->VTOR != (uint32_t)__VECTOR_RAM) + { + /* Copy the vector table from ROM to RAM */ + for (n = 0; n < ((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t); n++) + { + __VECTOR_RAM[n] = __VECTOR_TABLE[n]; + } + /* Point the VTOR to the position of vector table */ + SCB->VTOR = (uint32_t)__VECTOR_RAM; + } + + ret = __VECTOR_RAM[irq + 16]; + /* make sure the __VECTOR_RAM is noncachable */ + __VECTOR_RAM[irq + 16] = irqHandler; + + EnableGlobalIRQ(irqMaskValue); + +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif + + return ret; +} +#endif /* ENABLE_RAM_VECTOR_TABLE. */ +#endif /* __GIC_PRIO_BITS. */ + +#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) +#if !(defined(FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) && FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) + +void EnableDeepSleepIRQ(IRQn_Type interrupt) +{ + uint32_t intNumber = (uint32_t)interrupt; + + uint32_t index = 0; + + while (intNumber >= 32u) + { + index++; + intNumber -= 32u; + } + + SYSCON->STARTERSET[index] = 1u << intNumber; + EnableIRQ(interrupt); /* also enable interrupt at NVIC */ +} + +void DisableDeepSleepIRQ(IRQn_Type interrupt) +{ + uint32_t intNumber = (uint32_t)interrupt; + + DisableIRQ(interrupt); /* also disable interrupt at NVIC */ + uint32_t index = 0; + + while (intNumber >= 32u) + { + index++; + intNumber -= 32u; + } + + SYSCON->STARTERCLR[index] = 1u << intNumber; +} +#endif /* FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS */ +#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */ + +void *SDK_Malloc(size_t size, size_t alignbytes) +{ + mem_align_cb_t *p_cb = NULL; + uint32_t alignedsize = SDK_SIZEALIGN(size, alignbytes) + alignbytes + sizeof(mem_align_cb_t); + void *p_align_addr, *p_addr = malloc(alignedsize); + + if (!p_addr) + { + return NULL; + } + + p_align_addr = (void *)SDK_SIZEALIGN((uint32_t)p_addr + sizeof(mem_align_cb_t), alignbytes); + + p_cb = (mem_align_cb_t *)((uint32_t)p_align_addr - 4); + p_cb->identifier = SDK_MEM_MAGIC_NUMBER; + p_cb->offset = (uint32_t)p_align_addr - (uint32_t)p_addr; + + return (void *)p_align_addr; +} + +void SDK_Free(void *ptr) +{ + mem_align_cb_t *p_cb = (mem_align_cb_t *)((uint32_t)ptr - 4); + + if (p_cb->identifier != SDK_MEM_MAGIC_NUMBER) + { + return; + } + + free((void *)((uint32_t)ptr - p_cb->offset)); +} diff --git a/drivers/fsl_common.h b/drivers/fsl_common.h new file mode 100644 index 0000000..d8a74ce --- /dev/null +++ b/drivers/fsl_common.h @@ -0,0 +1,585 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FSL_COMMON_H_ +#define _FSL_COMMON_H_ + +#include +#include +#include +#include +#include + +#if defined(__ICCARM__) +#include +#endif + +#include "fsl_device_registers.h" + +/*! + * @addtogroup ksdk_common + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Construct a status code value from a group and code number. */ +#define MAKE_STATUS(group, code) ((((group)*100) + (code))) + +/*! @brief Construct the version number for drivers. */ +#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix)) + +/*! @name Driver version */ +/*@{*/ +/*! @brief common driver version 2.0.1. */ +#define FSL_COMMON_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +/* Debug console type definition. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_UART 1U /*!< Debug console based on UART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console based on LPUART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI 3U /*!< Debug console based on LPSCI. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console based on USBCDC. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM 5U /*!< Debug console based on FLEXCOMM. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_IUART 6U /*!< Debug console based on i.MX UART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_VUSART 7U /*!< Debug console based on LPC_VUSART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_MINI_USART 8U /*!< Debug console based on LPC_USART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_SWO 9U /*!< Debug console based on SWO. */ + +/*! @brief Status group numbers. */ +enum _status_groups +{ + kStatusGroup_Generic = 0, /*!< Group number for generic status codes. */ + kStatusGroup_FLASH = 1, /*!< Group number for FLASH status codes. */ + kStatusGroup_LPSPI = 4, /*!< Group number for LPSPI status codes. */ + kStatusGroup_FLEXIO_SPI = 5, /*!< Group number for FLEXIO SPI status codes. */ + kStatusGroup_DSPI = 6, /*!< Group number for DSPI status codes. */ + kStatusGroup_FLEXIO_UART = 7, /*!< Group number for FLEXIO UART status codes. */ + kStatusGroup_FLEXIO_I2C = 8, /*!< Group number for FLEXIO I2C status codes. */ + kStatusGroup_LPI2C = 9, /*!< Group number for LPI2C status codes. */ + kStatusGroup_UART = 10, /*!< Group number for UART status codes. */ + kStatusGroup_I2C = 11, /*!< Group number for UART status codes. */ + kStatusGroup_LPSCI = 12, /*!< Group number for LPSCI status codes. */ + kStatusGroup_LPUART = 13, /*!< Group number for LPUART status codes. */ + kStatusGroup_SPI = 14, /*!< Group number for SPI status code.*/ + kStatusGroup_XRDC = 15, /*!< Group number for XRDC status code.*/ + kStatusGroup_SEMA42 = 16, /*!< Group number for SEMA42 status code.*/ + kStatusGroup_SDHC = 17, /*!< Group number for SDHC status code */ + kStatusGroup_SDMMC = 18, /*!< Group number for SDMMC status code */ + kStatusGroup_SAI = 19, /*!< Group number for SAI status code */ + kStatusGroup_MCG = 20, /*!< Group number for MCG status codes. */ + kStatusGroup_SCG = 21, /*!< Group number for SCG status codes. */ + kStatusGroup_SDSPI = 22, /*!< Group number for SDSPI status codes. */ + kStatusGroup_FLEXIO_I2S = 23, /*!< Group number for FLEXIO I2S status codes */ + kStatusGroup_FLEXIO_MCULCD = 24, /*!< Group number for FLEXIO LCD status codes */ + kStatusGroup_FLASHIAP = 25, /*!< Group number for FLASHIAP status codes */ + kStatusGroup_FLEXCOMM_I2C = 26, /*!< Group number for FLEXCOMM I2C status codes */ + kStatusGroup_I2S = 27, /*!< Group number for I2S status codes */ + kStatusGroup_IUART = 28, /*!< Group number for IUART status codes */ + kStatusGroup_CSI = 29, /*!< Group number for CSI status codes */ + kStatusGroup_MIPI_DSI = 30, /*!< Group number for MIPI DSI status codes */ + kStatusGroup_SDRAMC = 35, /*!< Group number for SDRAMC status codes. */ + kStatusGroup_POWER = 39, /*!< Group number for POWER status codes. */ + kStatusGroup_ENET = 40, /*!< Group number for ENET status codes. */ + kStatusGroup_PHY = 41, /*!< Group number for PHY status codes. */ + kStatusGroup_TRGMUX = 42, /*!< Group number for TRGMUX status codes. */ + kStatusGroup_SMARTCARD = 43, /*!< Group number for SMARTCARD status codes. */ + kStatusGroup_LMEM = 44, /*!< Group number for LMEM status codes. */ + kStatusGroup_QSPI = 45, /*!< Group number for QSPI status codes. */ + kStatusGroup_DMA = 50, /*!< Group number for DMA status codes. */ + kStatusGroup_EDMA = 51, /*!< Group number for EDMA status codes. */ + kStatusGroup_DMAMGR = 52, /*!< Group number for DMAMGR status codes. */ + kStatusGroup_FLEXCAN = 53, /*!< Group number for FlexCAN status codes. */ + kStatusGroup_LTC = 54, /*!< Group number for LTC status codes. */ + kStatusGroup_FLEXIO_CAMERA = 55, /*!< Group number for FLEXIO CAMERA status codes. */ + kStatusGroup_LPC_SPI = 56, /*!< Group number for LPC_SPI status codes. */ + kStatusGroup_LPC_USART = 57, /*!< Group number for LPC_USART status codes. */ + kStatusGroup_DMIC = 58, /*!< Group number for DMIC status codes. */ + kStatusGroup_SDIF = 59, /*!< Group number for SDIF status codes.*/ + kStatusGroup_SPIFI = 60, /*!< Group number for SPIFI status codes. */ + kStatusGroup_OTP = 61, /*!< Group number for OTP status codes. */ + kStatusGroup_MCAN = 62, /*!< Group number for MCAN status codes. */ + kStatusGroup_CAAM = 63, /*!< Group number for CAAM status codes. */ + kStatusGroup_ECSPI = 64, /*!< Group number for ECSPI status codes. */ + kStatusGroup_USDHC = 65, /*!< Group number for USDHC status codes.*/ + kStatusGroup_LPC_I2C = 66, /*!< Group number for LPC_I2C status codes.*/ + kStatusGroup_DCP = 67, /*!< Group number for DCP status codes.*/ + kStatusGroup_MSCAN = 68, /*!< Group number for MSCAN status codes.*/ + kStatusGroup_ESAI = 69, /*!< Group number for ESAI status codes. */ + kStatusGroup_FLEXSPI = 70, /*!< Group number for FLEXSPI status codes. */ + kStatusGroup_MMDC = 71, /*!< Group number for MMDC status codes. */ + kStatusGroup_PDM = 72, /*!< Group number for MIC status codes. */ + kStatusGroup_SDMA = 73, /*!< Group number for SDMA status codes. */ + kStatusGroup_ICS = 74, /*!< Group number for ICS status codes. */ + kStatusGroup_SPDIF = 75, /*!< Group number for SPDIF status codes. */ + kStatusGroup_LPC_MINISPI = 76, /*!< Group number for LPC_MINISPI status codes. */ + kStatusGroup_HASHCRYPT = 77, /*!< Group number for Hashcrypt status codes */ + kStatusGroup_LPC_SPI_SSP = 78, /*!< Group number for LPC_SPI_SSP status codes. */ + kStatusGroup_LPC_I2C_1 = 97, /*!< Group number for LPC_I2C_1 status codes. */ + kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */ + kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */ + kStatusGroup_SEMC = 100, /*!< Group number for SEMC status codes. */ + kStatusGroup_ApplicationRangeStart = 101, /*!< Starting number for application groups. */ + kStatusGroup_IAP = 102, /*!< Group number for IAP status codes */ + + kStatusGroup_HAL_GPIO = 121, /*!< Group number for HAL GPIO status codes. */ + kStatusGroup_HAL_UART = 122, /*!< Group number for HAL UART status codes. */ + kStatusGroup_HAL_TIMER = 123, /*!< Group number for HAL TIMER status codes. */ + kStatusGroup_HAL_SPI = 124, /*!< Group number for HAL SPI status codes. */ + kStatusGroup_HAL_I2C = 125, /*!< Group number for HAL I2C status codes. */ + kStatusGroup_HAL_FLASH = 126, /*!< Group number for HAL FLASH status codes. */ + kStatusGroup_HAL_PWM = 127, /*!< Group number for HAL PWM status codes. */ + kStatusGroup_HAL_RNG = 128, /*!< Group number for HAL RNG status codes. */ + kStatusGroup_TIMERMANAGER = 135, /*!< Group number for TiMER MANAGER status codes. */ + kStatusGroup_SERIALMANAGER = 136, /*!< Group number for SERIAL MANAGER status codes. */ + kStatusGroup_LED = 137, /*!< Group number for LED status codes. */ + kStatusGroup_BUTTON = 138, /*!< Group number for BUTTON status codes. */ + kStatusGroup_EXTERN_EEPROM = 139, /*!< Group number for EXTERN EEPROM status codes. */ + kStatusGroup_SHELL = 140, /*!< Group number for SHELL status codes. */ + kStatusGroup_MEM_MANAGER = 141, /*!< Group number for MEM MANAGER status codes. */ + kStatusGroup_LIST = 142, /*!< Group number for List status codes. */ + kStatusGroup_OSA = 143, /*!< Group number for OSA status codes. */ + kStatusGroup_COMMON_TASK = 144, /*!< Group number for Common task status codes. */ + kStatusGroup_MSG = 145, /*!< Group number for messaging status codes. */ +}; + +/*! @brief Generic status return codes. */ +enum _generic_status +{ + kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0), + kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1), + kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2), + kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3), + kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4), + kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5), + kStatus_NoTransferInProgress = MAKE_STATUS(kStatusGroup_Generic, 6), +}; + +/*! @brief Type used for all status and error return values. */ +typedef int32_t status_t; + +/* + * The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t + * defined in previous of this file. + */ +#include "fsl_clock.h" + +/* + * Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral + */ +#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \ + (defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0))) +#include "fsl_reset.h" +#endif + +/* + * Macro guard for whether to use default weak IRQ implementation in drivers + */ +#ifndef FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ +#define FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ 1 +#endif + +/*! @name Min/max macros */ +/* @{ */ +#if !defined(MIN) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#if !defined(MAX) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif +/* @} */ + +/*! @brief Computes the number of elements in an array. */ +#if !defined(ARRAY_SIZE) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +/*! @name UINT16_MAX/UINT32_MAX value */ +/* @{ */ +#if !defined(UINT16_MAX) +#define UINT16_MAX ((uint16_t)-1) +#endif + +#if !defined(UINT32_MAX) +#define UINT32_MAX ((uint32_t)-1) +#endif +/* @} */ + +/*! @name Timer utilities */ +/* @{ */ +/*! Macro to convert a microsecond period to raw count value */ +#define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)((uint64_t)us * clockFreqInHz / 1000000U) +/*! Macro to convert a raw count value to microsecond */ +#define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000000U / clockFreqInHz) + +/*! Macro to convert a millisecond period to raw count value */ +#define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)ms * clockFreqInHz / 1000U) +/*! Macro to convert a raw count value to millisecond */ +#define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000U / clockFreqInHz) +/* @} */ + +/*! @name Alignment variable definition macros */ +/* @{ */ +#if (defined(__ICCARM__)) +/** + * Workaround to disable MISRA C message suppress warnings for IAR compiler. + * http://supp.iar.com/Support/?note=24725 + */ +_Pragma("diag_suppress=Pm120") +#define SDK_PRAGMA(x) _Pragma(#x) + _Pragma("diag_error=Pm120") +/*! Macro to define a variable with alignbytes alignment */ +#define SDK_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var +/*! Macro to define a variable with L1 d-cache line size alignment */ +#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#define SDK_L1DCACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) var +#endif +/*! Macro to define a variable with L2 cache line size alignment */ +#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) +#define SDK_L2CACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L2CACHE_LINESIZE_BYTE) var +#endif +#elif defined(__CC_ARM) || defined(__ARMCC_VERSION) +/*! Macro to define a variable with alignbytes alignment */ +#define SDK_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var +/*! Macro to define a variable with L1 d-cache line size alignment */ +#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#define SDK_L1DCACHE_ALIGN(var) __attribute__((aligned(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))) var +#endif +/*! Macro to define a variable with L2 cache line size alignment */ +#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) +#define SDK_L2CACHE_ALIGN(var) __attribute__((aligned(FSL_FEATURE_L2CACHE_LINESIZE_BYTE))) var +#endif +#elif defined(__GNUC__) +/*! Macro to define a variable with alignbytes alignment */ +#define SDK_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes))) +/*! Macro to define a variable with L1 d-cache line size alignment */ +#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#define SDK_L1DCACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))) +#endif +/*! Macro to define a variable with L2 cache line size alignment */ +#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) +#define SDK_L2CACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L2CACHE_LINESIZE_BYTE))) +#endif +#else +#error Toolchain not supported +#define SDK_ALIGN(var, alignbytes) var +#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#define SDK_L1DCACHE_ALIGN(var) var +#endif +#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) +#define SDK_L2CACHE_ALIGN(var) var +#endif +#endif + +/*! Macro to change a value to a given size aligned value */ +#define SDK_SIZEALIGN(var, alignbytes) \ + ((unsigned int)((var) + ((alignbytes)-1)) & (unsigned int)(~(unsigned int)((alignbytes)-1))) +/* @} */ + +/*! @name Non-cacheable region definition macros */ +/* For initialized non-zero non-cacheable variables, please using "AT_NONCACHEABLE_SECTION_INIT(var) ={xx};" or + * "AT_NONCACHEABLE_SECTION_ALIGN_INIT(var) ={xx};" in your projects to define them, for zero-inited non-cacheable variables, + * please using "AT_NONCACHEABLE_SECTION(var);" or "AT_NONCACHEABLE_SECTION_ALIGN(var);" to define them, these zero-inited variables + * will be initialized to zero in system startup. + */ +/* @{ */ +#if (defined(__ICCARM__)) +#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE)) +#define AT_NONCACHEABLE_SECTION(var) var @"NonCacheable" +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable" +#define AT_NONCACHEABLE_SECTION_INIT(var) var @"NonCacheable.init" +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable.init" +#else +#define AT_NONCACHEABLE_SECTION(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var +#define AT_NONCACHEABLE_SECTION_INIT(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var +#endif +#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION)) +#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE)) +#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"), zero_init)) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \ + __attribute__((section("NonCacheable"), zero_init)) __attribute__((aligned(alignbytes))) var +#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \ + __attribute__((section("NonCacheable.init"))) __attribute__((aligned(alignbytes))) var +#else +#define AT_NONCACHEABLE_SECTION(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var +#define AT_NONCACHEABLE_SECTION_INIT(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) __attribute__((aligned(alignbytes))) var +#endif +#elif(defined(__GNUC__)) +/* For GCC, when the non-cacheable section is required, please define "__STARTUP_INITIALIZE_NONCACHEDATA" + * in your projects to make sure the non-cacheable section variables will be initialized in system startup. + */ +#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE)) +#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \ + __attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes))) +#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \ + __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var __attribute__((aligned(alignbytes))) +#else +#define AT_NONCACHEABLE_SECTION(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes))) +#define AT_NONCACHEABLE_SECTION_INIT(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var __attribute__((aligned(alignbytes))) +#endif +#else +#error Toolchain not supported. +#define AT_NONCACHEABLE_SECTION(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var +#define AT_NONCACHEABLE_SECTION_INIT(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var +#endif +/* @} */ + +/*! @name Time sensitive region */ +/* @{ */ +#if defined(FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE) && FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE +#if (defined(__ICCARM__)) +#define AT_QUICKACCESS_SECTION_CODE(func) func @"CodeQuickAccess" +#define AT_QUICKACCESS_SECTION_DATA(func) func @"DataQuickAccess" +#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION)) +#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"))) func +#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func +#elif(defined(__GNUC__)) +#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"))) func +#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func +#else +#error Toolchain not supported. +#endif /* defined(__ICCARM__) */ +#else +#if (defined(__ICCARM__)) +#define AT_QUICKACCESS_SECTION_CODE(func) func +#define AT_QUICKACCESS_SECTION_DATA(func) func +#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION)) +#define AT_QUICKACCESS_SECTION_CODE(func) func +#define AT_QUICKACCESS_SECTION_DATA(func) func +#elif(defined(__GNUC__)) +#define AT_QUICKACCESS_SECTION_CODE(func) func +#define AT_QUICKACCESS_SECTION_DATA(func) func +#else +#error Toolchain not supported. +#endif +#endif /* __FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE */ +/* @} */ + +/*! @name Ram Function */ +#if (defined(__ICCARM__)) +#define RAMFUNCTION_SECTION_CODE(func) func @"RamFunction" +#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION)) +#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func +#elif(defined(__GNUC__)) +#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func +#else +#error Toolchain not supported. +#endif /* defined(__ICCARM__) */ +/* @} */ +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) + extern "C" +{ +#endif + + /*! + * @brief Enable specific interrupt. + * + * Enable LEVEL1 interrupt. For some devices, there might be multiple interrupt + * levels. For example, there are NVIC and intmux. Here the interrupts connected + * to NVIC are the LEVEL1 interrupts, because they are routed to the core directly. + * The interrupts connected to intmux are the LEVEL2 interrupts, they are routed + * to NVIC first then routed to core. + * + * This function only enables the LEVEL1 interrupts. The number of LEVEL1 interrupts + * is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS. + * + * @param interrupt The IRQ number. + * @retval kStatus_Success Interrupt enabled successfully + * @retval kStatus_Fail Failed to enable the interrupt + */ + static inline status_t EnableIRQ(IRQn_Type interrupt) + { + if (NotAvail_IRQn == interrupt) + { + return kStatus_Fail; + } + +#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0) + if (interrupt >= FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) + { + return kStatus_Fail; + } +#endif + +#if defined(__GIC_PRIO_BITS) + GIC_EnableIRQ(interrupt); +#else + NVIC_EnableIRQ(interrupt); +#endif + return kStatus_Success; + } + + /*! + * @brief Disable specific interrupt. + * + * Disable LEVEL1 interrupt. For some devices, there might be multiple interrupt + * levels. For example, there are NVIC and intmux. Here the interrupts connected + * to NVIC are the LEVEL1 interrupts, because they are routed to the core directly. + * The interrupts connected to intmux are the LEVEL2 interrupts, they are routed + * to NVIC first then routed to core. + * + * This function only disables the LEVEL1 interrupts. The number of LEVEL1 interrupts + * is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS. + * + * @param interrupt The IRQ number. + * @retval kStatus_Success Interrupt disabled successfully + * @retval kStatus_Fail Failed to disable the interrupt + */ + static inline status_t DisableIRQ(IRQn_Type interrupt) + { + if (NotAvail_IRQn == interrupt) + { + return kStatus_Fail; + } + +#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0) + if (interrupt >= FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) + { + return kStatus_Fail; + } +#endif + +#if defined(__GIC_PRIO_BITS) + GIC_DisableIRQ(interrupt); +#else + NVIC_DisableIRQ(interrupt); +#endif + return kStatus_Success; + } + + /*! + * @brief Disable the global IRQ + * + * Disable the global interrupt and return the current primask register. User is required to provided the primask + * register for the EnableGlobalIRQ(). + * + * @return Current primask value. + */ + static inline uint32_t DisableGlobalIRQ(void) + { +#if defined(CPSR_I_Msk) + uint32_t cpsr = __get_CPSR() & CPSR_I_Msk; + + __disable_irq(); + + return cpsr; +#else + uint32_t regPrimask = __get_PRIMASK(); + + __disable_irq(); + + return regPrimask; +#endif + } + + /*! + * @brief Enable the global IRQ + * + * Set the primask register with the provided primask value but not just enable the primask. The idea is for the + * convenience of integration of RTOS. some RTOS get its own management mechanism of primask. User is required to + * use the EnableGlobalIRQ() and DisableGlobalIRQ() in pair. + * + * @param primask value of primask register to be restored. The primask value is supposed to be provided by the + * DisableGlobalIRQ(). + */ + static inline void EnableGlobalIRQ(uint32_t primask) + { +#if defined(CPSR_I_Msk) + __set_CPSR((__get_CPSR() & ~CPSR_I_Msk) | primask); +#else + __set_PRIMASK(primask); +#endif + } + +#if defined(ENABLE_RAM_VECTOR_TABLE) + /*! + * @brief install IRQ handler + * + * @param irq IRQ number + * @param irqHandler IRQ handler address + * @return The old IRQ handler address + */ + uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); +#endif /* ENABLE_RAM_VECTOR_TABLE. */ + +#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) + /*! + * @brief Enable specific interrupt for wake-up from deep-sleep mode. + * + * Enable the interrupt for wake-up from deep sleep mode. + * Some interrupts are typically used in sleep mode only and will not occur during + * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable + * those clocks (significantly increasing power consumption in the reduced power mode), + * making these wake-ups possible. + * + * @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internaly). + * + * @param interrupt The IRQ number. + */ + void EnableDeepSleepIRQ(IRQn_Type interrupt); + + /*! + * @brief Disable specific interrupt for wake-up from deep-sleep mode. + * + * Disable the interrupt for wake-up from deep sleep mode. + * Some interrupts are typically used in sleep mode only and will not occur during + * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable + * those clocks (significantly increasing power consumption in the reduced power mode), + * making these wake-ups possible. + * + * @note This function also disables the interrupt in the NVIC (DisableIRQ() is called internaly). + * + * @param interrupt The IRQ number. + */ + void DisableDeepSleepIRQ(IRQn_Type interrupt); +#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */ + + /*! + * @brief Allocate memory with given alignment and aligned size. + * + * This is provided to support the dynamically allocated memory + * used in cache-able region. + * @param size The length required to malloc. + * @param alignbytes The alignment size. + * @retval The allocated memory. + */ + void *SDK_Malloc(size_t size, size_t alignbytes); + + /*! + * @brief Free memory. + * + * @param ptr The memory to be release. + */ + void SDK_Free(void *ptr); + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* _FSL_COMMON_H_ */ diff --git a/drivers/fsl_sdhc.c b/drivers/fsl_sdhc.c new file mode 100644 index 0000000..24dce54 --- /dev/null +++ b/drivers/fsl_sdhc.c @@ -0,0 +1,1573 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_sdhc.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.sdhc" +#endif + +/*! @brief Clock setting */ +/* Max SD clock divisor from base clock */ +#define SDHC_MAX_DVS ((SDHC_SYSCTL_DVS_MASK >> SDHC_SYSCTL_DVS_SHIFT) + 1U) +#define SDHC_PREV_DVS(x) ((x) -= 1U) +#define SDHC_MAX_CLKFS ((SDHC_SYSCTL_SDCLKFS_MASK >> SDHC_SYSCTL_SDCLKFS_SHIFT) + 1U) +#define SDHC_PREV_CLKFS(x) ((x) >>= 1U) + +/* Typedef for interrupt handler. */ +typedef void (*sdhc_isr_t)(SDHC_Type *base, sdhc_handle_t *handle); + +/*! @brief ADMA table configuration */ +typedef struct _sdhc_adma_table_config +{ + uint32_t *admaTable; /*!< ADMA table address, can't be null if transfer way is ADMA1/ADMA2 */ + uint32_t admaTableWords; /*!< ADMA table length united as words, can't be 0 if transfer way is ADMA1/ADMA2 */ +} sdhc_adma_table_config_t; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Get the instance. + * + * @param base SDHC peripheral base address. + * @return Instance number. + */ +static uint32_t SDHC_GetInstance(SDHC_Type *base); + +/*! + * @brief Set transfer interrupt. + * + * @param base SDHC peripheral base address. + * @param usingInterruptSignal True to use IRQ signal. + */ +static void SDHC_SetTransferInterrupt(SDHC_Type *base, bool usingInterruptSignal); + +/*! + * @brief Start transfer according to current transfer state + * + * @param base SDHC peripheral base address. + * @param command Command to be sent. + * @param data Data to be transferred. + * @param DMA mode selection + */ +static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_data_t *data, sdhc_dma_mode_t dmaMode); + +/*! + * @brief Receive command response + * + * @param base SDHC peripheral base address. + * @param command Command to be sent. + */ +static status_t SDHC_ReceiveCommandResponse(SDHC_Type *base, sdhc_command_t *command); + +/*! + * @brief Read DATAPORT when buffer enable bit is set. + * + * @param base SDHC peripheral base address. + * @param data Data to be read. + * @param transferredWords The number of data words have been transferred last time transaction. + * @return The number of total data words have been transferred after this time transaction. + */ +static uint32_t SDHC_ReadDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t transferredWords); + +/*! + * @brief Read data by using DATAPORT polling way. + * + * @param base SDHC peripheral base address. + * @param data Data to be read. + * @retval kStatus_Fail Read DATAPORT failed. + * @retval kStatus_Success Operate successfully. + */ +static status_t SDHC_ReadByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data); + +/*! + * @brief Write DATAPORT when buffer enable bit is set. + * + * @param base SDHC peripheral base address. + * @param data Data to be read. + * @param transferredWords The number of data words have been transferred last time. + * @return The number of total data words have been transferred after this time transaction. + */ +static uint32_t SDHC_WriteDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t transferredWords); + +/*! + * @brief Write data by using DATAPORT polling way. + * + * @param base SDHC peripheral base address. + * @param data Data to be transferred. + * @retval kStatus_Fail Write DATAPORT failed. + * @retval kStatus_Success Operate successfully. + */ +static status_t SDHC_WriteByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data); + +/*! + * @brief Send command by using polling way. + * + * @param base SDHC peripheral base address. + * @param command Command to be sent. + * @retval kStatus_Fail Send command failed. + * @retval kStatus_Success Operate successfully. + */ +static status_t SDHC_SendCommandBlocking(SDHC_Type *base, sdhc_command_t *command); + +/*! + * @brief Transfer data by DATAPORT and polling way. + * + * @param base SDHC peripheral base address. + * @param data Data to be transferred. + * @retval kStatus_Fail Transfer data failed. + * @retval kStatus_Success Operate successfully. + */ +static status_t SDHC_TransferByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data); + +/*! + * @brief Transfer data by ADMA2 and polling way. + * + * @param base SDHC peripheral base address. + * @param data Data to be transferred. + * @retval kStatus_Fail Transfer data failed. + * @retval kStatus_Success Operate successfully. + */ +static status_t SDHC_TransferByAdma2Blocking(SDHC_Type *base, sdhc_data_t *data); + +/*! + * @brief Transfer data by polling way. + * + * @param dmaMode DMA mode. + * @param base SDHC peripheral base address. + * @param data Data to be transferred. + * @retval kStatus_Fail Transfer data failed. + * @retval kStatus_InvalidArgument Argument is invalid. + * @retval kStatus_Success Operate successfully. + */ +static status_t SDHC_TransferDataBlocking(sdhc_dma_mode_t dmaMode, SDHC_Type *base, sdhc_data_t *data); + +/*! + * @brief Handle card detect interrupt. + * + * @param base SDHC peripheral base address. + * @param handle SDHC handle. + * @param interruptFlags Card detect related interrupt flags. + */ +static void SDHC_TransferHandleCardDetect(SDHC_Type *base, sdhc_handle_t *handle, uint32_t interruptFlags); + +/*! + * @brief Handle command interrupt. + * + * @param base SDHC peripheral base address. + * @param handle SDHC handle. + * @param interruptFlags Command related interrupt flags. + */ +static void SDHC_TransferHandleCommand(SDHC_Type *base, sdhc_handle_t *handle, uint32_t interruptFlags); + +/*! + * @brief Handle data interrupt. + * + * @param base SDHC peripheral base address. + * @param handle SDHC handle. + * @param interruptFlags Data related interrupt flags. + */ +static void SDHC_TransferHandleData(SDHC_Type *base, sdhc_handle_t *handle, uint32_t interruptFlags); + +/*! + * @brief Handle SDIO card interrupt signal. + * + * @param base SDHC peripheral base address. + * @param handle SDHC handle. + */ +static void SDHC_TransferHandleSdioInterrupt(SDHC_Type *base, sdhc_handle_t *handle); + +/*! + * @brief Handle SDIO block gap event. + * + * @param base SDHC peripheral base address. + * @param handle SDHC handle. + */ +static void SDHC_TransferHandleSdioBlockGap(SDHC_Type *base, sdhc_handle_t *handle); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief SDHC internal handle pointer array */ +static sdhc_handle_t *s_sdhcHandle[FSL_FEATURE_SOC_SDHC_COUNT]; + +/*! @brief SDHC base pointer array */ +static SDHC_Type *const s_sdhcBase[] = SDHC_BASE_PTRS; + +/*! @brief SDHC IRQ name array */ +static const IRQn_Type s_sdhcIRQ[] = SDHC_IRQS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief SDHC clock array name */ +static const clock_ip_name_t s_sdhcClock[] = SDHC_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/* SDHC ISR for transactional APIs. */ +static sdhc_isr_t s_sdhcIsr; + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t SDHC_GetInstance(SDHC_Type *base) +{ + uint8_t instance = 0; + + while ((instance < ARRAY_SIZE(s_sdhcBase)) && (s_sdhcBase[instance] != base)) + { + instance++; + } + + assert(instance < ARRAY_SIZE(s_sdhcBase)); + + return instance; +} + +static void SDHC_SetTransferInterrupt(SDHC_Type *base, bool usingInterruptSignal) +{ + uint32_t interruptEnabled; /* The Interrupt status flags to be enabled */ + bool cardDetectDat3 = (bool)(base->PROCTL & SDHC_PROCTL_D3CD_MASK); + + /* Disable all interrupts */ + SDHC_DisableInterruptStatus(base, (uint32_t)kSDHC_AllInterruptFlags); + SDHC_DisableInterruptSignal(base, (uint32_t)kSDHC_AllInterruptFlags); + DisableIRQ(s_sdhcIRQ[SDHC_GetInstance(base)]); + + interruptEnabled = + (kSDHC_CommandIndexErrorFlag | kSDHC_CommandCrcErrorFlag | kSDHC_CommandEndBitErrorFlag | + kSDHC_CommandTimeoutFlag | kSDHC_CommandCompleteFlag | kSDHC_DataTimeoutFlag | kSDHC_DataCrcErrorFlag | + kSDHC_DataEndBitErrorFlag | kSDHC_DataCompleteFlag | kSDHC_AutoCommand12ErrorFlag | kSDHC_BufferReadReadyFlag | + kSDHC_BufferWriteReadyFlag | kSDHC_DmaErrorFlag | kSDHC_DmaCompleteFlag); + if (cardDetectDat3) + { + interruptEnabled |= (kSDHC_CardInsertionFlag | kSDHC_CardRemovalFlag); + } + + SDHC_EnableInterruptStatus(base, interruptEnabled); + if (usingInterruptSignal) + { + SDHC_EnableInterruptSignal(base, interruptEnabled); + } +} + +static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_data_t *data, sdhc_dma_mode_t dmaMode) +{ + uint32_t flags = 0U; + sdhc_transfer_config_t sdhcTransferConfig = {0}; + + /* Define the flag corresponding to each response type. */ + switch (command->responseType) + { + case kCARD_ResponseTypeNone: + break; + case kCARD_ResponseTypeR1: /* Response 1 */ + flags |= (kSDHC_ResponseLength48Flag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); + break; + case kCARD_ResponseTypeR1b: /* Response 1 with busy */ + flags |= (kSDHC_ResponseLength48BusyFlag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); + break; + case kCARD_ResponseTypeR2: /* Response 2 */ + flags |= (kSDHC_ResponseLength136Flag | kSDHC_EnableCrcCheckFlag); + break; + case kCARD_ResponseTypeR3: /* Response 3 */ + flags |= (kSDHC_ResponseLength48Flag); + break; + case kCARD_ResponseTypeR4: /* Response 4 */ + flags |= (kSDHC_ResponseLength48Flag); + break; + case kCARD_ResponseTypeR5: /* Response 5 */ + flags |= (kSDHC_ResponseLength48Flag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); + break; + case kCARD_ResponseTypeR5b: /* Response 5 with busy */ + flags |= (kSDHC_ResponseLength48BusyFlag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); + break; + case kCARD_ResponseTypeR6: /* Response 6 */ + flags |= (kSDHC_ResponseLength48Flag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); + break; + case kCARD_ResponseTypeR7: /* Response 7 */ + flags |= (kSDHC_ResponseLength48Flag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); + break; + default: + break; + } + if (command->type == kCARD_CommandTypeAbort) + { + flags |= kSDHC_CommandTypeAbortFlag; + } + + if (data) + { + flags |= kSDHC_DataPresentFlag; + + if (dmaMode != kSDHC_DmaModeNo) + { + flags |= kSDHC_EnableDmaFlag; + base->IRQSIGEN &= ~(kSDHC_BufferWriteReadyFlag | kSDHC_BufferReadReadyFlag | kSDHC_DmaCompleteFlag); + base->IRQSTATEN &= ~(kSDHC_BufferWriteReadyFlag | kSDHC_BufferReadReadyFlag | kSDHC_DmaCompleteFlag); + } + else + { + base->IRQSIGEN |= kSDHC_BufferWriteReadyFlag | kSDHC_BufferReadReadyFlag; + base->IRQSTATEN |= kSDHC_BufferWriteReadyFlag | kSDHC_BufferReadReadyFlag; + } + + if (data->rxData) + { + flags |= kSDHC_DataReadFlag; + } + if (data->blockCount > 1U) + { + flags |= (kSDHC_MultipleBlockFlag | kSDHC_EnableBlockCountFlag); + if (data->enableAutoCommand12) + { + /* Enable Auto command 12. */ + flags |= kSDHC_EnableAutoCommand12Flag; + } + } + + sdhcTransferConfig.dataBlockSize = data->blockSize; + sdhcTransferConfig.dataBlockCount = data->blockCount; + } + else + { + sdhcTransferConfig.dataBlockSize = 0U; + sdhcTransferConfig.dataBlockCount = 0U; + } + + sdhcTransferConfig.commandArgument = command->argument; + sdhcTransferConfig.commandIndex = command->index; + sdhcTransferConfig.flags = flags; + SDHC_SetTransferConfig(base, &sdhcTransferConfig); +} + +static status_t SDHC_ReceiveCommandResponse(SDHC_Type *base, sdhc_command_t *command) +{ + uint32_t i; + + if (command->responseType != kCARD_ResponseTypeNone) + { + command->response[0U] = SDHC_GetCommandResponse(base, 0U); + if (command->responseType == kCARD_ResponseTypeR2) + { + command->response[1U] = SDHC_GetCommandResponse(base, 1U); + command->response[2U] = SDHC_GetCommandResponse(base, 2U); + command->response[3U] = SDHC_GetCommandResponse(base, 3U); + + i = 4U; + /* R3-R2-R1-R0(lowest 8 bit is invalid bit) has the same format as R2 format in SD specification document + after removed internal CRC7 and end bit. */ + do + { + command->response[i - 1U] <<= 8U; + if (i > 1U) + { + command->response[i - 1U] |= ((command->response[i - 2U] & 0xFF000000U) >> 24U); + } + } while (i--); + } + } + /* check response error flag */ + if ((command->responseErrorFlags != 0U) && + ((command->responseType == kCARD_ResponseTypeR1) || (command->responseType == kCARD_ResponseTypeR1b) || + (command->responseType == kCARD_ResponseTypeR6) || (command->responseType == kCARD_ResponseTypeR5))) + { + if (((command->responseErrorFlags) & (command->response[0U])) != 0U) + { + return kStatus_SDHC_SendCommandFailed; + } + } + + return kStatus_Success; +} + +static uint32_t SDHC_ReadDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t transferredWords) +{ + uint32_t i; + uint32_t totalWords; + uint32_t wordsCanBeRead; /* The words can be read at this time. */ + uint32_t readWatermark = ((base->WML & SDHC_WML_RDWML_MASK) >> SDHC_WML_RDWML_SHIFT); + + /* + * Add non aligned access support ,user need make sure your buffer size is big + * enough to hold the data,in other words,user need make sure the buffer size + * is 4 byte aligned + */ + if (data->blockSize % sizeof(uint32_t) != 0U) + { + data->blockSize += + sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */ + } + + totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t)); + + /* If watermark level is equal or bigger than totalWords, transfers totalWords data. */ + if (readWatermark >= totalWords) + { + wordsCanBeRead = totalWords; + } + /* If watermark level is less than totalWords and left words to be sent is equal or bigger than readWatermark, + transfers watermark level words. */ + else if ((readWatermark < totalWords) && ((totalWords - transferredWords) >= readWatermark)) + { + wordsCanBeRead = readWatermark; + } + /* If watermark level is less than totalWords and left words to be sent is less than readWatermark, transfers left + words. */ + else + { + wordsCanBeRead = (totalWords - transferredWords); + } + + i = 0U; + while (i < wordsCanBeRead) + { + data->rxData[transferredWords++] = SDHC_ReadData(base); + i++; + } + + return transferredWords; +} + +static status_t SDHC_ReadByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data) +{ + uint32_t totalWords; + uint32_t transferredWords = 0U; + status_t error = kStatus_Success; + + /* + * Add non aligned access support ,user need make sure your buffer size is big + * enough to hold the data,in other words,user need make sure the buffer size + * is 4 byte aligned + */ + if (data->blockSize % sizeof(uint32_t) != 0U) + { + data->blockSize += + sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */ + } + + totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t)); + + while ((error == kStatus_Success) && (transferredWords < totalWords)) + { + while (!(SDHC_GetInterruptStatusFlags(base) & (kSDHC_BufferReadReadyFlag | kSDHC_DataErrorFlag))) + { + } + + if (SDHC_GetInterruptStatusFlags(base) & kSDHC_DataErrorFlag) + { + if (!(data->enableIgnoreError)) + { + error = kStatus_Fail; + } + } + if (error == kStatus_Success) + { + transferredWords = SDHC_ReadDataPort(base, data, transferredWords); + } + /* clear buffer ready and error */ + SDHC_ClearInterruptStatusFlags(base, kSDHC_BufferReadReadyFlag | kSDHC_DataErrorFlag); + } + + /* Clear data complete flag after the last read operation. */ + SDHC_ClearInterruptStatusFlags(base, kSDHC_DataCompleteFlag | kSDHC_DataErrorFlag); + + return error; +} + +static uint32_t SDHC_WriteDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t transferredWords) +{ + uint32_t i; + uint32_t totalWords; + uint32_t wordsCanBeWrote; /* Words can be wrote at this time. */ + uint32_t writeWatermark = ((base->WML & SDHC_WML_WRWML_MASK) >> SDHC_WML_WRWML_SHIFT); + + /* + * Add non aligned access support ,user need make sure your buffer size is big + * enough to hold the data,in other words,user need make sure the buffer size + * is 4 byte aligned + */ + if (data->blockSize % sizeof(uint32_t) != 0U) + { + data->blockSize += + sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */ + } + + totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t)); + + /* If watermark level is equal or bigger than totalWords, transfers totalWords data.*/ + if (writeWatermark >= totalWords) + { + wordsCanBeWrote = totalWords; + } + /* If watermark level is less than totalWords and left words to be sent is equal or bigger than watermark, + transfers watermark level words. */ + else if ((writeWatermark < totalWords) && ((totalWords - transferredWords) >= writeWatermark)) + { + wordsCanBeWrote = writeWatermark; + } + /* If watermark level is less than totalWords and left words to be sent is less than watermark, transfers left + words. */ + else + { + wordsCanBeWrote = (totalWords - transferredWords); + } + + i = 0U; + while (i < wordsCanBeWrote) + { + SDHC_WriteData(base, data->txData[transferredWords++]); + i++; + } + + return transferredWords; +} + +static status_t SDHC_WriteByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data) +{ + uint32_t totalWords; + uint32_t transferredWords = 0U; + status_t error = kStatus_Success; + + /* + * Add non aligned access support ,user need make sure your buffer size is big + * enough to hold the data,in other words,user need make sure the buffer size + * is 4 byte aligned + */ + if (data->blockSize % sizeof(uint32_t) != 0U) + { + data->blockSize += + sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */ + } + + totalWords = (data->blockCount * data->blockSize) / sizeof(uint32_t); + + while ((error == kStatus_Success) && (transferredWords < totalWords)) + { + while (!(SDHC_GetInterruptStatusFlags(base) & (kSDHC_BufferWriteReadyFlag | kSDHC_DataErrorFlag))) + { + } + + if (SDHC_GetInterruptStatusFlags(base) & kSDHC_DataErrorFlag) + { + if (!(data->enableIgnoreError)) + { + error = kStatus_Fail; + } + } + if (error == kStatus_Success) + { + transferredWords = SDHC_WriteDataPort(base, data, transferredWords); + } + + /* Clear buffer enable flag to trigger transfer. Clear error flag when SDHC encounter error. */ + SDHC_ClearInterruptStatusFlags(base, (kSDHC_BufferWriteReadyFlag | kSDHC_DataErrorFlag)); + } + + /* Wait write data complete or data transfer error after the last writing operation. */ + while (!(SDHC_GetInterruptStatusFlags(base) & (kSDHC_DataCompleteFlag | kSDHC_DataErrorFlag))) + { + } + if (SDHC_GetInterruptStatusFlags(base) & kSDHC_DataErrorFlag) + { + if (!(data->enableIgnoreError)) + { + error = kStatus_Fail; + } + } + + SDHC_ClearInterruptStatusFlags(base, (kSDHC_DataCompleteFlag | kSDHC_DataErrorFlag)); + + return error; +} + +static status_t SDHC_SendCommandBlocking(SDHC_Type *base, sdhc_command_t *command) +{ + status_t error = kStatus_Success; + + /* Wait command complete or SDHC encounters error. */ + while (!(SDHC_GetInterruptStatusFlags(base) & (kSDHC_CommandCompleteFlag | kSDHC_CommandErrorFlag))) + { + } + + if (SDHC_GetInterruptStatusFlags(base) & kSDHC_CommandErrorFlag) + { + error = kStatus_Fail; + } + /* Receive response when command completes successfully. */ + if (error == kStatus_Success) + { + error = SDHC_ReceiveCommandResponse(base, command); + } + + SDHC_ClearInterruptStatusFlags(base, (kSDHC_CommandCompleteFlag | kSDHC_CommandErrorFlag)); + + return error; +} + +static status_t SDHC_TransferByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data) +{ + status_t error = kStatus_Success; + + if (data->rxData) + { + error = SDHC_ReadByDataPortBlocking(base, data); + } + else + { + error = SDHC_WriteByDataPortBlocking(base, data); + } + + return error; +} + +static status_t SDHC_TransferByAdma2Blocking(SDHC_Type *base, sdhc_data_t *data) +{ + status_t error = kStatus_Success; + + /* Wait data complete or SDHC encounters error. */ + while (!(SDHC_GetInterruptStatusFlags(base) & (kSDHC_DataCompleteFlag | kSDHC_DataErrorFlag | kSDHC_DmaErrorFlag))) + { + } + if (SDHC_GetInterruptStatusFlags(base) & (kSDHC_DataErrorFlag | kSDHC_DmaErrorFlag)) + { + if (!(data->enableIgnoreError)) + { + error = kStatus_Fail; + } + } + SDHC_ClearInterruptStatusFlags( + base, (kSDHC_DataCompleteFlag | kSDHC_DmaCompleteFlag | kSDHC_DataErrorFlag | kSDHC_DmaErrorFlag)); + return error; +} + +#if defined FSL_SDHC_ENABLE_ADMA1 +#define SDHC_TransferByAdma1Blocking(base, data) SDHC_TransferByAdma2Blocking(base, data) +#endif /* FSL_SDHC_ENABLE_ADMA1 */ + +static status_t SDHC_TransferDataBlocking(sdhc_dma_mode_t dmaMode, SDHC_Type *base, sdhc_data_t *data) +{ + status_t error = kStatus_Success; + + switch (dmaMode) + { + case kSDHC_DmaModeNo: + error = SDHC_TransferByDataPortBlocking(base, data); + break; +#if defined FSL_SDHC_ENABLE_ADMA1 + case kSDHC_DmaModeAdma1: + error = SDHC_TransferByAdma1Blocking(base, data); + break; +#endif /* FSL_SDHC_ENABLE_ADMA1 */ + case kSDHC_DmaModeAdma2: + error = SDHC_TransferByAdma2Blocking(base, data); + break; + default: + error = kStatus_InvalidArgument; + break; + } + + return error; +} + +static void SDHC_TransferHandleCardDetect(SDHC_Type *base, sdhc_handle_t *handle, uint32_t interruptFlags) +{ + if (interruptFlags & kSDHC_CardInsertionFlag) + { + if (handle->callback.CardInserted) + { + handle->callback.CardInserted(base, handle->userData); + } + } + else + { + if (handle->callback.CardRemoved) + { + handle->callback.CardRemoved(base, handle->userData); + } + } +} + +static void SDHC_TransferHandleCommand(SDHC_Type *base, sdhc_handle_t *handle, uint32_t interruptFlags) +{ + assert(handle->command); + + if ((interruptFlags & kSDHC_CommandErrorFlag) && (!(handle->data)) && (handle->callback.TransferComplete)) + { + handle->callback.TransferComplete(base, handle, kStatus_SDHC_SendCommandFailed, handle->userData); + } + else + { + /* Receive response */ + SDHC_ReceiveCommandResponse(base, handle->command); + if ((!(handle->data)) && (handle->callback.TransferComplete)) + { + handle->callback.TransferComplete(base, handle, kStatus_Success, handle->userData); + } + } +} + +static void SDHC_TransferHandleData(SDHC_Type *base, sdhc_handle_t *handle, uint32_t interruptFlags) +{ + assert(handle->data); + + if ((!(handle->data->enableIgnoreError)) && (interruptFlags & (kSDHC_DataErrorFlag | kSDHC_DmaErrorFlag)) && + (handle->callback.TransferComplete)) + { + handle->callback.TransferComplete(base, handle, kStatus_SDHC_TransferDataFailed, handle->userData); + } + else + { + if (interruptFlags & kSDHC_BufferReadReadyFlag) + { + handle->transferredWords = SDHC_ReadDataPort(base, handle->data, handle->transferredWords); + } + else if (interruptFlags & kSDHC_BufferWriteReadyFlag) + { + handle->transferredWords = SDHC_WriteDataPort(base, handle->data, handle->transferredWords); + } + else + { + } + + if ((interruptFlags & kSDHC_DataCompleteFlag) && (handle->callback.TransferComplete)) + { + handle->callback.TransferComplete(base, handle, kStatus_Success, handle->userData); + } + else + { + /* Do nothing when DMA complete flag is set. Wait until data complete flag is set. */ + } + } +} + +static void SDHC_TransferHandleSdioInterrupt(SDHC_Type *base, sdhc_handle_t *handle) +{ + if (handle->callback.SdioInterrupt) + { + handle->callback.SdioInterrupt(base, handle->userData); + } +} + +static void SDHC_TransferHandleSdioBlockGap(SDHC_Type *base, sdhc_handle_t *handle) +{ + if (handle->callback.SdioBlockGap) + { + handle->callback.SdioBlockGap(base, handle->userData); + } +} + +/*! + * brief SDHC module initialization function. + * + * Configures the SDHC according to the user configuration. + * + * Example: + code + sdhc_config_t config; + config.cardDetectDat3 = false; + config.endianMode = kSDHC_EndianModeLittle; + config.dmaMode = kSDHC_DmaModeAdma2; + config.readWatermarkLevel = 128U; + config.writeWatermarkLevel = 128U; + SDHC_Init(SDHC, &config); + endcode + * + * param base SDHC peripheral base address. + * param config SDHC configuration information. + * retval kStatus_Success Operate successfully. + */ +void SDHC_Init(SDHC_Type *base, const sdhc_config_t *config) +{ + assert(config); +#if !defined FSL_SDHC_ENABLE_ADMA1 + assert(config->dmaMode != kSDHC_DmaModeAdma1); +#endif /* FSL_SDHC_ENABLE_ADMA1 */ + assert((config->writeWatermarkLevel >= 1U) && (config->writeWatermarkLevel <= 128U)); + assert((config->readWatermarkLevel >= 1U) && (config->readWatermarkLevel <= 128U)); + + uint32_t proctl; + uint32_t wml; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable SDHC clock. */ + CLOCK_EnableClock(s_sdhcClock[SDHC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Reset SDHC. */ + SDHC_Reset(base, kSDHC_ResetAll, 100); + + proctl = base->PROCTL; + wml = base->WML; + + proctl &= ~(SDHC_PROCTL_D3CD_MASK | SDHC_PROCTL_EMODE_MASK | SDHC_PROCTL_DMAS_MASK); + /* Set DAT3 as card detection pin */ + if (config->cardDetectDat3) + { + proctl |= SDHC_PROCTL_D3CD_MASK; + } + /* Endian mode and DMA mode */ + proctl |= (SDHC_PROCTL_EMODE(config->endianMode) | SDHC_PROCTL_DMAS(config->dmaMode)); + + /* Watermark level */ + wml &= ~(SDHC_WML_RDWML_MASK | SDHC_WML_WRWML_MASK); + wml |= (SDHC_WML_RDWML(config->readWatermarkLevel) | SDHC_WML_WRWML(config->writeWatermarkLevel)); + + base->WML = wml; + base->PROCTL = proctl; + + /* Disable all clock auto gated off feature because of DAT0 line logic(card buffer full status) can't be updated + correctly when clock auto gated off is enabled. */ + base->SYSCTL |= (SDHC_SYSCTL_PEREN_MASK | SDHC_SYSCTL_HCKEN_MASK | SDHC_SYSCTL_IPGEN_MASK); + + /* Enable interrupt status but doesn't enable interrupt signal. */ + SDHC_SetTransferInterrupt(base, false); +} + +/*! + * brief Deinitializes the SDHC. + * + * param base SDHC peripheral base address. + */ +void SDHC_Deinit(SDHC_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable clock. */ + CLOCK_DisableClock(s_sdhcClock[SDHC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * brief Resets the SDHC. + * + * param base SDHC peripheral base address. + * param mask The reset type mask(_sdhc_reset). + * param timeout Timeout for reset. + * retval true Reset successfully. + * retval false Reset failed. + */ +bool SDHC_Reset(SDHC_Type *base, uint32_t mask, uint32_t timeout) +{ + base->SYSCTL |= (mask & (SDHC_SYSCTL_RSTA_MASK | SDHC_SYSCTL_RSTC_MASK | SDHC_SYSCTL_RSTD_MASK)); + /* Delay some time to wait reset success. */ + while ((base->SYSCTL & mask)) + { + if (!timeout) + { + break; + } + timeout--; + } + + return ((!timeout) ? false : true); +} + +/*! + * brief Gets the capability information. + * + * param base SDHC peripheral base address. + * param capability Structure to save capability information. + */ +void SDHC_GetCapability(SDHC_Type *base, sdhc_capability_t *capability) +{ + assert(capability); + + uint32_t htCapability; + uint32_t hostVer; + uint32_t maxBlockLength; + + hostVer = base->HOSTVER; + htCapability = base->HTCAPBLT; + + /* Get the capability of SDHC. */ + capability->specVersion = ((hostVer & SDHC_HOSTVER_SVN_MASK) >> SDHC_HOSTVER_SVN_SHIFT); + capability->vendorVersion = ((hostVer & SDHC_HOSTVER_VVN_MASK) >> SDHC_HOSTVER_VVN_SHIFT); + maxBlockLength = ((htCapability & SDHC_HTCAPBLT_MBL_MASK) >> SDHC_HTCAPBLT_MBL_SHIFT); + capability->maxBlockLength = (512U << maxBlockLength); + /* Other attributes not in HTCAPBLT register. */ + capability->maxBlockCount = SDHC_MAX_BLOCK_COUNT; + capability->flags = (htCapability & (kSDHC_SupportAdmaFlag | kSDHC_SupportHighSpeedFlag | kSDHC_SupportDmaFlag | + kSDHC_SupportSuspendResumeFlag | kSDHC_SupportV330Flag)); +#if defined FSL_FEATURE_SDHC_HAS_V300_SUPPORT && FSL_FEATURE_SDHC_HAS_V300_SUPPORT + capability->flags |= (htCapability & kSDHC_SupportV300Flag); +#endif +#if defined FSL_FEATURE_SDHC_HAS_V180_SUPPORT && FSL_FEATURE_SDHC_HAS_V180_SUPPORT + capability->flags |= (htCapability & kSDHC_SupportV180Flag); +#endif + /* eSDHC on all kinetis boards will support 4/8 bit data bus width. */ + capability->flags |= (kSDHC_Support4BitFlag | kSDHC_Support8BitFlag); +} + +/*! + * brief Sets the SD bus clock frequency. + * + * param base SDHC peripheral base address. + * param srcClock_Hz SDHC source clock frequency united in Hz. + * param busClock_Hz SD bus clock frequency united in Hz. + * + * return The nearest frequency of busClock_Hz configured to SD bus. + */ +uint32_t SDHC_SetSdClock(SDHC_Type *base, uint32_t srcClock_Hz, uint32_t busClock_Hz) +{ + assert(srcClock_Hz != 0U); + assert((busClock_Hz != 0U) && (busClock_Hz <= srcClock_Hz)); + + uint32_t totalDiv = 0U; + uint32_t divisor = 0U; + uint32_t prescaler = 0U; + uint32_t sysctl = 0U; + uint32_t nearestFrequency = 0U; + + /* calucate total divisor first */ + if ((totalDiv = srcClock_Hz / busClock_Hz) > (SDHC_MAX_CLKFS * SDHC_MAX_DVS)) + { + return 0U; + } + + if (totalDiv != 0U) + { + /* calucate the divisor (srcClock_Hz / divisor) <= busClock_Hz */ + if ((srcClock_Hz / totalDiv) > busClock_Hz) + { + totalDiv++; + } + + /* divide the total divisor to div and prescaler */ + if (totalDiv > SDHC_MAX_DVS) + { + prescaler = totalDiv / SDHC_MAX_DVS; + /* prescaler must be a value which equal 2^n and smaller than SDHC_MAX_CLKFS */ + while (((SDHC_MAX_CLKFS % prescaler) != 0U) || (prescaler == 1U)) + { + prescaler++; + } + /* calucate the divisor */ + divisor = totalDiv / prescaler; + /* fine tuning the divisor until divisor * prescaler >= totalDiv */ + while ((divisor * prescaler) < totalDiv) + { + divisor++; + } + + nearestFrequency = srcClock_Hz / (divisor == 0U ? 1U : divisor) / prescaler; + } + else + { + divisor = totalDiv; + prescaler = 0U; + nearestFrequency = srcClock_Hz / divisor; + } + } + /* in this condition , srcClock_Hz = busClock_Hz, */ + else + { + /* total divider = 1U */ + divisor = 0U; + prescaler = 0U; + nearestFrequency = srcClock_Hz; + } + + /* calucate the value write to register */ + if (divisor != 0U) + { + SDHC_PREV_DVS(divisor); + } + /* calucate the value write to register */ + if (prescaler != 0U) + { + SDHC_PREV_CLKFS(prescaler); + } + + /* Disable SD clock. It should be disabled before changing the SD clock frequency.*/ + base->SYSCTL &= ~SDHC_SYSCTL_SDCLKEN_MASK; + + /* Set the SD clock frequency divisor, SD clock frequency select, data timeout counter value. */ + sysctl = base->SYSCTL; + sysctl &= ~(SDHC_SYSCTL_DVS_MASK | SDHC_SYSCTL_SDCLKFS_MASK | SDHC_SYSCTL_DTOCV_MASK); + sysctl |= (SDHC_SYSCTL_DVS(divisor) | SDHC_SYSCTL_SDCLKFS(prescaler) | SDHC_SYSCTL_DTOCV(0xEU)); + base->SYSCTL = sysctl; + + /* Wait until the SD clock is stable. */ + while (!(base->PRSSTAT & SDHC_PRSSTAT_SDSTB_MASK)) + { + } + /* Enable the SD clock. */ + base->SYSCTL |= SDHC_SYSCTL_SDCLKEN_MASK; + + return nearestFrequency; +} + +/*! + * brief Sends 80 clocks to the card to set it to the active state. + * + * This function must be called each time the card is inserted to ensure that the card can receive the command + * correctly. + * + * param base SDHC peripheral base address. + * param timeout Timeout to initialize card. + * retval true Set card active successfully. + * retval false Set card active failed. + */ +bool SDHC_SetCardActive(SDHC_Type *base, uint32_t timeout) +{ + base->SYSCTL |= SDHC_SYSCTL_INITA_MASK; + /* Delay some time to wait card become active state. */ + while (base->SYSCTL & SDHC_SYSCTL_INITA_MASK) + { + if (!timeout) + { + break; + } + timeout--; + } + + return ((!timeout) ? false : true); +} + +/*! + * brief Sets the card transfer-related configuration. + * + * This function fills the card transfer-related command argument/transfer flag/data size. The command and data are sent + by + * SDHC after calling this function. + * + * Example: + code + sdhc_transfer_config_t transferConfig; + transferConfig.dataBlockSize = 512U; + transferConfig.dataBlockCount = 2U; + transferConfig.commandArgument = 0x01AAU; + transferConfig.commandIndex = 8U; + transferConfig.flags |= (kSDHC_EnableDmaFlag | kSDHC_EnableAutoCommand12Flag | kSDHC_MultipleBlockFlag); + SDHC_SetTransferConfig(SDHC, &transferConfig); + endcode + * + * param base SDHC peripheral base address. + * param config Command configuration structure. + */ +void SDHC_SetTransferConfig(SDHC_Type *base, const sdhc_transfer_config_t *config) +{ + assert(config); + assert(config->dataBlockSize <= (SDHC_BLKATTR_BLKSIZE_MASK >> SDHC_BLKATTR_BLKSIZE_SHIFT)); + assert(config->dataBlockCount <= (SDHC_BLKATTR_BLKCNT_MASK >> SDHC_BLKATTR_BLKCNT_SHIFT)); + + base->BLKATTR = ((base->BLKATTR & ~(SDHC_BLKATTR_BLKSIZE_MASK | SDHC_BLKATTR_BLKCNT_MASK)) | + (SDHC_BLKATTR_BLKSIZE(config->dataBlockSize) | SDHC_BLKATTR_BLKCNT(config->dataBlockCount))); + base->CMDARG = config->commandArgument; + base->XFERTYP = (((config->commandIndex << SDHC_XFERTYP_CMDINX_SHIFT) & SDHC_XFERTYP_CMDINX_MASK) | + (config->flags & (SDHC_XFERTYP_DMAEN_MASK | SDHC_XFERTYP_MSBSEL_MASK | SDHC_XFERTYP_DPSEL_MASK | + SDHC_XFERTYP_CMDTYP_MASK | SDHC_XFERTYP_BCEN_MASK | SDHC_XFERTYP_CICEN_MASK | + SDHC_XFERTYP_CCCEN_MASK | SDHC_XFERTYP_RSPTYP_MASK | SDHC_XFERTYP_DTDSEL_MASK | + SDHC_XFERTYP_AC12EN_MASK))); +} + +/*! + * brief Enables or disables the SDIO card control. + * + * param base SDHC peripheral base address. + * param mask SDIO card control flags mask(_sdhc_sdio_control_flag). + * param enable True to enable, false to disable. + */ +void SDHC_EnableSdioControl(SDHC_Type *base, uint32_t mask, bool enable) +{ + uint32_t proctl = base->PROCTL; + uint32_t vendor = base->VENDOR; + + if (enable) + { + if (mask & kSDHC_StopAtBlockGapFlag) + { + proctl |= SDHC_PROCTL_SABGREQ_MASK; + } + if (mask & kSDHC_ReadWaitControlFlag) + { + proctl |= SDHC_PROCTL_RWCTL_MASK; + } + if (mask & kSDHC_InterruptAtBlockGapFlag) + { + proctl |= SDHC_PROCTL_IABG_MASK; + } + if (mask & kSDHC_ExactBlockNumberReadFlag) + { + vendor |= SDHC_VENDOR_EXBLKNU_MASK; + } + } + else + { + if (mask & kSDHC_StopAtBlockGapFlag) + { + proctl &= ~SDHC_PROCTL_SABGREQ_MASK; + } + if (mask & kSDHC_ReadWaitControlFlag) + { + proctl &= ~SDHC_PROCTL_RWCTL_MASK; + } + if (mask & kSDHC_InterruptAtBlockGapFlag) + { + proctl &= ~SDHC_PROCTL_IABG_MASK; + } + if (mask & kSDHC_ExactBlockNumberReadFlag) + { + vendor &= ~SDHC_VENDOR_EXBLKNU_MASK; + } + } + + base->PROCTL = proctl; + base->VENDOR = vendor; +} + +/*! + * brief Configures the MMC boot feature. + * + * Example: + code + sdhc_boot_config_t config; + config.ackTimeoutCount = 4; + config.bootMode = kSDHC_BootModeNormal; + config.blockCount = 5; + config.enableBootAck = true; + config.enableBoot = true; + config.enableAutoStopAtBlockGap = true; + SDHC_SetMmcBootConfig(SDHC, &config); + endcode + * + * param base SDHC peripheral base address. + * param config The MMC boot configuration information. + */ +void SDHC_SetMmcBootConfig(SDHC_Type *base, const sdhc_boot_config_t *config) +{ + assert(config); + assert(config->ackTimeoutCount <= (SDHC_MMCBOOT_DTOCVACK_MASK >> SDHC_MMCBOOT_DTOCVACK_SHIFT)); + assert(config->blockCount <= (SDHC_MMCBOOT_BOOTBLKCNT_MASK >> SDHC_MMCBOOT_BOOTBLKCNT_SHIFT)); + + uint32_t mmcboot = 0U; + + mmcboot = (SDHC_MMCBOOT_DTOCVACK(config->ackTimeoutCount) | SDHC_MMCBOOT_BOOTMODE(config->bootMode) | + SDHC_MMCBOOT_BOOTBLKCNT(config->blockCount)); + if (config->enableBootAck) + { + mmcboot |= SDHC_MMCBOOT_BOOTACK_MASK; + } + if (config->enableBoot) + { + mmcboot |= SDHC_MMCBOOT_BOOTEN_MASK; + } + if (config->enableAutoStopAtBlockGap) + { + mmcboot |= SDHC_MMCBOOT_AUTOSABGEN_MASK; + } + base->MMCBOOT = mmcboot; +} + +/*! + * brief Sets the ADMA descriptor table configuration. + * + * param base SDHC peripheral base address. + * param dmaMode DMA mode. + * param table ADMA table address. + * param tableWords ADMA table buffer length united as Words. + * param data Data buffer address. + * param dataBytes Data length united as bytes. + * retval kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data. + * retval kStatus_Success Operate successfully. + */ +status_t SDHC_SetAdmaTableConfig(SDHC_Type *base, + sdhc_dma_mode_t dmaMode, + uint32_t *table, + uint32_t tableWords, + const uint32_t *data, + uint32_t dataBytes) +{ + status_t error = kStatus_Success; + const uint32_t *startAddress = data; + uint32_t entries; + uint32_t i; +#if defined FSL_SDHC_ENABLE_ADMA1 + sdhc_adma1_descriptor_t *adma1EntryAddress; +#endif + sdhc_adma2_descriptor_t *adma2EntryAddress; + + if ((((!table) || (!tableWords)) && ((dmaMode == kSDHC_DmaModeAdma1) || (dmaMode == kSDHC_DmaModeAdma2))) || + (!data) || (!dataBytes) +#if !defined FSL_SDHC_ENABLE_ADMA1 + || (dmaMode == kSDHC_DmaModeAdma1) +#endif + ) + { + error = kStatus_InvalidArgument; + } + else if (((dmaMode == kSDHC_DmaModeAdma2) && (((uint32_t)startAddress % SDHC_ADMA2_LENGTH_ALIGN) != 0U)) +#if defined FSL_SDHC_ENABLE_ADMA1 + || ((dmaMode == kSDHC_DmaModeAdma1) && (((uint32_t)startAddress % SDHC_ADMA1_LENGTH_ALIGN) != 0U)) +#endif + ) + { + error = kStatus_SDHC_DMADataBufferAddrNotAlign; + } + else + { + switch (dmaMode) + { + case kSDHC_DmaModeNo: + break; +#if defined FSL_SDHC_ENABLE_ADMA1 + case kSDHC_DmaModeAdma1: + /* + * Add non aligned access support ,user need make sure your buffer size is big + * enough to hold the data,in other words,user need make sure the buffer size + * is 4 byte aligned + */ + if (dataBytes % sizeof(uint32_t) != 0U) + { + dataBytes += + sizeof(uint32_t) - (dataBytes % sizeof(uint32_t)); /* make the data length as word-aligned */ + } + + /* Check if ADMA descriptor's number is enough. */ + entries = ((dataBytes / SDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + 1U); + /* ADMA1 needs two descriptors to finish a transfer */ + entries <<= 1U; + if (entries > ((tableWords * sizeof(uint32_t)) / sizeof(sdhc_adma1_descriptor_t))) + { + error = kStatus_OutOfRange; + } + else + { + adma1EntryAddress = (sdhc_adma1_descriptor_t *)(table); + for (i = 0U; i < entries; i += 2U) + { + /* Each descriptor for ADMA1 is 32-bit in length */ + if ((dataBytes - sizeof(uint32_t) * (startAddress - data)) <= + SDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + { + /* The last piece of data, setting end flag in descriptor */ + adma1EntryAddress[i] = ((uint32_t)(dataBytes - sizeof(uint32_t) * (startAddress - data)) + << SDHC_ADMA1_DESCRIPTOR_LENGTH_SHIFT); + adma1EntryAddress[i] |= kSDHC_Adma1DescriptorTypeSetLength; + adma1EntryAddress[i + 1U] = (uint32_t)(startAddress); + adma1EntryAddress[i + 1U] |= + (kSDHC_Adma1DescriptorTypeTransfer | kSDHC_Adma1DescriptorEndFlag); + } + else + { + adma1EntryAddress[i] = ((uint32_t)SDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY + << SDHC_ADMA1_DESCRIPTOR_LENGTH_SHIFT); + adma1EntryAddress[i] |= kSDHC_Adma1DescriptorTypeSetLength; + adma1EntryAddress[i + 1U] = + ((uint32_t)(startAddress) << SDHC_ADMA1_DESCRIPTOR_ADDRESS_SHIFT); + adma1EntryAddress[i + 1U] |= kSDHC_Adma1DescriptorTypeTransfer; + startAddress += SDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY / sizeof(uint32_t); + } + } + + /* When use ADMA, disable simple DMA */ + base->DSADDR = 0U; + base->ADSADDR = (uint32_t)table; + } + break; +#endif /* FSL_SDHC_ENABLE_ADMA1 */ + case kSDHC_DmaModeAdma2: + /* + * Add non aligned access support ,user need make sure your buffer size is big + * enough to hold the data,in other words,user need make sure the buffer size + * is 4 byte aligned + */ + if (dataBytes % sizeof(uint32_t) != 0U) + { + dataBytes += + sizeof(uint32_t) - (dataBytes % sizeof(uint32_t)); /* make the data length as word-aligned */ + } + + /* Check if ADMA descriptor's number is enough. */ + entries = ((dataBytes / SDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + 1U); + if (entries > ((tableWords * sizeof(uint32_t)) / sizeof(sdhc_adma2_descriptor_t))) + { + error = kStatus_OutOfRange; + } + else + { + adma2EntryAddress = (sdhc_adma2_descriptor_t *)(table); + for (i = 0U; i < entries; i++) + { + /* Each descriptor for ADMA2 is 64-bit in length */ + if ((dataBytes - sizeof(uint32_t) * (startAddress - data)) <= + SDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + { + /* The last piece of data, setting end flag in descriptor */ + adma2EntryAddress[i].address = startAddress; + adma2EntryAddress[i].attribute = ((dataBytes - sizeof(uint32_t) * (startAddress - data)) + << SDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT); + adma2EntryAddress[i].attribute |= + (kSDHC_Adma2DescriptorTypeTransfer | kSDHC_Adma2DescriptorEndFlag); + } + else + { + adma2EntryAddress[i].address = startAddress; + adma2EntryAddress[i].attribute = + (((SDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY / sizeof(uint32_t)) * sizeof(uint32_t)) + << SDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT); + adma2EntryAddress[i].attribute |= kSDHC_Adma2DescriptorTypeTransfer; + startAddress += (SDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY / sizeof(uint32_t)); + } + } + + /* When use ADMA, disable simple DMA */ + base->DSADDR = 0U; + base->ADSADDR = (uint32_t)table; + } + break; + default: + break; + } + } + + return error; +} + +/*! + * brief Transfers the command/data using a blocking method. + * + * This function waits until the command response/data is received or the SDHC encounters an error by polling the status + * flag. + * This function support non word align data addr transfer support, if data buffer addr is not align in DMA mode, + * the API will continue finish the transfer by polling IO directly + * The application must not call this API in multiple threads at the same time. Because of that this API doesn't support + * the re-entry mechanism. + * + * note There is no need to call the API 'SDHC_TransferCreateHandle' when calling this API. + * + * param base SDHC peripheral base address. + * param admaTable ADMA table address, can't be null if transfer way is ADMA1/ADMA2. + * param admaTableWords ADMA table length united as words, can't be 0 if transfer way is ADMA1/ADMA2. + * param transfer Transfer content. + * retval kStatus_InvalidArgument Argument is invalid. + * retval kStatus_SDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed. + * retval kStatus_SDHC_SendCommandFailed Send command failed. + * retval kStatus_SDHC_TransferDataFailed Transfer data failed. + * retval kStatus_Success Operate successfully. + */ +status_t SDHC_TransferBlocking(SDHC_Type *base, uint32_t *admaTable, uint32_t admaTableWords, sdhc_transfer_t *transfer) +{ + assert(transfer); + + status_t error = kStatus_Success; + sdhc_dma_mode_t dmaMode = (sdhc_dma_mode_t)((base->PROCTL & SDHC_PROCTL_DMAS_MASK) >> SDHC_PROCTL_DMAS_SHIFT); + sdhc_command_t *command = transfer->command; + sdhc_data_t *data = transfer->data; + + /* make sure the cmd/block count is valid */ + if ((!command) || (data && (data->blockCount > SDHC_MAX_BLOCK_COUNT))) + { + return kStatus_InvalidArgument; + } + + /* Wait until command/data bus out of busy status. */ + while (SDHC_GetPresentStatusFlags(base) & kSDHC_CommandInhibitFlag) + { + } + while (data && (SDHC_GetPresentStatusFlags(base) & kSDHC_DataInhibitFlag)) + { + } + + /* Update ADMA descriptor table according to different DMA mode(no DMA, ADMA1, ADMA2).*/ + if (data && (NULL != admaTable)) + { + error = + SDHC_SetAdmaTableConfig(base, dmaMode, admaTable, admaTableWords, + (data->rxData ? data->rxData : data->txData), (data->blockCount * data->blockSize)); + /* in this situation , we disable the DMA instead of polling transfer mode */ + if (error != kStatus_Success) + { + dmaMode = kSDHC_DmaModeNo; + } + } + + /* Send command and receive data. */ + SDHC_StartTransfer(base, command, data, dmaMode); + + if (kStatus_Success != SDHC_SendCommandBlocking(base, command)) + { + return kStatus_SDHC_SendCommandFailed; + } + + if (data && (kStatus_Success != SDHC_TransferDataBlocking(dmaMode, base, data))) + { + return kStatus_SDHC_TransferDataFailed; + } + + return kStatus_Success; +} + +/*! + * brief Creates the SDHC handle. + * + * param base SDHC peripheral base address. + * param handle SDHC handle pointer. + * param callback Structure pointer to contain all callback functions. + * param userData Callback function parameter. + */ +void SDHC_TransferCreateHandle(SDHC_Type *base, + sdhc_handle_t *handle, + const sdhc_transfer_callback_t *callback, + void *userData) +{ + assert(handle); + assert(callback); + + /* Zero the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Set the callback. */ + handle->callback.CardInserted = callback->CardInserted; + handle->callback.CardRemoved = callback->CardRemoved; + handle->callback.SdioInterrupt = callback->SdioInterrupt; + handle->callback.SdioBlockGap = callback->SdioBlockGap; + handle->callback.TransferComplete = callback->TransferComplete; + handle->userData = userData; + + /* Save the handle in global variables to support the double weak mechanism. */ + s_sdhcHandle[SDHC_GetInstance(base)] = handle; + + /* Enable interrupt in NVIC. */ + SDHC_SetTransferInterrupt(base, true); + + /* save IRQ handler */ + s_sdhcIsr = SDHC_TransferHandleIRQ; + + EnableIRQ(s_sdhcIRQ[SDHC_GetInstance(base)]); +} + +/*! + * brief Transfers the command/data using an interrupt and an asynchronous method. + * + * This function sends a command and data and returns immediately. It doesn't wait the transfer complete or encounter an + * error. + * This function support non word align data addr transfer support, if data buffer addr is not align in DMA mode, + * the API will continue finish the transfer by polling IO directly + * The application must not call this API in multiple threads at the same time. Because of that this API doesn't support + * the re-entry mechanism. + * + * note Call the API 'SDHC_TransferCreateHandle' when calling this API. + * + * param base SDHC peripheral base address. + * param handle SDHC handle. + * param admaTable ADMA table address, can't be null if transfer way is ADMA1/ADMA2. + * param admaTableWords ADMA table length united as words, can't be 0 if transfer way is ADMA1/ADMA2. + * param transfer Transfer content. + * retval kStatus_InvalidArgument Argument is invalid. + * retval kStatus_SDHC_BusyTransferring Busy transferring. + * retval kStatus_SDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed. + * retval kStatus_Success Operate successfully. + */ +status_t SDHC_TransferNonBlocking( + SDHC_Type *base, sdhc_handle_t *handle, uint32_t *admaTable, uint32_t admaTableWords, sdhc_transfer_t *transfer) +{ + assert(transfer); + + sdhc_dma_mode_t dmaMode = (sdhc_dma_mode_t)((base->PROCTL & SDHC_PROCTL_DMAS_MASK) >> SDHC_PROCTL_DMAS_SHIFT); + status_t error = kStatus_Success; + sdhc_command_t *command = transfer->command; + sdhc_data_t *data = transfer->data; + + /* make sure cmd/block count is valid */ + if ((!command) || (data && (data->blockCount > SDHC_MAX_BLOCK_COUNT))) + { + return kStatus_InvalidArgument; + } + + /* Wait until command/data bus out of busy status. */ + if ((SDHC_GetPresentStatusFlags(base) & kSDHC_CommandInhibitFlag) || + (data && (SDHC_GetPresentStatusFlags(base) & kSDHC_DataInhibitFlag))) + { + return kStatus_SDHC_BusyTransferring; + } + + /* Update ADMA descriptor table according to different DMA mode(no DMA, ADMA1, ADMA2).*/ + if (data && (NULL != admaTable)) + { + error = + SDHC_SetAdmaTableConfig(base, dmaMode, admaTable, admaTableWords, + (data->rxData ? data->rxData : data->txData), (data->blockCount * data->blockSize)); + /* in this situation , we disable the DMA instead of polling transfer mode */ + if (error != kStatus_Success) + { + /* change to polling mode */ + dmaMode = kSDHC_DmaModeNo; + } + } + + /* Save command and data into handle before transferring. */ + handle->command = command; + handle->data = data; + handle->interruptFlags = 0U; + /* transferredWords will only be updated in ISR when transfer way is DATAPORT. */ + handle->transferredWords = 0U; + + SDHC_StartTransfer(base, command, data, dmaMode); + + return kStatus_Success; +} + +/*! + * brief IRQ handler for the SDHC. + * + * This function deals with the IRQs on the given host controller. + * + * param base SDHC peripheral base address. + * param handle SDHC handle. + */ +void SDHC_TransferHandleIRQ(SDHC_Type *base, sdhc_handle_t *handle) +{ + assert(handle); + + uint32_t interruptFlags; + + interruptFlags = SDHC_GetInterruptStatusFlags(base); + handle->interruptFlags = interruptFlags; + + if (interruptFlags & kSDHC_CardDetectFlag) + { + SDHC_TransferHandleCardDetect(base, handle, (interruptFlags & kSDHC_CardDetectFlag)); + } + if (interruptFlags & kSDHC_CommandFlag) + { + SDHC_TransferHandleCommand(base, handle, (interruptFlags & kSDHC_CommandFlag)); + } + if (interruptFlags & kSDHC_DataFlag) + { + SDHC_TransferHandleData(base, handle, (interruptFlags & kSDHC_DataFlag)); + } + if (interruptFlags & kSDHC_CardInterruptFlag) + { + SDHC_TransferHandleSdioInterrupt(base, handle); + } + if (interruptFlags & kSDHC_BlockGapEventFlag) + { + SDHC_TransferHandleSdioBlockGap(base, handle); + } + + SDHC_ClearInterruptStatusFlags(base, interruptFlags); +} + +#if defined(SDHC) +void SDHC_DriverIRQHandler(void) +{ + assert(s_sdhcHandle[0]); + + s_sdhcIsr(SDHC, s_sdhcHandle[0]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif diff --git a/drivers/fsl_sdhc.h b/drivers/fsl_sdhc.h new file mode 100644 index 0000000..52dc86d --- /dev/null +++ b/drivers/fsl_sdhc.h @@ -0,0 +1,1091 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _FSL_SDHC_H_ +#define _FSL_SDHC_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup sdhc + * @{ + */ + +/****************************************************************************** + * Definitions. + *****************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief Driver version 2.1.8. */ +#define FSL_SDHC_DRIVER_VERSION (MAKE_VERSION(2U, 1U, 8U)) +/*@}*/ + +/*! @brief Maximum block count can be set one time */ +#define SDHC_MAX_BLOCK_COUNT (SDHC_BLKATTR_BLKCNT_MASK >> SDHC_BLKATTR_BLKCNT_SHIFT) + +/*! @brief SDHC status */ +enum _sdhc_status +{ + kStatus_SDHC_BusyTransferring = MAKE_STATUS(kStatusGroup_SDHC, 0U), /*!< Transfer is on-going */ + kStatus_SDHC_PrepareAdmaDescriptorFailed = MAKE_STATUS(kStatusGroup_SDHC, 1U), /*!< Set DMA descriptor failed */ + kStatus_SDHC_SendCommandFailed = MAKE_STATUS(kStatusGroup_SDHC, 2U), /*!< Send command failed */ + kStatus_SDHC_TransferDataFailed = MAKE_STATUS(kStatusGroup_SDHC, 3U), /*!< Transfer data failed */ + kStatus_SDHC_DMADataBufferAddrNotAlign = + MAKE_STATUS(kStatusGroup_SDHC, 4U), /*!< data buffer addr not align in DMA mode */ +}; + +/*! @brief Host controller capabilities flag mask */ +enum _sdhc_capability_flag +{ + kSDHC_SupportAdmaFlag = SDHC_HTCAPBLT_ADMAS_MASK, /*!< Support ADMA */ + kSDHC_SupportHighSpeedFlag = SDHC_HTCAPBLT_HSS_MASK, /*!< Support high-speed */ + kSDHC_SupportDmaFlag = SDHC_HTCAPBLT_DMAS_MASK, /*!< Support DMA */ + kSDHC_SupportSuspendResumeFlag = SDHC_HTCAPBLT_SRS_MASK, /*!< Support suspend/resume */ + kSDHC_SupportV330Flag = SDHC_HTCAPBLT_VS33_MASK, /*!< Support voltage 3.3V */ +#if defined FSL_FEATURE_SDHC_HAS_V300_SUPPORT && FSL_FEATURE_SDHC_HAS_V300_SUPPORT + kSDHC_SupportV300Flag = SDHC_HTCAPBLT_VS30_MASK, /*!< Support voltage 3.0V */ +#endif +#if defined FSL_FEATURE_SDHC_HAS_V180_SUPPORT && FSL_FEATURE_SDHC_HAS_V180_SUPPORT + kSDHC_SupportV180Flag = SDHC_HTCAPBLT_VS18_MASK, /*!< Support voltage 1.8V */ +#endif + /* Put additional two flags in HTCAPBLT_MBL's position. */ + kSDHC_Support4BitFlag = (SDHC_HTCAPBLT_MBL_SHIFT << 0U), /*!< Support 4 bit mode */ + kSDHC_Support8BitFlag = (SDHC_HTCAPBLT_MBL_SHIFT << 1U), /*!< Support 8 bit mode */ +}; + +/*! @brief Wakeup event mask */ +enum _sdhc_wakeup_event +{ + kSDHC_WakeupEventOnCardInt = SDHC_PROCTL_WECINT_MASK, /*!< Wakeup on card interrupt */ + kSDHC_WakeupEventOnCardInsert = SDHC_PROCTL_WECINS_MASK, /*!< Wakeup on card insertion */ + kSDHC_WakeupEventOnCardRemove = SDHC_PROCTL_WECRM_MASK, /*!< Wakeup on card removal */ + + kSDHC_WakeupEventsAll = (kSDHC_WakeupEventOnCardInt | kSDHC_WakeupEventOnCardInsert | + kSDHC_WakeupEventOnCardRemove), /*!< All wakeup events */ +}; + +/*! @brief Reset type mask */ +enum _sdhc_reset +{ + kSDHC_ResetAll = SDHC_SYSCTL_RSTA_MASK, /*!< Reset all except card detection */ + kSDHC_ResetCommand = SDHC_SYSCTL_RSTC_MASK, /*!< Reset command line */ + kSDHC_ResetData = SDHC_SYSCTL_RSTD_MASK, /*!< Reset data line */ + + kSDHC_ResetsAll = (kSDHC_ResetAll | kSDHC_ResetCommand | kSDHC_ResetData), /*!< All reset types */ +}; + +/*! @brief Transfer flag mask */ +enum _sdhc_transfer_flag +{ + kSDHC_EnableDmaFlag = SDHC_XFERTYP_DMAEN_MASK, /*!< Enable DMA */ + + kSDHC_CommandTypeSuspendFlag = (SDHC_XFERTYP_CMDTYP(1U)), /*!< Suspend command */ + kSDHC_CommandTypeResumeFlag = (SDHC_XFERTYP_CMDTYP(2U)), /*!< Resume command */ + kSDHC_CommandTypeAbortFlag = (SDHC_XFERTYP_CMDTYP(3U)), /*!< Abort command */ + + kSDHC_EnableBlockCountFlag = SDHC_XFERTYP_BCEN_MASK, /*!< Enable block count */ + kSDHC_EnableAutoCommand12Flag = SDHC_XFERTYP_AC12EN_MASK, /*!< Enable auto CMD12 */ + kSDHC_DataReadFlag = SDHC_XFERTYP_DTDSEL_MASK, /*!< Enable data read */ + kSDHC_MultipleBlockFlag = SDHC_XFERTYP_MSBSEL_MASK, /*!< Multiple block data read/write */ + + kSDHC_ResponseLength136Flag = SDHC_XFERTYP_RSPTYP(1U), /*!< 136 bit response length */ + kSDHC_ResponseLength48Flag = SDHC_XFERTYP_RSPTYP(2U), /*!< 48 bit response length */ + kSDHC_ResponseLength48BusyFlag = SDHC_XFERTYP_RSPTYP(3U), /*!< 48 bit response length with busy status */ + + kSDHC_EnableCrcCheckFlag = SDHC_XFERTYP_CCCEN_MASK, /*!< Enable CRC check */ + kSDHC_EnableIndexCheckFlag = SDHC_XFERTYP_CICEN_MASK, /*!< Enable index check */ + kSDHC_DataPresentFlag = SDHC_XFERTYP_DPSEL_MASK, /*!< Data present flag */ +}; + +/*! @brief Present status flag mask */ +enum _sdhc_present_status_flag +{ + kSDHC_CommandInhibitFlag = SDHC_PRSSTAT_CIHB_MASK, /*!< Command inhibit */ + kSDHC_DataInhibitFlag = SDHC_PRSSTAT_CDIHB_MASK, /*!< Data inhibit */ + kSDHC_DataLineActiveFlag = SDHC_PRSSTAT_DLA_MASK, /*!< Data line active */ + kSDHC_SdClockStableFlag = SDHC_PRSSTAT_SDSTB_MASK, /*!< SD bus clock stable */ + kSDHC_WriteTransferActiveFlag = SDHC_PRSSTAT_WTA_MASK, /*!< Write transfer active */ + kSDHC_ReadTransferActiveFlag = SDHC_PRSSTAT_RTA_MASK, /*!< Read transfer active */ + kSDHC_BufferWriteEnableFlag = SDHC_PRSSTAT_BWEN_MASK, /*!< Buffer write enable */ + kSDHC_BufferReadEnableFlag = SDHC_PRSSTAT_BREN_MASK, /*!< Buffer read enable */ + kSDHC_CardInsertedFlag = SDHC_PRSSTAT_CINS_MASK, /*!< Card inserted */ + kSDHC_CommandLineLevelFlag = SDHC_PRSSTAT_CLSL_MASK, /*!< Command line signal level */ + + kSDHC_Data0LineLevelFlag = (1U << 24U), /*!< Data0 line signal level */ + kSDHC_Data1LineLevelFlag = (1U << 25U), /*!< Data1 line signal level */ + kSDHC_Data2LineLevelFlag = (1U << 26U), /*!< Data2 line signal level */ + kSDHC_Data3LineLevelFlag = (1U << 27U), /*!< Data3 line signal level */ + kSDHC_Data4LineLevelFlag = (1U << 28U), /*!< Data4 line signal level */ + kSDHC_Data5LineLevelFlag = (1U << 29U), /*!< Data5 line signal level */ + kSDHC_Data6LineLevelFlag = (1U << 30U), /*!< Data6 line signal level */ + kSDHC_Data7LineLevelFlag = (int)(1U << 31U), /*!< Data7 line signal level */ +}; + +/*! @brief Interrupt status flag mask */ +enum _sdhc_interrupt_status_flag +{ + kSDHC_CommandCompleteFlag = SDHC_IRQSTAT_CC_MASK, /*!< Command complete */ + kSDHC_DataCompleteFlag = SDHC_IRQSTAT_TC_MASK, /*!< Data complete */ + kSDHC_BlockGapEventFlag = SDHC_IRQSTAT_BGE_MASK, /*!< Block gap event */ + kSDHC_DmaCompleteFlag = SDHC_IRQSTAT_DINT_MASK, /*!< DMA interrupt */ + kSDHC_BufferWriteReadyFlag = SDHC_IRQSTAT_BWR_MASK, /*!< Buffer write ready */ + kSDHC_BufferReadReadyFlag = SDHC_IRQSTAT_BRR_MASK, /*!< Buffer read ready */ + kSDHC_CardInsertionFlag = SDHC_IRQSTAT_CINS_MASK, /*!< Card inserted */ + kSDHC_CardRemovalFlag = SDHC_IRQSTAT_CRM_MASK, /*!< Card removed */ + kSDHC_CardInterruptFlag = SDHC_IRQSTAT_CINT_MASK, /*!< Card interrupt */ + kSDHC_CommandTimeoutFlag = SDHC_IRQSTAT_CTOE_MASK, /*!< Command timeout error */ + kSDHC_CommandCrcErrorFlag = SDHC_IRQSTAT_CCE_MASK, /*!< Command CRC error */ + kSDHC_CommandEndBitErrorFlag = SDHC_IRQSTAT_CEBE_MASK, /*!< Command end bit error */ + kSDHC_CommandIndexErrorFlag = SDHC_IRQSTAT_CIE_MASK, /*!< Command index error */ + kSDHC_DataTimeoutFlag = SDHC_IRQSTAT_DTOE_MASK, /*!< Data timeout error */ + kSDHC_DataCrcErrorFlag = SDHC_IRQSTAT_DCE_MASK, /*!< Data CRC error */ + kSDHC_DataEndBitErrorFlag = SDHC_IRQSTAT_DEBE_MASK, /*!< Data end bit error */ + kSDHC_AutoCommand12ErrorFlag = SDHC_IRQSTAT_AC12E_MASK, /*!< Auto CMD12 error */ + kSDHC_DmaErrorFlag = SDHC_IRQSTAT_DMAE_MASK, /*!< DMA error */ + + kSDHC_CommandErrorFlag = (kSDHC_CommandTimeoutFlag | kSDHC_CommandCrcErrorFlag | kSDHC_CommandEndBitErrorFlag | + kSDHC_CommandIndexErrorFlag), /*!< Command error */ + kSDHC_DataErrorFlag = (kSDHC_DataTimeoutFlag | kSDHC_DataCrcErrorFlag | kSDHC_DataEndBitErrorFlag | + kSDHC_AutoCommand12ErrorFlag), /*!< Data error */ + kSDHC_ErrorFlag = (kSDHC_CommandErrorFlag | kSDHC_DataErrorFlag | kSDHC_DmaErrorFlag), /*!< All error */ + kSDHC_DataFlag = (kSDHC_DataCompleteFlag | kSDHC_DmaCompleteFlag | kSDHC_BufferWriteReadyFlag | + kSDHC_BufferReadReadyFlag | kSDHC_DataErrorFlag | kSDHC_DmaErrorFlag), /*!< Data interrupts */ + kSDHC_CommandFlag = (kSDHC_CommandErrorFlag | kSDHC_CommandCompleteFlag), /*!< Command interrupts */ + kSDHC_CardDetectFlag = (kSDHC_CardInsertionFlag | kSDHC_CardRemovalFlag), /*!< Card detection interrupts */ + + kSDHC_AllInterruptFlags = (kSDHC_BlockGapEventFlag | kSDHC_CardInterruptFlag | kSDHC_CommandFlag | kSDHC_DataFlag | + kSDHC_ErrorFlag), /*!< All flags mask */ +}; + +/*! @brief Auto CMD12 error status flag mask */ +enum _sdhc_auto_command12_error_status_flag +{ + kSDHC_AutoCommand12NotExecutedFlag = SDHC_AC12ERR_AC12NE_MASK, /*!< Not executed error */ + kSDHC_AutoCommand12TimeoutFlag = SDHC_AC12ERR_AC12TOE_MASK, /*!< Timeout error */ + kSDHC_AutoCommand12EndBitErrorFlag = SDHC_AC12ERR_AC12EBE_MASK, /*!< End bit error */ + kSDHC_AutoCommand12CrcErrorFlag = SDHC_AC12ERR_AC12CE_MASK, /*!< CRC error */ + kSDHC_AutoCommand12IndexErrorFlag = SDHC_AC12ERR_AC12IE_MASK, /*!< Index error */ + kSDHC_AutoCommand12NotIssuedFlag = SDHC_AC12ERR_CNIBAC12E_MASK, /*!< Not issued error */ +}; + +/*! @brief ADMA error status flag mask */ +enum _sdhc_adma_error_status_flag +{ + kSDHC_AdmaLenghMismatchFlag = SDHC_ADMAES_ADMALME_MASK, /*!< Length mismatch error */ + kSDHC_AdmaDescriptorErrorFlag = SDHC_ADMAES_ADMADCE_MASK, /*!< Descriptor error */ +}; + +/*! + * @brief ADMA error state + * + * This state is the detail state when ADMA error has occurred. + */ +typedef enum _sdhc_adma_error_state +{ + kSDHC_AdmaErrorStateStopDma = 0x00U, /*!< Stop DMA */ + kSDHC_AdmaErrorStateFetchDescriptor = 0x01U, /*!< Fetch descriptor */ + kSDHC_AdmaErrorStateChangeAddress = 0x02U, /*!< Change address */ + kSDHC_AdmaErrorStateTransferData = 0x03U, /*!< Transfer data */ +} sdhc_adma_error_state_t; + +/*! @brief Force event bit position */ +enum _sdhc_force_event +{ + kSDHC_ForceEventAutoCommand12NotExecuted = SDHC_FEVT_AC12NE_MASK, /*!< Auto CMD12 not executed error */ + kSDHC_ForceEventAutoCommand12Timeout = SDHC_FEVT_AC12TOE_MASK, /*!< Auto CMD12 timeout error */ + kSDHC_ForceEventAutoCommand12CrcError = SDHC_FEVT_AC12CE_MASK, /*!< Auto CMD12 CRC error */ + kSDHC_ForceEventEndBitError = SDHC_FEVT_AC12EBE_MASK, /*!< Auto CMD12 end bit error */ + kSDHC_ForceEventAutoCommand12IndexError = SDHC_FEVT_AC12IE_MASK, /*!< Auto CMD12 index error */ + kSDHC_ForceEventAutoCommand12NotIssued = SDHC_FEVT_CNIBAC12E_MASK, /*!< Auto CMD12 not issued error */ + kSDHC_ForceEventCommandTimeout = SDHC_FEVT_CTOE_MASK, /*!< Command timeout error */ + kSDHC_ForceEventCommandCrcError = SDHC_FEVT_CCE_MASK, /*!< Command CRC error */ + kSDHC_ForceEventCommandEndBitError = SDHC_FEVT_CEBE_MASK, /*!< Command end bit error */ + kSDHC_ForceEventCommandIndexError = SDHC_FEVT_CIE_MASK, /*!< Command index error */ + kSDHC_ForceEventDataTimeout = SDHC_FEVT_DTOE_MASK, /*!< Data timeout error */ + kSDHC_ForceEventDataCrcError = SDHC_FEVT_DCE_MASK, /*!< Data CRC error */ + kSDHC_ForceEventDataEndBitError = SDHC_FEVT_DEBE_MASK, /*!< Data end bit error */ + kSDHC_ForceEventAutoCommand12Error = SDHC_FEVT_AC12E_MASK, /*!< Auto CMD12 error */ + kSDHC_ForceEventCardInt = (int)SDHC_FEVT_CINT_MASK, /*!< Card interrupt */ + kSDHC_ForceEventDmaError = SDHC_FEVT_DMAE_MASK, /*!< Dma error */ + + kSDHC_ForceEventsAll = (int)(SDHC_FEVT_AC12NE_MASK | SDHC_FEVT_AC12TOE_MASK | SDHC_FEVT_AC12CE_MASK | + SDHC_FEVT_AC12EBE_MASK | SDHC_FEVT_AC12IE_MASK | SDHC_FEVT_CNIBAC12E_MASK | + SDHC_FEVT_CTOE_MASK | SDHC_FEVT_CCE_MASK | SDHC_FEVT_CEBE_MASK | SDHC_FEVT_CIE_MASK | + SDHC_FEVT_DTOE_MASK | SDHC_FEVT_DCE_MASK | SDHC_FEVT_DEBE_MASK | SDHC_FEVT_AC12E_MASK | + SDHC_FEVT_CINT_MASK | SDHC_FEVT_DMAE_MASK), /*!< All force event flags mask */ +}; + +/*! @brief Data transfer width */ +typedef enum _sdhc_data_bus_width +{ + kSDHC_DataBusWidth1Bit = 0U, /*!< 1-bit mode */ + kSDHC_DataBusWidth4Bit = 1U, /*!< 4-bit mode */ + kSDHC_DataBusWidth8Bit = 2U, /*!< 8-bit mode */ +} sdhc_data_bus_width_t; + +/*! @brief Endian mode */ +typedef enum _sdhc_endian_mode +{ + kSDHC_EndianModeBig = 0U, /*!< Big endian mode */ + kSDHC_EndianModeHalfWordBig = 1U, /*!< Half word big endian mode */ + kSDHC_EndianModeLittle = 2U, /*!< Little endian mode */ +} sdhc_endian_mode_t; + +/*! @brief DMA mode */ +typedef enum _sdhc_dma_mode +{ + kSDHC_DmaModeNo = 0U, /*!< No DMA */ + kSDHC_DmaModeAdma1 = 1U, /*!< ADMA1 is selected */ + kSDHC_DmaModeAdma2 = 2U, /*!< ADMA2 is selected */ +} sdhc_dma_mode_t; + +/*! @brief SDIO control flag mask */ +enum _sdhc_sdio_control_flag +{ + kSDHC_StopAtBlockGapFlag = 0x01, /*!< Stop at block gap */ + kSDHC_ReadWaitControlFlag = 0x02, /*!< Read wait control */ + kSDHC_InterruptAtBlockGapFlag = 0x04, /*!< Interrupt at block gap */ + kSDHC_ExactBlockNumberReadFlag = 0x08, /*!< Exact block number read */ +}; + +/*! @brief MMC card boot mode */ +typedef enum _sdhc_boot_mode +{ + kSDHC_BootModeNormal = 0U, /*!< Normal boot */ + kSDHC_BootModeAlternative = 1U, /*!< Alternative boot */ +} sdhc_boot_mode_t; + +/*! @brief The command type */ +typedef enum _sdhc_card_command_type +{ + kCARD_CommandTypeNormal = 0U, /*!< Normal command */ + kCARD_CommandTypeSuspend = 1U, /*!< Suspend command */ + kCARD_CommandTypeResume = 2U, /*!< Resume command */ + kCARD_CommandTypeAbort = 3U, /*!< Abort command */ +} sdhc_card_command_type_t; + +/*! + * @brief The command response type. + * + * Define the command response type from card to host controller. + */ +typedef enum _sdhc_card_response_type +{ + kCARD_ResponseTypeNone = 0U, /*!< Response type: none */ + kCARD_ResponseTypeR1 = 1U, /*!< Response type: R1 */ + kCARD_ResponseTypeR1b = 2U, /*!< Response type: R1b */ + kCARD_ResponseTypeR2 = 3U, /*!< Response type: R2 */ + kCARD_ResponseTypeR3 = 4U, /*!< Response type: R3 */ + kCARD_ResponseTypeR4 = 5U, /*!< Response type: R4 */ + kCARD_ResponseTypeR5 = 6U, /*!< Response type: R5 */ + kCARD_ResponseTypeR5b = 7U, /*!< Response type: R5b */ + kCARD_ResponseTypeR6 = 8U, /*!< Response type: R6 */ + kCARD_ResponseTypeR7 = 9U, /*!< Response type: R7 */ +} sdhc_card_response_type_t; + +/*! @brief The alignment size for ADDRESS filed in ADMA1's descriptor */ +#define SDHC_ADMA1_ADDRESS_ALIGN (4096U) +/*! @brief The alignment size for LENGTH field in ADMA1's descriptor */ +#define SDHC_ADMA1_LENGTH_ALIGN (4096U) +/*! @brief The alignment size for ADDRESS field in ADMA2's descriptor */ +#define SDHC_ADMA2_ADDRESS_ALIGN (4U) +/*! @brief The alignment size for LENGTH filed in ADMA2's descriptor */ +#define SDHC_ADMA2_LENGTH_ALIGN (4U) + +/* ADMA1 descriptor table + * |------------------------|---------|--------------------------| + * | Address/page field |Reserved | Attribute | + * |------------------------|---------|--------------------------| + * |31 12|11 6|05 |04 |03|02 |01 |00 | + * |------------------------|---------|----|----|--|---|---|-----| + * | address or data length | 000000 |Act2|Act1| 0|Int|End|Valid| + * |------------------------|---------|----|----|--|---|---|-----| + * + * + * |------|------|-----------------|-------|-------------| + * | Act2 | Act1 | Comment | 31-28 | 27 - 12 | + * |------|------|-----------------|---------------------| + * | 0 | 0 | No op | Don't care | + * |------|------|-----------------|-------|-------------| + * | 0 | 1 | Set data length | 0000 | Data Length | + * |------|------|-----------------|-------|-------------| + * | 1 | 0 | Transfer data | Data address | + * |------|------|-----------------|---------------------| + * | 1 | 1 | Link descriptor | Descriptor address | + * |------|------|-----------------|---------------------| + */ +/*! @brief The bit shift for ADDRESS filed in ADMA1's descriptor */ +#define SDHC_ADMA1_DESCRIPTOR_ADDRESS_SHIFT (12U) +/*! @brief The bit mask for ADDRESS field in ADMA1's descriptor */ +#define SDHC_ADMA1_DESCRIPTOR_ADDRESS_MASK (0xFFFFFU) +/*! @brief The bit shift for LENGTH filed in ADMA1's descriptor */ +#define SDHC_ADMA1_DESCRIPTOR_LENGTH_SHIFT (12U) +/*! @brief The mask for LENGTH field in ADMA1's descriptor */ +#define SDHC_ADMA1_DESCRIPTOR_LENGTH_MASK (0xFFFFU) +/*! @brief The maximum value of LENGTH filed in ADMA1's descriptor */ +#define SDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (SDHC_ADMA1_DESCRIPTOR_LENGTH_MASK + 1U) + +/*! @brief The mask for the control/status field in ADMA1 descriptor */ +enum _sdhc_adma1_descriptor_flag +{ + kSDHC_Adma1DescriptorValidFlag = (1U << 0U), /*!< Valid flag */ + kSDHC_Adma1DescriptorEndFlag = (1U << 1U), /*!< End flag */ + kSDHC_Adma1DescriptorInterrupFlag = (1U << 2U), /*!< Interrupt flag */ + kSDHC_Adma1DescriptorActivity1Flag = (1U << 4U), /*!< Activity 1 flag */ + kSDHC_Adma1DescriptorActivity2Flag = (1U << 5U), /*!< Activity 2 flag */ + kSDHC_Adma1DescriptorTypeNop = (kSDHC_Adma1DescriptorValidFlag), /*!< No operation */ + kSDHC_Adma1DescriptorTypeTransfer = + (kSDHC_Adma1DescriptorActivity2Flag | kSDHC_Adma1DescriptorValidFlag), /*!< Transfer data */ + kSDHC_Adma1DescriptorTypeLink = (kSDHC_Adma1DescriptorActivity1Flag | kSDHC_Adma1DescriptorActivity2Flag | + kSDHC_Adma1DescriptorValidFlag), /*!< Link descriptor */ + kSDHC_Adma1DescriptorTypeSetLength = + (kSDHC_Adma1DescriptorActivity1Flag | kSDHC_Adma1DescriptorValidFlag), /*!< Set data length */ +}; + +/* ADMA2 descriptor table + * |----------------|---------------|-------------|--------------------------| + * | Address field | Length | Reserved | Attribute | + * |----------------|---------------|-------------|--------------------------| + * |63 32|31 16|15 06|05 |04 |03|02 |01 |00 | + * |----------------|---------------|-------------|----|----|--|---|---|-----| + * | 32-bit address | 16-bit length | 0000000000 |Act2|Act1| 0|Int|End|Valid| + * |----------------|---------------|-------------|----|----|--|---|---|-----| + * + * + * | Act2 | Act1 | Comment | Operation | + * |------|------|-----------------|-------------------------------------------------------------------| + * | 0 | 0 | No op | Don't care | + * |------|------|-----------------|-------------------------------------------------------------------| + * | 0 | 1 | Reserved | Read this line and go to next one | + * |------|------|-----------------|-------------------------------------------------------------------| + * | 1 | 0 | Transfer data | Transfer data with address and length set in this descriptor line | + * |------|------|-----------------|-------------------------------------------------------------------| + * | 1 | 1 | Link descriptor | Link to another descriptor | + * |------|------|-----------------|-------------------------------------------------------------------| + */ +/*! @brief The bit shift for LENGTH field in ADMA2's descriptor */ +#define SDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT (16U) +/*! @brief The bit mask for LENGTH field in ADMA2's descriptor */ +#define SDHC_ADMA2_DESCRIPTOR_LENGTH_MASK (0xFFFFU) +/*! @brief The maximum value of LENGTH field in ADMA2's descriptor */ +#define SDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (SDHC_ADMA2_DESCRIPTOR_LENGTH_MASK) + +/*! @brief ADMA1 descriptor control and status mask */ +enum _sdhc_adma2_descriptor_flag +{ + kSDHC_Adma2DescriptorValidFlag = (1U << 0U), /*!< Valid flag */ + kSDHC_Adma2DescriptorEndFlag = (1U << 1U), /*!< End flag */ + kSDHC_Adma2DescriptorInterruptFlag = (1U << 2U), /*!< Interrupt flag */ + kSDHC_Adma2DescriptorActivity1Flag = (1U << 4U), /*!< Activity 1 mask */ + kSDHC_Adma2DescriptorActivity2Flag = (1U << 5U), /*!< Activity 2 mask */ + + kSDHC_Adma2DescriptorTypeNop = (kSDHC_Adma2DescriptorValidFlag), /*!< No operation */ + kSDHC_Adma2DescriptorTypeReserved = + (kSDHC_Adma2DescriptorActivity1Flag | kSDHC_Adma2DescriptorValidFlag), /*!< Reserved */ + kSDHC_Adma2DescriptorTypeTransfer = + (kSDHC_Adma2DescriptorActivity2Flag | kSDHC_Adma2DescriptorValidFlag), /*!< Transfer type */ + kSDHC_Adma2DescriptorTypeLink = (kSDHC_Adma2DescriptorActivity1Flag | kSDHC_Adma2DescriptorActivity2Flag | + kSDHC_Adma2DescriptorValidFlag), /*!< Link type */ +}; + +/*! @brief Defines the adma1 descriptor structure. */ +typedef uint32_t sdhc_adma1_descriptor_t; + +/*! @brief Defines the ADMA2 descriptor structure. */ +typedef struct _sdhc_adma2_descriptor +{ + uint32_t attribute; /*!< The control and status field */ + const uint32_t *address; /*!< The address field */ +} sdhc_adma2_descriptor_t; + +/*! + * @brief SDHC capability information. + * + * Defines a structure to save the capability information of SDHC. + */ +typedef struct _sdhc_capability +{ + uint32_t specVersion; /*!< Specification version */ + uint32_t vendorVersion; /*!< Vendor version */ + uint32_t maxBlockLength; /*!< Maximum block length united as byte */ + uint32_t maxBlockCount; /*!< Maximum block count can be set one time */ + uint32_t flags; /*!< Capability flags to indicate the support information(_sdhc_capability_flag) */ +} sdhc_capability_t; + +/*! @brief Card transfer configuration. + * + * Define structure to configure the transfer-related command index/argument/flags and data block + * size/data block numbers. This structure needs to be filled each time a command is sent to the card. + */ +typedef struct _sdhc_transfer_config +{ + size_t dataBlockSize; /*!< Data block size */ + uint32_t dataBlockCount; /*!< Data block count */ + uint32_t commandArgument; /*!< Command argument */ + uint32_t commandIndex; /*!< Command index */ + uint32_t flags; /*!< Transfer flags(_sdhc_transfer_flag) */ +} sdhc_transfer_config_t; + +/*! @brief Data structure to configure the MMC boot feature */ +typedef struct _sdhc_boot_config +{ + uint32_t ackTimeoutCount; /*!< Timeout value for the boot ACK. The available range is 0 ~ 15. */ + sdhc_boot_mode_t bootMode; /*!< Boot mode selection. */ + uint32_t blockCount; /*!< Stop at block gap value of automatic mode. Available range is 0 ~ 65535. */ + bool enableBootAck; /*!< Enable or disable boot ACK */ + bool enableBoot; /*!< Enable or disable fast boot */ + bool enableAutoStopAtBlockGap; /*!< Enable or disable auto stop at block gap function in boot period */ +} sdhc_boot_config_t; + +/*! @brief Data structure to initialize the SDHC */ +typedef struct _sdhc_config +{ + bool cardDetectDat3; /*!< Enable DAT3 as card detection pin */ + sdhc_endian_mode_t endianMode; /*!< Endian mode */ + sdhc_dma_mode_t dmaMode; /*!< DMA mode */ + uint32_t readWatermarkLevel; /*!< Watermark level for DMA read operation. Available range is 1 ~ 128. */ + uint32_t writeWatermarkLevel; /*!< Watermark level for DMA write operation. Available range is 1 ~ 128. */ +} sdhc_config_t; + +/*! + * @brief Card data descriptor + * + * Defines a structure to contain data-related attribute. 'enableIgnoreError' is used for the case that upper card + * driver + * want to ignore the error event to read/write all the data not to stop read/write immediately when error event + * happen for example bus testing procedure for MMC card. + */ +typedef struct _sdhc_data +{ + bool enableAutoCommand12; /*!< Enable auto CMD12 */ + bool enableIgnoreError; /*!< Enable to ignore error event to read/write all the data */ + size_t blockSize; /*!< Block size */ + uint32_t blockCount; /*!< Block count */ + uint32_t *rxData; /*!< Buffer to save data read */ + const uint32_t *txData; /*!< Data buffer to write */ +} sdhc_data_t; + +/*! + * @brief Card command descriptor + * + * Define card command-related attribute. + */ +typedef struct _sdhc_command +{ + uint32_t index; /*!< Command index */ + uint32_t argument; /*!< Command argument */ + sdhc_card_command_type_t type; /*!< Command type */ + sdhc_card_response_type_t responseType; /*!< Command response type */ + uint32_t response[4U]; /*!< Response for this command */ + uint32_t responseErrorFlags; /*!< response error flag, the flag which need to check + the command reponse*/ +} sdhc_command_t; + +/*! @brief Transfer state */ +typedef struct _sdhc_transfer +{ + sdhc_data_t *data; /*!< Data to transfer */ + sdhc_command_t *command; /*!< Command to send */ +} sdhc_transfer_t; + +/*! @brief SDHC handle typedef */ +typedef struct _sdhc_handle sdhc_handle_t; + +/*! @brief SDHC callback functions. */ +typedef struct _sdhc_transfer_callback +{ + void (*CardInserted)(SDHC_Type *base, + void *userData); /*!< Card inserted occurs when DAT3/CD pin is for card detect */ + void (*CardRemoved)(SDHC_Type *base, void *userData); /*!< Card removed occurs */ + void (*SdioInterrupt)(SDHC_Type *base, void *userData); /*!< SDIO card interrupt occurs */ + void (*SdioBlockGap)(SDHC_Type *base, void *userData); /*!< SDIO card stopped at block gap occurs */ + void (*TransferComplete)(SDHC_Type *base, + sdhc_handle_t *handle, + status_t status, + void *userData); /*!< Transfer complete callback */ +} sdhc_transfer_callback_t; + +/*! + * @brief SDHC handle + * + * Defines the structure to save the SDHC state information and callback function. The detailed interrupt status when + * sending a command or transfering data can be obtained from the interruptFlags field by using the mask defined in + * sdhc_interrupt_flag_t. + * + * @note All the fields except interruptFlags and transferredWords must be allocated by the user. + */ +struct _sdhc_handle +{ + /* Transfer parameter */ + sdhc_data_t *volatile data; /*!< Data to transfer */ + sdhc_command_t *volatile command; /*!< Command to send */ + + /* Transfer status */ + volatile uint32_t interruptFlags; /*!< Interrupt flags of last transaction */ + volatile uint32_t transferredWords; /*!< Words transferred by DATAPORT way */ + + /* Callback functions */ + sdhc_transfer_callback_t callback; /*!< Callback function */ + void *userData; /*!< Parameter for transfer complete callback */ +}; + +/*! @brief SDHC transfer function. */ +typedef status_t (*sdhc_transfer_function_t)(SDHC_Type *base, sdhc_transfer_t *content); + +/*! @brief SDHC host descriptor */ +typedef struct _sdhc_host +{ + SDHC_Type *base; /*!< SDHC peripheral base address */ + uint32_t sourceClock_Hz; /*!< SDHC source clock frequency united in Hz */ + sdhc_config_t config; /*!< SDHC configuration */ + sdhc_capability_t capability; /*!< SDHC capability information */ + sdhc_transfer_function_t transfer; /*!< SDHC transfer function */ +} sdhc_host_t; + +/************************************************************************************************* + * API + ************************************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief SDHC module initialization function. + * + * Configures the SDHC according to the user configuration. + * + * Example: + @code + sdhc_config_t config; + config.cardDetectDat3 = false; + config.endianMode = kSDHC_EndianModeLittle; + config.dmaMode = kSDHC_DmaModeAdma2; + config.readWatermarkLevel = 128U; + config.writeWatermarkLevel = 128U; + SDHC_Init(SDHC, &config); + @endcode + * + * @param base SDHC peripheral base address. + * @param config SDHC configuration information. + * @retval kStatus_Success Operate successfully. + */ +void SDHC_Init(SDHC_Type *base, const sdhc_config_t *config); + +/*! + * @brief Deinitializes the SDHC. + * + * @param base SDHC peripheral base address. + */ +void SDHC_Deinit(SDHC_Type *base); + +/*! + * @brief Resets the SDHC. + * + * @param base SDHC peripheral base address. + * @param mask The reset type mask(_sdhc_reset). + * @param timeout Timeout for reset. + * @retval true Reset successfully. + * @retval false Reset failed. + */ +bool SDHC_Reset(SDHC_Type *base, uint32_t mask, uint32_t timeout); + +/* @} */ + +/*! + * @name DMA Control + * @{ + */ + +/*! + * @brief Sets the ADMA descriptor table configuration. + * + * @param base SDHC peripheral base address. + * @param dmaMode DMA mode. + * @param table ADMA table address. + * @param tableWords ADMA table buffer length united as Words. + * @param data Data buffer address. + * @param dataBytes Data length united as bytes. + * @retval kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data. + * @retval kStatus_Success Operate successfully. + */ +status_t SDHC_SetAdmaTableConfig(SDHC_Type *base, + sdhc_dma_mode_t dmaMode, + uint32_t *table, + uint32_t tableWords, + const uint32_t *data, + uint32_t dataBytes); + +/* @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables the interrupt status. + * + * @param base SDHC peripheral base address. + * @param mask Interrupt status flags mask(_sdhc_interrupt_status_flag). + */ +static inline void SDHC_EnableInterruptStatus(SDHC_Type *base, uint32_t mask) +{ + base->IRQSTATEN |= mask; +} + +/*! + * @brief Disables the interrupt status. + * + * @param base SDHC peripheral base address. + * @param mask The interrupt status flags mask(_sdhc_interrupt_status_flag). + */ +static inline void SDHC_DisableInterruptStatus(SDHC_Type *base, uint32_t mask) +{ + base->IRQSTATEN &= ~mask; +} + +/*! + * @brief Enables the interrupt signal corresponding to the interrupt status flag. + * + * @param base SDHC peripheral base address. + * @param mask The interrupt status flags mask(_sdhc_interrupt_status_flag). + */ +static inline void SDHC_EnableInterruptSignal(SDHC_Type *base, uint32_t mask) +{ + base->IRQSIGEN |= mask; +} + +/*! + * @brief Disables the interrupt signal corresponding to the interrupt status flag. + * + * @param base SDHC peripheral base address. + * @param mask The interrupt status flags mask(_sdhc_interrupt_status_flag). + */ +static inline void SDHC_DisableInterruptSignal(SDHC_Type *base, uint32_t mask) +{ + base->IRQSIGEN &= ~mask; +} + +/* @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the current interrupt status. + * + * @param base SDHC peripheral base address. + * @return Current interrupt status flags mask(_sdhc_interrupt_status_flag). + */ +static inline uint32_t SDHC_GetInterruptStatusFlags(SDHC_Type *base) +{ + return base->IRQSTAT; +} + +/*! + * @brief Clears a specified interrupt status. + * + * @param base SDHC peripheral base address. + * @param mask The interrupt status flags mask(_sdhc_interrupt_status_flag). + */ +static inline void SDHC_ClearInterruptStatusFlags(SDHC_Type *base, uint32_t mask) +{ + base->IRQSTAT = mask; +} + +/*! + * @brief Gets the status of auto command 12 error. + * + * @param base SDHC peripheral base address. + * @return Auto command 12 error status flags mask(_sdhc_auto_command12_error_status_flag). + */ +static inline uint32_t SDHC_GetAutoCommand12ErrorStatusFlags(SDHC_Type *base) +{ + return base->AC12ERR; +} + +/*! + * @brief Gets the status of the ADMA error. + * + * @param base SDHC peripheral base address. + * @return ADMA error status flags mask(_sdhc_adma_error_status_flag). + */ +static inline uint32_t SDHC_GetAdmaErrorStatusFlags(SDHC_Type *base) +{ + return base->ADMAES; +} + +/*! + * @brief Gets a present status. + * + * This function gets the present SDHC's status except for an interrupt status and an error status. + * + * @param base SDHC peripheral base address. + * @return Present SDHC's status flags mask(_sdhc_present_status_flag). + */ +static inline uint32_t SDHC_GetPresentStatusFlags(SDHC_Type *base) +{ + return base->PRSSTAT; +} + +/* @} */ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Gets the capability information. + * + * @param base SDHC peripheral base address. + * @param capability Structure to save capability information. + */ +void SDHC_GetCapability(SDHC_Type *base, sdhc_capability_t *capability); + +/*! + * @brief Enables or disables the SD bus clock. + * + * @param base SDHC peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void SDHC_EnableSdClock(SDHC_Type *base, bool enable) +{ + if (enable) + { + base->SYSCTL |= SDHC_SYSCTL_SDCLKEN_MASK; + } + else + { + base->SYSCTL &= ~SDHC_SYSCTL_SDCLKEN_MASK; + } +} + +/*! + * @brief Sets the SD bus clock frequency. + * + * @param base SDHC peripheral base address. + * @param srcClock_Hz SDHC source clock frequency united in Hz. + * @param busClock_Hz SD bus clock frequency united in Hz. + * + * @return The nearest frequency of busClock_Hz configured to SD bus. + */ +uint32_t SDHC_SetSdClock(SDHC_Type *base, uint32_t srcClock_Hz, uint32_t busClock_Hz); + +/*! + * @brief Sends 80 clocks to the card to set it to the active state. + * + * This function must be called each time the card is inserted to ensure that the card can receive the command + * correctly. + * + * @param base SDHC peripheral base address. + * @param timeout Timeout to initialize card. + * @retval true Set card active successfully. + * @retval false Set card active failed. + */ +bool SDHC_SetCardActive(SDHC_Type *base, uint32_t timeout); + +/*! + * @brief Sets the data transfer width. + * + * @param base SDHC peripheral base address. + * @param width Data transfer width. + */ +static inline void SDHC_SetDataBusWidth(SDHC_Type *base, sdhc_data_bus_width_t width) +{ + base->PROCTL = ((base->PROCTL & ~SDHC_PROCTL_DTW_MASK) | SDHC_PROCTL_DTW(width)); +} + +/*! + * @brief detect card insert status. + * + * @param base SDHC peripheral base address. + * @param enable/disable flag + */ +static inline void SDHC_CardDetectByData3(SDHC_Type *base, bool enable) +{ + if (enable) + { + base->PROCTL |= SDHC_PROCTL_D3CD_MASK; + } + else + { + base->PROCTL &= ~SDHC_PROCTL_D3CD_MASK; + } +} + +/*! + * @brief Sets the card transfer-related configuration. + * + * This function fills the card transfer-related command argument/transfer flag/data size. The command and data are sent + by + * SDHC after calling this function. + * + * Example: + @code + sdhc_transfer_config_t transferConfig; + transferConfig.dataBlockSize = 512U; + transferConfig.dataBlockCount = 2U; + transferConfig.commandArgument = 0x01AAU; + transferConfig.commandIndex = 8U; + transferConfig.flags |= (kSDHC_EnableDmaFlag | kSDHC_EnableAutoCommand12Flag | kSDHC_MultipleBlockFlag); + SDHC_SetTransferConfig(SDHC, &transferConfig); + @endcode + * + * @param base SDHC peripheral base address. + * @param config Command configuration structure. + */ +void SDHC_SetTransferConfig(SDHC_Type *base, const sdhc_transfer_config_t *config); + +/*! + * @brief Gets the command response. + * + * @param base SDHC peripheral base address. + * @param index The index of response register, range from 0 to 3. + * @return Response register transfer. + */ +static inline uint32_t SDHC_GetCommandResponse(SDHC_Type *base, uint32_t index) +{ + assert(index < 4U); + + return base->CMDRSP[index]; +} + +/*! + * @brief Fills the data port. + * + * This function is used to implement the data transfer by Data Port instead of DMA. + * + * @param base SDHC peripheral base address. + * @param data The data about to be sent. + */ +static inline void SDHC_WriteData(SDHC_Type *base, uint32_t data) +{ + base->DATPORT = data; +} + +/*! + * @brief Retrieves the data from the data port. + * + * This function is used to implement the data transfer by Data Port instead of DMA. + * + * @param base SDHC peripheral base address. + * @return The data has been read. + */ +static inline uint32_t SDHC_ReadData(SDHC_Type *base) +{ + return base->DATPORT; +} + +/*! + * @brief Enables or disables a wakeup event in low-power mode. + * + * @param base SDHC peripheral base address. + * @param mask Wakeup events mask(_sdhc_wakeup_event). + * @param enable True to enable, false to disable. + */ +static inline void SDHC_EnableWakeupEvent(SDHC_Type *base, uint32_t mask, bool enable) +{ + if (enable) + { + base->PROCTL |= mask; + } + else + { + base->PROCTL &= ~mask; + } +} + +/*! + * @brief Enables or disables the card detection level for testing. + * + * @param base SDHC peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void SDHC_EnableCardDetectTest(SDHC_Type *base, bool enable) +{ + if (enable) + { + base->PROCTL |= SDHC_PROCTL_CDSS_MASK; + } + else + { + base->PROCTL &= ~SDHC_PROCTL_CDSS_MASK; + } +} + +/*! + * @brief Sets the card detection test level. + * + * This function sets the card detection test level to indicate whether the card is inserted into the SDHC when DAT[3]/ + * CD pin is selected as a card detection pin. This function can also assert the pin logic when DAT[3]/CD pin is + * selected + * as the card detection pin. + * + * @param base SDHC peripheral base address. + * @param high True to set the card detect level to high. + */ +static inline void SDHC_SetCardDetectTestLevel(SDHC_Type *base, bool high) +{ + if (high) + { + base->PROCTL |= SDHC_PROCTL_CDTL_MASK; + } + else + { + base->PROCTL &= ~SDHC_PROCTL_CDTL_MASK; + } +} + +/*! + * @brief Enables or disables the SDIO card control. + * + * @param base SDHC peripheral base address. + * @param mask SDIO card control flags mask(_sdhc_sdio_control_flag). + * @param enable True to enable, false to disable. + */ +void SDHC_EnableSdioControl(SDHC_Type *base, uint32_t mask, bool enable); + +/*! + * @brief Restarts a transaction which has stopped at the block GAP for the SDIO card. + * + * @param base SDHC peripheral base address. + */ +static inline void SDHC_SetContinueRequest(SDHC_Type *base) +{ + base->PROCTL |= SDHC_PROCTL_CREQ_MASK; +} + +/*! + * @brief Configures the MMC boot feature. + * + * Example: + @code + sdhc_boot_config_t config; + config.ackTimeoutCount = 4; + config.bootMode = kSDHC_BootModeNormal; + config.blockCount = 5; + config.enableBootAck = true; + config.enableBoot = true; + config.enableAutoStopAtBlockGap = true; + SDHC_SetMmcBootConfig(SDHC, &config); + @endcode + * + * @param base SDHC peripheral base address. + * @param config The MMC boot configuration information. + */ +void SDHC_SetMmcBootConfig(SDHC_Type *base, const sdhc_boot_config_t *config); + +/*! + * @brief Forces generating events according to the given mask. + * + * @param base SDHC peripheral base address. + * @param mask The force events mask(_sdhc_force_event). + */ +static inline void SDHC_SetForceEvent(SDHC_Type *base, uint32_t mask) +{ + base->FEVT = mask; +} + +/* @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Transfers the command/data using a blocking method. + * + * This function waits until the command response/data is received or the SDHC encounters an error by polling the status + * flag. + * This function support non word align data addr transfer support, if data buffer addr is not align in DMA mode, + * the API will continue finish the transfer by polling IO directly + * The application must not call this API in multiple threads at the same time. Because of that this API doesn't support + * the re-entry mechanism. + * + * @note There is no need to call the API 'SDHC_TransferCreateHandle' when calling this API. + * + * @param base SDHC peripheral base address. + * @param admaTable ADMA table address, can't be null if transfer way is ADMA1/ADMA2. + * @param admaTableWords ADMA table length united as words, can't be 0 if transfer way is ADMA1/ADMA2. + * @param transfer Transfer content. + * @retval kStatus_InvalidArgument Argument is invalid. + * @retval kStatus_SDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed. + * @retval kStatus_SDHC_SendCommandFailed Send command failed. + * @retval kStatus_SDHC_TransferDataFailed Transfer data failed. + * @retval kStatus_Success Operate successfully. + */ +status_t SDHC_TransferBlocking(SDHC_Type *base, + uint32_t *admaTable, + uint32_t admaTableWords, + sdhc_transfer_t *transfer); + +/*! + * @brief Creates the SDHC handle. + * + * @param base SDHC peripheral base address. + * @param handle SDHC handle pointer. + * @param callback Structure pointer to contain all callback functions. + * @param userData Callback function parameter. + */ +void SDHC_TransferCreateHandle(SDHC_Type *base, + sdhc_handle_t *handle, + const sdhc_transfer_callback_t *callback, + void *userData); + +/*! + * @brief Transfers the command/data using an interrupt and an asynchronous method. + * + * This function sends a command and data and returns immediately. It doesn't wait the transfer complete or encounter an + * error. + * This function support non word align data addr transfer support, if data buffer addr is not align in DMA mode, + * the API will continue finish the transfer by polling IO directly + * The application must not call this API in multiple threads at the same time. Because of that this API doesn't support + * the re-entry mechanism. + * + * @note Call the API 'SDHC_TransferCreateHandle' when calling this API. + * + * @param base SDHC peripheral base address. + * @param handle SDHC handle. + * @param admaTable ADMA table address, can't be null if transfer way is ADMA1/ADMA2. + * @param admaTableWords ADMA table length united as words, can't be 0 if transfer way is ADMA1/ADMA2. + * @param transfer Transfer content. + * @retval kStatus_InvalidArgument Argument is invalid. + * @retval kStatus_SDHC_BusyTransferring Busy transferring. + * @retval kStatus_SDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed. + * @retval kStatus_Success Operate successfully. + */ +status_t SDHC_TransferNonBlocking( + SDHC_Type *base, sdhc_handle_t *handle, uint32_t *admaTable, uint32_t admaTableWords, sdhc_transfer_t *transfer); + +/*! + * @brief IRQ handler for the SDHC. + * + * This function deals with the IRQs on the given host controller. + * + * @param base SDHC peripheral base address. + * @param handle SDHC handle. + */ +void SDHC_TransferHandleIRQ(SDHC_Type *base, sdhc_handle_t *handle); + +/* @} */ + +#if defined(__cplusplus) +} +#endif +/*! @} */ + +#endif /* _FSL_SDHC_H_*/ diff --git a/drivers/fsl_wdog.c b/drivers/fsl_wdog.c new file mode 100644 index 0000000..4c15707 --- /dev/null +++ b/drivers/fsl_wdog.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_wdog.h" + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.wdog" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * brief Initializes the WDOG configuration sturcture. + * + * This function initializes the WDOG configuration structure to default values. The default + * values are as follows. + * code + * wdogConfig->enableWdog = true; + * wdogConfig->clockSource = kWDOG_LpoClockSource; + * wdogConfig->prescaler = kWDOG_ClockPrescalerDivide1; + * wdogConfig->workMode.enableWait = true; + * wdogConfig->workMode.enableStop = false; + * wdogConfig->workMode.enableDebug = false; + * wdogConfig->enableUpdate = true; + * wdogConfig->enableInterrupt = false; + * wdogConfig->enableWindowMode = false; + * wdogConfig->windowValue = 0; + * wdogConfig->timeoutValue = 0xFFFFU; + * endcode + * + * param config Pointer to the WDOG configuration structure. + * see wdog_config_t + */ +void WDOG_GetDefaultConfig(wdog_config_t *config) +{ + assert(config); + + /* Initializes the configure structure to zero. */ + memset(config, 0, sizeof(*config)); + + config->enableWdog = true; + config->clockSource = kWDOG_LpoClockSource; + config->prescaler = kWDOG_ClockPrescalerDivide1; +#if defined(FSL_FEATURE_WDOG_HAS_WAITEN) && FSL_FEATURE_WDOG_HAS_WAITEN + config->workMode.enableWait = true; +#endif /* FSL_FEATURE_WDOG_HAS_WAITEN */ + config->workMode.enableStop = false; + config->workMode.enableDebug = false; + config->enableUpdate = true; + config->enableInterrupt = false; + config->enableWindowMode = false; + config->windowValue = 0U; + config->timeoutValue = 0xFFFFU; +} + +/*! + * brief Initializes the WDOG. + * + * This function initializes the WDOG. When called, the WDOG runs according to the configuration. + * To reconfigure WDOG without forcing a reset first, enableUpdate must be set to true + * in the configuration. + * + * This is an example. + * code + * wdog_config_t config; + * WDOG_GetDefaultConfig(&config); + * config.timeoutValue = 0x7ffU; + * config.enableUpdate = true; + * WDOG_Init(wdog_base,&config); + * endcode + * + * param base WDOG peripheral base address + * param config The configuration of WDOG + */ +void WDOG_Init(WDOG_Type *base, const wdog_config_t *config) +{ + assert(config); + + uint32_t value = 0U; + uint32_t primaskValue = 0U; + + value = WDOG_STCTRLH_WDOGEN(config->enableWdog) | WDOG_STCTRLH_CLKSRC(config->clockSource) | + WDOG_STCTRLH_IRQRSTEN(config->enableInterrupt) | WDOG_STCTRLH_WINEN(config->enableWindowMode) | + WDOG_STCTRLH_ALLOWUPDATE(config->enableUpdate) | WDOG_STCTRLH_DBGEN(config->workMode.enableDebug) | + WDOG_STCTRLH_STOPEN(config->workMode.enableStop) | +#if defined(FSL_FEATURE_WDOG_HAS_WAITEN) && FSL_FEATURE_WDOG_HAS_WAITEN + WDOG_STCTRLH_WAITEN(config->workMode.enableWait) | +#endif /* FSL_FEATURE_WDOG_HAS_WAITEN */ + WDOG_STCTRLH_DISTESTWDOG(1U); + + /* Disable the global interrupts. Otherwise, an interrupt could effectively invalidate the unlock sequence + * and the WCT may expire. After the configuration finishes, re-enable the global interrupts. */ + primaskValue = DisableGlobalIRQ(); + WDOG_Unlock(base); + /* Wait one bus clock cycle */ + base->RSTCNT = 0U; + /* Set configruation */ + base->PRESC = WDOG_PRESC_PRESCVAL(config->prescaler); + base->WINH = (uint16_t)((config->windowValue >> 16U) & 0xFFFFU); + base->WINL = (uint16_t)((config->windowValue) & 0xFFFFU); + base->TOVALH = (uint16_t)((config->timeoutValue >> 16U) & 0xFFFFU); + base->TOVALL = (uint16_t)((config->timeoutValue) & 0xFFFFU); + base->STCTRLH = value; + EnableGlobalIRQ(primaskValue); +} + +/*! + * brief Shuts down the WDOG. + * + * This function shuts down the WDOG. + * Ensure that the WDOG_STCTRLH.ALLOWUPDATE is 1 which indicates that the register update is enabled. + */ +void WDOG_Deinit(WDOG_Type *base) +{ + uint32_t primaskValue = 0U; + + /* Disable the global interrupts */ + primaskValue = DisableGlobalIRQ(); + WDOG_Unlock(base); + /* Wait one bus clock cycle */ + base->RSTCNT = 0U; + WDOG_Disable(base); + EnableGlobalIRQ(primaskValue); + WDOG_ClearResetCount(base); +} + +/*! + * brief Configures the WDOG functional test. + * + * This function is used to configure the WDOG functional test. When called, the WDOG goes into test mode + * and runs according to the configuration. + * Ensure that the WDOG_STCTRLH.ALLOWUPDATE is 1 which means that the register update is enabled. + * + * This is an example. + * code + * wdog_test_config_t test_config; + * test_config.testMode = kWDOG_QuickTest; + * test_config.timeoutValue = 0xfffffu; + * WDOG_SetTestModeConfig(wdog_base, &test_config); + * endcode + * param base WDOG peripheral base address + * param config The functional test configuration of WDOG + */ +void WDOG_SetTestModeConfig(WDOG_Type *base, wdog_test_config_t *config) +{ + assert(config); + + uint32_t value = 0U; + uint32_t primaskValue = 0U; + + value = WDOG_STCTRLH_DISTESTWDOG(0U) | WDOG_STCTRLH_TESTWDOG(1U) | WDOG_STCTRLH_TESTSEL(config->testMode) | + WDOG_STCTRLH_BYTESEL(config->testedByte) | WDOG_STCTRLH_IRQRSTEN(0U) | WDOG_STCTRLH_WDOGEN(1U) | + WDOG_STCTRLH_ALLOWUPDATE(1U); + + /* Disable the global interrupts. Otherwise, an interrupt could effectively invalidate the unlock sequence + * and the WCT may expire. After the configuration finishes, re-enable the global interrupts. */ + primaskValue = DisableGlobalIRQ(); + WDOG_Unlock(base); + /* Wait one bus clock cycle */ + base->RSTCNT = 0U; + /* Set configruation */ + base->TOVALH = (uint16_t)((config->timeoutValue >> 16U) & 0xFFFFU); + base->TOVALL = (uint16_t)((config->timeoutValue) & 0xFFFFU); + base->STCTRLH = value; + EnableGlobalIRQ(primaskValue); +} + +/*! + * brief Gets the WDOG all status flags. + * + * This function gets all status flags. + * + * This is an example for getting the Running Flag. + * code + * uint32_t status; + * status = WDOG_GetStatusFlags (wdog_base) & kWDOG_RunningFlag; + * endcode + * param base WDOG peripheral base address + * return State of the status flag: asserted (true) or not-asserted (false).see _wdog_status_flags_t + * - true: a related status flag has been set. + * - false: a related status flag is not set. + */ +uint32_t WDOG_GetStatusFlags(WDOG_Type *base) +{ + uint32_t status_flag = 0U; + + status_flag |= (base->STCTRLH & WDOG_STCTRLH_WDOGEN_MASK); + status_flag |= (base->STCTRLL & WDOG_STCTRLL_INTFLG_MASK); + + return status_flag; +} + +/*! + * brief Clears the WDOG flag. + * + * This function clears the WDOG status flag. + * + * This is an example for clearing the timeout (interrupt) flag. + * code + * WDOG_ClearStatusFlags(wdog_base,kWDOG_TimeoutFlag); + * endcode + * param base WDOG peripheral base address + * param mask The status flags to clear. + * The parameter could be any combination of the following values. + * kWDOG_TimeoutFlag + */ +void WDOG_ClearStatusFlags(WDOG_Type *base, uint32_t mask) +{ + if (mask & kWDOG_TimeoutFlag) + { + base->STCTRLL |= WDOG_STCTRLL_INTFLG_MASK; + } +} + +/*! + * brief Refreshes the WDOG timer. + * + * This function feeds the WDOG. + * This function should be called before the WDOG timer is in timeout. Otherwise, a reset is asserted. + * + * param base WDOG peripheral base address + */ +void WDOG_Refresh(WDOG_Type *base) +{ + uint32_t primaskValue = 0U; + + /* Disable the global interrupt to protect refresh sequence */ + primaskValue = DisableGlobalIRQ(); + base->REFRESH = WDOG_FIRST_WORD_OF_REFRESH; + base->REFRESH = WDOG_SECOND_WORD_OF_REFRESH; + EnableGlobalIRQ(primaskValue); +} diff --git a/drivers/fsl_wdog.h b/drivers/fsl_wdog.h new file mode 100644 index 0000000..a573f75 --- /dev/null +++ b/drivers/fsl_wdog.h @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _FSL_WDOG_H_ +#define _FSL_WDOG_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup wdog + * @{ + */ + + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief Defines WDOG driver version 2.0.0. */ +#define FSL_WDOG_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/*! @name Unlock sequence */ +/*@{*/ +#define WDOG_FIRST_WORD_OF_UNLOCK (0xC520U) /*!< First word of unlock sequence */ +#define WDOG_SECOND_WORD_OF_UNLOCK (0xD928U) /*!< Second word of unlock sequence */ +/*@}*/ + +/*! @name Refresh sequence */ +/*@{*/ +#define WDOG_FIRST_WORD_OF_REFRESH (0xA602U) /*!< First word of refresh sequence */ +#define WDOG_SECOND_WORD_OF_REFRESH (0xB480U) /*!< Second word of refresh sequence */ +/*@}*/ + +/*! @brief Describes WDOG clock source. */ +typedef enum _wdog_clock_source +{ + kWDOG_LpoClockSource = 0U, /*!< WDOG clock sourced from LPO*/ + kWDOG_AlternateClockSource = 1U, /*!< WDOG clock sourced from alternate clock source*/ +} wdog_clock_source_t; + +/*! @brief Defines WDOG work mode. */ +typedef struct _wdog_work_mode +{ +#if defined(FSL_FEATURE_WDOG_HAS_WAITEN) && FSL_FEATURE_WDOG_HAS_WAITEN + bool enableWait; /*!< Enables or disables WDOG in wait mode */ +#endif /* FSL_FEATURE_WDOG_HAS_WAITEN */ + bool enableStop; /*!< Enables or disables WDOG in stop mode */ + bool enableDebug; /*!< Enables or disables WDOG in debug mode */ +} wdog_work_mode_t; + +/*! @brief Describes the selection of the clock prescaler. */ +typedef enum _wdog_clock_prescaler +{ + kWDOG_ClockPrescalerDivide1 = 0x0U, /*!< Divided by 1 */ + kWDOG_ClockPrescalerDivide2 = 0x1U, /*!< Divided by 2 */ + kWDOG_ClockPrescalerDivide3 = 0x2U, /*!< Divided by 3 */ + kWDOG_ClockPrescalerDivide4 = 0x3U, /*!< Divided by 4 */ + kWDOG_ClockPrescalerDivide5 = 0x4U, /*!< Divided by 5 */ + kWDOG_ClockPrescalerDivide6 = 0x5U, /*!< Divided by 6 */ + kWDOG_ClockPrescalerDivide7 = 0x6U, /*!< Divided by 7 */ + kWDOG_ClockPrescalerDivide8 = 0x7U, /*!< Divided by 8 */ +} wdog_clock_prescaler_t; + +/*! @brief Describes WDOG configuration structure. */ +typedef struct _wdog_config +{ + bool enableWdog; /*!< Enables or disables WDOG */ + wdog_clock_source_t clockSource; /*!< Clock source select */ + wdog_clock_prescaler_t prescaler; /*!< Clock prescaler value */ + wdog_work_mode_t workMode; /*!< Configures WDOG work mode in debug stop and wait mode */ + bool enableUpdate; /*!< Update write-once register enable */ + bool enableInterrupt; /*!< Enables or disables WDOG interrupt */ + bool enableWindowMode; /*!< Enables or disables WDOG window mode */ + uint32_t windowValue; /*!< Window value */ + uint32_t timeoutValue; /*!< Timeout value */ +} wdog_config_t; + +/*! @brief Describes WDOG test mode. */ +typedef enum _wdog_test_mode +{ + kWDOG_QuickTest = 0U, /*!< Selects quick test */ + kWDOG_ByteTest = 1U, /*!< Selects byte test */ +} wdog_test_mode_t; + +/*! @brief Describes WDOG tested byte selection in byte test mode. */ +typedef enum _wdog_tested_byte +{ + kWDOG_TestByte0 = 0U, /*!< Byte 0 selected in byte test mode */ + kWDOG_TestByte1 = 1U, /*!< Byte 1 selected in byte test mode */ + kWDOG_TestByte2 = 2U, /*!< Byte 2 selected in byte test mode */ + kWDOG_TestByte3 = 3U, /*!< Byte 3 selected in byte test mode */ +} wdog_tested_byte_t; + +/*! @brief Describes WDOG test mode configuration structure. */ +typedef struct _wdog_test_config +{ + wdog_test_mode_t testMode; /*!< Selects test mode */ + wdog_tested_byte_t testedByte; /*!< Selects tested byte in byte test mode */ + uint32_t timeoutValue; /*!< Timeout value */ +} wdog_test_config_t; + +/*! + * @brief WDOG interrupt configuration structure, default settings all disabled. + * + * This structure contains the settings for all of the WDOG interrupt configurations. + */ +enum _wdog_interrupt_enable_t +{ + kWDOG_InterruptEnable = WDOG_STCTRLH_IRQRSTEN_MASK, /*!< WDOG timeout generates an interrupt before reset*/ +}; + +/*! + * @brief WDOG status flags. + * + * This structure contains the WDOG status flags for use in the WDOG functions. + */ +enum _wdog_status_flags_t +{ + kWDOG_RunningFlag = WDOG_STCTRLH_WDOGEN_MASK, /*!< Running flag, set when WDOG is enabled*/ + kWDOG_TimeoutFlag = WDOG_STCTRLL_INTFLG_MASK, /*!< Interrupt flag, set when an exception occurs*/ +}; + +/******************************************************************************* + * API + *******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @name WDOG Initialization and De-initialization + * @{ + */ + +/*! + * @brief Initializes the WDOG configuration sturcture. + * + * This function initializes the WDOG configuration structure to default values. The default + * values are as follows. + * @code + * wdogConfig->enableWdog = true; + * wdogConfig->clockSource = kWDOG_LpoClockSource; + * wdogConfig->prescaler = kWDOG_ClockPrescalerDivide1; + * wdogConfig->workMode.enableWait = true; + * wdogConfig->workMode.enableStop = false; + * wdogConfig->workMode.enableDebug = false; + * wdogConfig->enableUpdate = true; + * wdogConfig->enableInterrupt = false; + * wdogConfig->enableWindowMode = false; + * wdogConfig->windowValue = 0; + * wdogConfig->timeoutValue = 0xFFFFU; + * @endcode + * + * @param config Pointer to the WDOG configuration structure. + * @see wdog_config_t + */ +void WDOG_GetDefaultConfig(wdog_config_t *config); + +/*! + * @brief Initializes the WDOG. + * + * This function initializes the WDOG. When called, the WDOG runs according to the configuration. + * To reconfigure WDOG without forcing a reset first, enableUpdate must be set to true + * in the configuration. + * + * This is an example. + * @code + * wdog_config_t config; + * WDOG_GetDefaultConfig(&config); + * config.timeoutValue = 0x7ffU; + * config.enableUpdate = true; + * WDOG_Init(wdog_base,&config); + * @endcode + * + * @param base WDOG peripheral base address + * @param config The configuration of WDOG + */ +void WDOG_Init(WDOG_Type *base, const wdog_config_t *config); + +/*! + * @brief Shuts down the WDOG. + * + * This function shuts down the WDOG. + * Ensure that the WDOG_STCTRLH.ALLOWUPDATE is 1 which indicates that the register update is enabled. + */ +void WDOG_Deinit(WDOG_Type *base); + +/*! + * @brief Configures the WDOG functional test. + * + * This function is used to configure the WDOG functional test. When called, the WDOG goes into test mode + * and runs according to the configuration. + * Ensure that the WDOG_STCTRLH.ALLOWUPDATE is 1 which means that the register update is enabled. + * + * This is an example. + * @code + * wdog_test_config_t test_config; + * test_config.testMode = kWDOG_QuickTest; + * test_config.timeoutValue = 0xfffffu; + * WDOG_SetTestModeConfig(wdog_base, &test_config); + * @endcode + * @param base WDOG peripheral base address + * @param config The functional test configuration of WDOG + */ +void WDOG_SetTestModeConfig(WDOG_Type *base, wdog_test_config_t *config); + +/* @} */ + +/*! + * @name WDOG Functional Operation + * @{ + */ + +/*! + * @brief Enables the WDOG module. + * + * This function write value into WDOG_STCTRLH register to enable the WDOG, it is a write-once register, + * make sure that the WCT window is still open and this register has not been written in this WCT + * while this function is called. + * + * @param base WDOG peripheral base address + */ +static inline void WDOG_Enable(WDOG_Type *base) +{ + base->STCTRLH |= WDOG_STCTRLH_WDOGEN_MASK; +} + +/*! + * @brief Disables the WDOG module. + * + * This function writes a value into the WDOG_STCTRLH register to disable the WDOG. It is a write-once register. + * Ensure that the WCT window is still open and that register has not been written to in this WCT + * while the function is called. + * + * @param base WDOG peripheral base address + */ +static inline void WDOG_Disable(WDOG_Type *base) +{ + base->STCTRLH &= ~WDOG_STCTRLH_WDOGEN_MASK; +} + +/*! + * @brief Enables the WDOG interrupt. + * + * This function writes a value into the WDOG_STCTRLH register to enable the WDOG interrupt. It is a write-once register. + * Ensure that the WCT window is still open and the register has not been written to in this WCT + * while the function is called. + * + * @param base WDOG peripheral base address + * @param mask The interrupts to enable + * The parameter can be combination of the following source if defined. + * @arg kWDOG_InterruptEnable + */ +static inline void WDOG_EnableInterrupts(WDOG_Type *base, uint32_t mask) +{ + base->STCTRLH |= mask; +} + +/*! + * @brief Disables the WDOG interrupt. + * + * This function writes a value into the WDOG_STCTRLH register to disable the WDOG interrupt. It is a write-once register. + * Ensure that the WCT window is still open and the register has not been written to in this WCT + * while the function is called. + * + * @param base WDOG peripheral base address + * @param mask The interrupts to disable + * The parameter can be combination of the following source if defined. + * @arg kWDOG_InterruptEnable + */ +static inline void WDOG_DisableInterrupts(WDOG_Type *base, uint32_t mask) +{ + base->STCTRLH &= ~mask; +} + +/*! + * @brief Gets the WDOG all status flags. + * + * This function gets all status flags. + * + * This is an example for getting the Running Flag. + * @code + * uint32_t status; + * status = WDOG_GetStatusFlags (wdog_base) & kWDOG_RunningFlag; + * @endcode + * @param base WDOG peripheral base address + * @return State of the status flag: asserted (true) or not-asserted (false).@see _wdog_status_flags_t + * - true: a related status flag has been set. + * - false: a related status flag is not set. + */ +uint32_t WDOG_GetStatusFlags(WDOG_Type *base); + +/*! + * @brief Clears the WDOG flag. + * + * This function clears the WDOG status flag. + * + * This is an example for clearing the timeout (interrupt) flag. + * @code + * WDOG_ClearStatusFlags(wdog_base,kWDOG_TimeoutFlag); + * @endcode + * @param base WDOG peripheral base address + * @param mask The status flags to clear. + * The parameter could be any combination of the following values. + * kWDOG_TimeoutFlag + */ +void WDOG_ClearStatusFlags(WDOG_Type *base, uint32_t mask); + +/*! + * @brief Sets the WDOG timeout value. + * + * This function sets the timeout value. + * It should be ensured that the time-out value for the WDOG is always greater than + * 2xWCT time + 20 bus clock cycles. + * This function writes a value into WDOG_TOVALH and WDOG_TOVALL registers which are wirte-once. + * Ensure the WCT window is still open and the two registers have not been written to in this WCT + * while the function is called. + * + * @param base WDOG peripheral base address + * @param timeoutCount WDOG timeout value; count of WDOG clock tick. + */ +static inline void WDOG_SetTimeoutValue(WDOG_Type *base, uint32_t timeoutCount) +{ + base->TOVALH = (uint16_t)((timeoutCount >> 16U) & 0xFFFFU); + base->TOVALL = (uint16_t)((timeoutCount)&0xFFFFU); +} + +/*! + * @brief Sets the WDOG window value. + * + * This function sets the WDOG window value. + * This function writes a value into WDOG_WINH and WDOG_WINL registers which are wirte-once. + * Ensure the WCT window is still open and the two registers have not been written to in this WCT + * while the function is called. + * + * @param base WDOG peripheral base address + * @param windowValue WDOG window value. + */ +static inline void WDOG_SetWindowValue(WDOG_Type *base, uint32_t windowValue) +{ + base->WINH = (uint16_t)((windowValue >> 16U) & 0xFFFFU); + base->WINL = (uint16_t)((windowValue)&0xFFFFU); +} + +/*! + * @brief Unlocks the WDOG register written. + * + * This function unlocks the WDOG register written. + * Before starting the unlock sequence and following congfiguration, disable the global interrupts. + * Otherwise, an interrupt may invalidate the unlocking sequence and the WCT may expire. + * After the configuration finishes, re-enable the global interrupts. + * + * @param base WDOG peripheral base address + */ +static inline void WDOG_Unlock(WDOG_Type *base) +{ + base->UNLOCK = WDOG_FIRST_WORD_OF_UNLOCK; + base->UNLOCK = WDOG_SECOND_WORD_OF_UNLOCK; +} + +/*! + * @brief Refreshes the WDOG timer. + * + * This function feeds the WDOG. + * This function should be called before the WDOG timer is in timeout. Otherwise, a reset is asserted. + * + * @param base WDOG peripheral base address + */ +void WDOG_Refresh(WDOG_Type *base); + +/*! + * @brief Gets the WDOG reset count. + * + * This function gets the WDOG reset count value. + * + * @param base WDOG peripheral base address + * @return WDOG reset count value. + */ +static inline uint16_t WDOG_GetResetCount(WDOG_Type *base) +{ + return base->RSTCNT; +} +/*! + * @brief Clears the WDOG reset count. + * + * This function clears the WDOG reset count value. + * + * @param base WDOG peripheral base address + */ +static inline void WDOG_ClearResetCount(WDOG_Type *base) +{ + base->RSTCNT |= UINT16_MAX; +} + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @}*/ + +#endif /* _FSL_WDOG_H_ */ diff --git a/osa/usb_osa.h b/osa/usb_osa.h new file mode 100644 index 0000000..94c1086 --- /dev/null +++ b/osa/usb_osa.h @@ -0,0 +1,576 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_OSA_H__ +#define __USB_OSA_H__ + +/*! + * @addtogroup usb_os_abstraction + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Define big endian */ +#define USB_BIG_ENDIAN (0U) +/*! @brief Define little endian */ +#define USB_LITTLE_ENDIAN (1U) + +/*! @brief Define current endian */ +#define ENDIANNESS USB_LITTLE_ENDIAN + +/*! @brief Define USB OSA event handle */ +typedef void *usb_osa_event_handle; + +/*! @brief Define USB OSA semaphore handle */ +typedef void *usb_osa_sem_handle; + +/*! @brief Define USB OSA mutex handle */ +typedef void *usb_osa_mutex_handle; + +/*! @brief Define USB OSA message queue handle */ +typedef void *usb_osa_msgq_handle; + +/*! @brief USB OSA error code */ +typedef enum _usb_osa_status +{ + kStatus_USB_OSA_Success = 0x00U, /*!< Success */ + kStatus_USB_OSA_Error, /*!< Failed */ + kStatus_USB_OSA_TimeOut, /*!< Timeout occurs while waiting */ +} usb_osa_status_t; + +/*! @brief The event flags are cleared automatically or manually.*/ +typedef enum _usb_osa_event_mode +{ + kUSB_OsaEventManualClear = 0U, /*!< The flags of the event is cleared manually. */ + kUSB_OsaEventAutoClear = 1U, /*!< The flags of the event is cleared automatically. */ +} usb_osa_event_mode_t; + +/* Include required header file based on RTOS selection */ +#if defined(USB_STACK_BM) + +#include "usb_osa_bm.h" + +#elif defined(USB_STACK_FREERTOS) + +#include "usb_osa_freertos.h" + +#elif defined(USB_STACK_UCOSII) + +#include "usb_osa_ucosii.h" + +#elif defined(USB_STACK_UCOSIII) + +#include "usb_osa_ucosiii.h" + +#else +#if defined(SDK_OS_BAREMETAL) + +#define USB_STACK_BM +#include "usb_osa_bm.h" + +#elif defined(SDK_OS_FREE_RTOS) + +#define USB_STACK_FREERTOS +#include "usb_osa_freertos.h" + +#elif defined(SDK_OS_UCOSII) + +#define USB_STACK_UCOSII +#include "usb_osa_ucosii.h" + +#elif defined(SDK_OS_UCOSIII) + +#define USB_STACK_UCOSIII +#include "usb_osa_ucosiii.h" + +#else + +#error Not define RTOS in file "usb_osa.h". +#endif +#endif + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name USB OSA Memory Management + * @{ + */ + +/*! + * @brief Reserves the requested amount of memory in bytes. + * + * The function is used to reserve the requested amount of memory in bytes and initializes it to 0. + * + * @param length Amount of bytes to reserve. + * + * @return Pointer to the reserved memory. NULL if memory can't be allocated. + */ +void *USB_OsaMemoryAllocate(uint32_t length); + +/*! + * @brief Frees the memory previously reserved. + * + * The function is used to free the memory block previously reserved. + * + * @param p Pointer to the start of the memory block previously reserved. + * + */ +extern void USB_OsaMemoryFree(void *p); + +/* @} */ + +/*! + * @name USB OSA Event + * @{ + */ + +/*! + * @brief Creates an event object with all flags cleared. + * + * This function creates an event object and sets its clear mode. If the clear mode + * is kUSB_OsaEventAutoClear, when a task gets the event flags, these flags are + * cleared automatically. If the clear mode is kUSB_OsaEventManualClear, the flags must + * be cleared manually. + * + * @param handle It is an out parameter, which is used to return the pointer of the event object. + * @param flag The event is auto-clear or manual-clear. See the enumeration #usb_osa_event_mode_t. + * + * @return A USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_event_handle eventHandle; + usb_osa_status_t usbOsaStatus; + usbOsaStatus = USB_OsaEventCreate(&eventHandle, kUSB_OsaEventManualClear); + @endcode + * + */ +extern usb_osa_status_t USB_OsaEventCreate(usb_osa_event_handle *handle, uint32_t flag); + +/*! + * @brief Destroys a created event object. + * + * @param handle Pointer to the event object. + * + * @return A USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_status_t usbOsaStatus; + ... + usbOsaStatus = USB_OsaEventDestroy(eventHandle); + @endcode + * + */ +extern usb_osa_status_t USB_OsaEventDestroy(usb_osa_event_handle handle); + +/*! + * @brief Sets an event flag. + * + * Sets specified flags for an event object. + * + * @param handle Pointer to the event object. + * @param bitMask Event flags to be set. + * + * @return A USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_status_t usbOsaStatus; + ... + usbOsaStatus = USB_OsaEventSet(eventHandle, 0x01U); + @endcode + * + */ +extern usb_osa_status_t USB_OsaEventSet(usb_osa_event_handle handle, uint32_t bitMask); + +/*! + * @brief Waits for an event flag. + * + * This function waits for a combination of flags to be set in an event object. + * An applications can wait for any/all bits to be set. This function can + * get the flags that wake up the waiting task. + * + * @param handle Pointer to the event object. + * @param bitMask Event flags to wait. + * @param flag Wait all flags or any flag to be set. 0U - wait any flag, others, wait all flags. + * @param timeout The maximum number of milliseconds to wait for the event. + * If the wait condition is not met, passing 0U + * waits indefinitely when the environment is an RTOS and returns the kStatus_OSA_Timeout + * immediately. Pass any value for the bare metal. + * @param bitSet Flags that wake up the waiting task are obtained by this parameter. + * + * @return An USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_status_t usbOsaStatus; + uint32_t bitSet; + ... + usbOsaStatus = USB_OsaEventWait(eventHandle, 0x01U, 0U, 0U, &bitSet); + @endcode + * + */ +extern usb_osa_status_t USB_OsaEventWait( + usb_osa_event_handle handle, uint32_t bitMask, uint32_t flag, uint32_t timeout, uint32_t *bitSet); + +/*! + * @brief Checks an event flag. + * + * This function checks for a combination of flags to be set in an event object. + * + * @param handle Pointer to the event object. + * @param bitMask Event flags to check. + * @param bitSet Flags have been set. + * + * @return An USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_status_t usbOsaStatus; + uint32_t bitSet; + ... + usbOsaStatus = USB_OsaEventCheck(eventHandle, 0x01U, &bitSet); + @endcode + * + */ +extern usb_osa_status_t USB_OsaEventCheck(usb_osa_event_handle handle, uint32_t bitMask, uint32_t *bitSet); + +/*! + * @brief Clears an event flag. + * + * This function clears flags of an event object. + * + * @param handle Pointer to the event object + * @param bitMask Event flags to be cleared. + * + * @return An USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_status_t usbOsaStatus; + ... + usbOsaStatus = USB_OsaEventClear(eventHandle, 0x01U); + @endcode + */ +extern usb_osa_status_t USB_OsaEventClear(usb_osa_event_handle handle, uint32_t bitMask); +/* @} */ + +/*! + * @name USB OSA Semaphore + * @{ + */ + +/*! + * @brief Creates a semaphore with a given value. + * + * This function creates a semaphore and sets the default count. + * + * @param handle It is an out parameter, which is used to return pointer of the semaphore object. + * @param count Initializes a value of the semaphore. + * + * @return An USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_sem_handle semHandle; + usb_osa_status_t usbOsaStatus; + usbOsaStatus = USB_OsaSemCreate(&semHandle, 1U); + @endcode + * + */ +extern usb_osa_status_t USB_OsaSemCreate(usb_osa_sem_handle *handle, uint32_t count); + +/*! + * @brief Destroys a semaphore object. + * + * This function destroys a semaphore object. + * + * @param handle Pointer to the semaphore. + * + * @return An USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_sem_handle semHandle; + usb_osa_status_t usbOsaStatus; + ... + usbOsaStatus = USB_OsaSemDestroy(semHandle); + @endcode + * + */ +extern usb_osa_status_t USB_OsaSemDestroy(usb_osa_sem_handle handle); + +/*! + * @brief Posts a semaphore. + * + * This function wakes up a task waiting on the semaphore. If a task is not pending, increases the semaphore's + value. + * + * @param handle Pointer to the semaphore. + * + * @return A USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_sem_handle semHandle; + usb_osa_status_t usbOsaStatus; + ... + usbOsaStatus = USB_OsaSemPost(semHandle); + @endcode + * + */ +extern usb_osa_status_t USB_OsaSemPost(usb_osa_sem_handle handle); + +/*! + * @brief Waits on a semaphore. + * + * This function checks the semaphore's value. If it is positive, it decreases the semaphore's value and return + kStatus_OSA_Success. + * + * @param handle Pointer to the semaphore. + * @param timeout The maximum number of milliseconds to wait for the semaphore. + * If the wait condition is not met, passing 0U + * waits indefinitely when environment is RTOS. And return kStatus_OSA_Timeout + * immediately for bare metal no matter what value has been passed. + * + * @return A USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_sem_handle semHandle; + usb_osa_status_t usbOsaStatus; + ... + usbOsaStatus = USB_OsaSemWait(semHandle, 0U); + @endcode + * + */ +extern usb_osa_status_t USB_OsaSemWait(usb_osa_sem_handle handle, uint32_t timeout); +/* @} */ + +/*! + * @name USB OSA Mutex + * @{ + */ + +/*! + * @brief Creates a mutex. + * + * This function creates a mutex and sets it to an unlocked status. + * + * @param handle It is out parameter, which is used to return the pointer of the mutex object. + * + * @return A USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_mutex_handle mutexHandle; + usb_osa_status_t usbOsaStatus; + usbOsaStatus = USB_OsaMutexCreate(&mutexHandle); + @endcode + * + */ +extern usb_osa_status_t USB_OsaMutexCreate(usb_osa_mutex_handle *handle); + +/*! + * @brief Destroys a mutex. + * + * This function destroys a mutex and sets it to an unlocked status. + * + * @param handle Pointer to the mutex. + * + * @return A USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_mutex_handle mutexHandle; + usb_osa_status_t usbOsaStatus; + ... + usbOsaStatus = USB_OsaMutexDestroy(mutexHandle); + @endcode + * + */ +extern usb_osa_status_t USB_OsaMutexDestroy(usb_osa_mutex_handle handle); + +/*! + * @brief Waits for a mutex and locks it. + * + * This function checks the mutex status. If it is unlocked, it locks it and returns the + * kStatus_OSA_Success. Otherwise, it waits forever to lock in RTOS and returns the + * kStatus_OSA_Success immediately for bare metal. + * + * @param handle Pointer to the mutex. + * + * @return A USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_mutex_handle mutexHandle; + usb_osa_status_t usbOsaStatus; + ... + usbOsaStatus = USB_OsaMutexLock(mutexHandle); + @endcode + * + */ +extern usb_osa_status_t USB_OsaMutexLock(usb_osa_mutex_handle handle); + +/*! + * @brief Unlocks a mutex. + * + * This function unlocks a mutex. + * + * @param handle Pointer to the mutex. + * + * @return A USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_mutex_handle mutexHandle; + usb_osa_status_t usbOsaStatus; + ... + usbOsaStatus = USB_OsaMutexUnlock(mutexHandle); + @endcode + * + */ +extern usb_osa_status_t USB_OsaMutexUnlock(usb_osa_mutex_handle handle); +/* @} */ + +/*! + * @name USB OSA Message Queue + * @{ + */ + +/*! + * @brief Creates a message queue. + * + * This function creates a message queue. + * + * @param handle It is an out parameter, which is used to return a pointer of the message queue object. + * @param count The count of elements in the queue. + * @param size Size of every elements in words. + * + * @return A USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_msgq_handle msgqHandle; + usb_osa_status_t usbOsaStatus; + usbOsaStatus = USB_OsaMsgqCreate(msgqHandle, 8U, 4U); + @endcode + * + */ +extern usb_osa_status_t USB_OsaMsgqCreate(usb_osa_msgq_handle *handle, uint32_t count, uint32_t size); + +/*! + * @brief Destroys a message queue. + * + * This function destroys a message queue. + * + * @param handle Pointer to a message queue. + * + * @return A USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_msgq_handle msgqHandle; + usb_osa_status_t usbOsaStatus; + ... + usbOsaStatus = USB_OsaMsgqDestroy(msgqHandle); + @endcode + * + */ +extern usb_osa_status_t USB_OsaMsgqDestroy(usb_osa_msgq_handle handle); + +/*! + * @brief Sends a message. + * + * This function sends a message to the tail of the message queue. + * + * @param handle Pointer to a message queue. + * @param msg The pointer to a message to be put into the queue. + * + * @return A USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_msgq_handle msgqHandle; + message_struct_t message; + usb_osa_status_t usbOsaStatus; + ... + usbOsaStatus = USB_OsaMsgqSend(msgqHandle, &message); + @endcode + * + */ +extern usb_osa_status_t USB_OsaMsgqSend(usb_osa_msgq_handle handle, void *msg); + +/*! + * @brief Receives a message. + * + * This function receives a message from the head of the message queue. + * + * @param handle Pointer to a message queue. + * @param msg The pointer to save a received message. + * @param timeout The maximum number of milliseconds to wait for a message. + * If the wait condition is not met, passing 0U + * waits indefinitely when an environment is RTOS and returns the kStatus_OSA_Timeout + * immediately for bare metal. + * + * @return A USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_msgq_handle msgqHandle; + message_struct_t message; + usb_osa_status_t usbOsaStatus; + ... + usbOsaStatus = USB_OsaMsgqRecv(msgqHandle, &message, 0U); + @endcode + * + */ +extern usb_osa_status_t USB_OsaMsgqRecv(usb_osa_msgq_handle handle, void *msg, uint32_t timeout); + +/*! + * @brief Checks a message queue and receives a message if the queue is not empty. + * + * This function checks a message queue and receives a message if the queue is not empty. + * + * @param handle Pointer to a message queue. + * @param msg The pointer to save a received message. + * + * @return A USB OSA error code or kStatus_OSA_Success. + * + * Example: + @code + usb_osa_msgq_handle msgqHandle; + message_struct_t message; + usb_osa_status_t usbOsaStatus; + ... + usbOsaStatus = USB_OsaMsgqCheck(msgqHandle, &message); + @endcode + * + */ +extern usb_osa_status_t USB_OsaMsgqCheck(usb_osa_msgq_handle handle, void *msg); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/* @} */ + +#endif /* __USB_OSA_H__ */ diff --git a/osa/usb_osa_bm.c b/osa/usb_osa_bm.c new file mode 100644 index 0000000..666d6ad --- /dev/null +++ b/osa/usb_osa_bm.c @@ -0,0 +1,522 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "stdint.h" +#include "usb.h" +#include "usb_osa.h" +#include "stdlib.h" +#include "fsl_device_registers.h" +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define USB_OSA_BM_EVENT_COUNT (4U) +#define USB_OSA_BM_SEM_COUNT (1U) +#define USB_OSA_BM_MSGQ_COUNT (1U) +#define USB_OSA_BM_MSG_COUNT (8U) +#define USB_OSA_BM_MSG_SIZE (4U) + +/* BM Event status structure */ +typedef struct _usb_osa_event_struct +{ + uint32_t value; /* Event mask */ + uint32_t flag; /* Event flags, includes auto clear flag */ + uint8_t isUsed; /* Is used */ +} usb_osa_event_struct_t; + +/* BM semaphore status structure */ +typedef struct _usb_osa_sem_struct +{ + uint32_t value; /* Semaphore count */ + uint8_t isUsed; /* Is used */ +} usb_osa_sem_struct_t; + +/* BM msg status structure */ +typedef struct _usb_osa_msg_struct +{ + uint32_t msg[USB_OSA_BM_MSG_SIZE]; /* Message entity pointer */ +} usb_osa_msg_struct_t; + +/* BM msgq status structure */ +typedef struct _usb_osa_msgq_struct +{ + usb_osa_msg_struct_t msgs[USB_OSA_BM_MSG_COUNT]; /* Message entity list */ + uint32_t count; /* Max message entity count */ + uint32_t msgSize; /* Size of each message */ + uint32_t msgCount; /* Valid messages */ + uint32_t index; /* The first empty message entity index */ + uint32_t current; /* The vaild message index */ + uint8_t isUsed; /* Is used */ +} usb_osa_msgq_struct_t; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_osa_sem_struct_t + s_UsbBmSemStruct[USB_OSA_BM_SEM_COUNT]; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_osa_event_struct_t + s_UsbBmEventStruct[USB_OSA_BM_EVENT_COUNT]; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_osa_msgq_struct_t + s_UsbBmMsgqStruct[USB_OSA_BM_MSGQ_COUNT]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +void *USB_OsaMemoryAllocate(uint32_t length) +{ + void *p = (void *)malloc(length); + uint8_t *temp = (uint8_t *)p; + if (p) + { + for (uint32_t count = 0U; count < length; count++) + { + temp[count] = 0U; + } + } + return p; +} + +void USB_OsaMemoryFree(void *p) +{ + free(p); +} + +void USB_OsaEnterCritical(uint32_t *sr) +{ + *sr = DisableGlobalIRQ(); + + + __ASM("CPSID i"); +} + +void USB_OsaExitCritical(uint32_t sr) +{ + EnableGlobalIRQ(sr); +} + +usb_osa_status_t USB_OsaEventCreate(usb_osa_event_handle *handle, uint32_t flag) +{ + usb_osa_event_struct_t *event = NULL; + USB_OSA_SR_ALLOC(); + + if (!handle) + { + return kStatus_USB_OSA_Error; + } + + USB_OSA_ENTER_CRITICAL(); + for (uint32_t i = 0; i < USB_OSA_BM_EVENT_COUNT; i++) + { + if (0 == s_UsbBmEventStruct[i].isUsed) + { + event = &s_UsbBmEventStruct[i]; + break; + } + } + + if (NULL == event) + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_Error; + } + + event->value = 0U; + event->flag = flag; + event->isUsed = 1; + *handle = event; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_Success; +} + +usb_osa_status_t USB_OsaEventDestroy(usb_osa_event_handle handle) +{ + usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle; + USB_OSA_SR_ALLOC(); + + if (handle) + { + USB_OSA_ENTER_CRITICAL(); + event->isUsed = 0; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_Success; + } + return kStatus_USB_OSA_Error; +} + +usb_osa_status_t USB_OsaEventSet(usb_osa_event_handle handle, uint32_t bitMask) +{ + usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle; + USB_OSA_SR_ALLOC(); + + if (handle) + { + USB_OSA_ENTER_CRITICAL(); + event->value |= bitMask; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_Success; + } + return kStatus_USB_OSA_Error; +} + +usb_osa_status_t USB_OsaEventWait( + usb_osa_event_handle handle, uint32_t bitMask, uint32_t flag, uint32_t timeout, uint32_t *bitSet) +{ + usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle; + uint32_t bits; + USB_OSA_SR_ALLOC(); + + if (handle) + { + USB_OSA_ENTER_CRITICAL(); + bits = event->value & bitMask; + if (flag) + { + if (bits != bitMask) + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_TimeOut; + } + } + else + { + if (!bits) + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_TimeOut; + } + } + if (bitSet) + { + *bitSet = bits; + } + if (event->flag) + { + event->value &= ~bits; + } + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_Success; + } + return kStatus_USB_OSA_Error; +} + +usb_osa_status_t USB_OsaEventCheck(usb_osa_event_handle handle, uint32_t bitMask, uint32_t *bitSet) +{ + usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle; + uint32_t bits; + USB_OSA_SR_ALLOC(); + + if (handle) + { + USB_OSA_ENTER_CRITICAL(); + bits = event->value & bitMask; + + if (!bits) + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_Error; + } + + if (bitSet) + { + *bitSet = bits; + } + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_Success; + } + return kStatus_USB_OSA_Error; +} + +usb_osa_status_t USB_OsaEventClear(usb_osa_event_handle handle, uint32_t bitMask) +{ + usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle; + uint32_t bits; + USB_OSA_SR_ALLOC(); + + if (handle) + { + USB_OSA_ENTER_CRITICAL(); + bits = event->value & bitMask; + event->value &= ~bits; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_Success; + } + return kStatus_USB_OSA_Error; +} + +usb_osa_status_t USB_OsaSemCreate(usb_osa_sem_handle *handle, uint32_t count) +{ + usb_osa_sem_struct_t *sem = NULL; + USB_OSA_SR_ALLOC(); + + if (!handle) + { + return kStatus_USB_OSA_Error; + } + + USB_OSA_ENTER_CRITICAL(); + for (uint32_t i = 0; i < USB_OSA_BM_SEM_COUNT; i++) + { + if (0 == s_UsbBmSemStruct[i].isUsed) + { + sem = &s_UsbBmSemStruct[i]; + break; + } + } + if (NULL == sem) + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_Error; + } + + sem->value = count; + sem->isUsed = 1; + *handle = sem; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_Success; +} + +usb_osa_status_t USB_OsaSemDestroy(usb_osa_sem_handle handle) +{ + usb_osa_sem_struct_t *sem = (usb_osa_sem_struct_t *)handle; + USB_OSA_SR_ALLOC(); + + if (handle) + { + USB_OSA_ENTER_CRITICAL(); + sem->isUsed = 0; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_Success; + } + return kStatus_USB_OSA_Error; +} + +usb_osa_status_t USB_OsaSemPost(usb_osa_sem_handle handle) +{ + usb_osa_sem_struct_t *sem = (usb_osa_sem_struct_t *)handle; + USB_OSA_SR_ALLOC(); + + if (!handle) + { + return kStatus_USB_OSA_Error; + } + + USB_OSA_ENTER_CRITICAL(); + sem->value++; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_Success; +} + +usb_osa_status_t USB_OsaSemWait(usb_osa_sem_handle handle, uint32_t timeout) +{ + usb_osa_sem_struct_t *sem = (usb_osa_sem_struct_t *)handle; + USB_OSA_SR_ALLOC(); + + if (!handle) + { + return kStatus_USB_OSA_Error; + } + + USB_OSA_ENTER_CRITICAL(); + if (sem->value) + { + sem->value--; + } + else + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_TimeOut; + } + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_Success; +} + +usb_osa_status_t USB_OsaMutexCreate(usb_osa_mutex_handle *handle) +{ + if (!handle) + { + return kStatus_USB_OSA_Error; + } + *handle = (usb_osa_mutex_handle)0xFFFF0000U; + return kStatus_USB_OSA_Success; +} + +usb_osa_status_t USB_OsaMutexDestroy(usb_osa_mutex_handle handle) +{ + return kStatus_USB_OSA_Success; +} +usb_osa_status_t USB_OsaMutexLock(usb_osa_mutex_handle handle) +{ + return kStatus_USB_OSA_Success; +} +usb_osa_status_t USB_OsaMutexUnlock(usb_osa_mutex_handle handle) +{ + return kStatus_USB_OSA_Success; +} + +usb_osa_status_t USB_OsaMsgqCreate(usb_osa_msgq_handle *handle, uint32_t count, uint32_t size) +{ + usb_osa_msgq_struct_t *msgq = NULL; + USB_OSA_SR_ALLOC(); + + if (!handle) + { + return kStatus_USB_OSA_Error; + } + USB_OSA_ENTER_CRITICAL(); + + for (uint32_t i = 0; i < USB_OSA_BM_MSGQ_COUNT; i++) + { + if (0 == s_UsbBmMsgqStruct[i].isUsed) + { + msgq = &s_UsbBmMsgqStruct[i]; + break; + } + } + if ((NULL == msgq) || (count > USB_OSA_BM_MSG_COUNT) || (size > USB_OSA_BM_MSG_SIZE)) + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_Error; + } + msgq->count = count; + msgq->msgSize = size; + msgq->msgCount = 0U; + msgq->index = 0U; + msgq->current = 0U; + msgq->isUsed = 1; + *handle = msgq; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_Success; +} + +usb_osa_status_t USB_OsaMsgqDestroy(usb_osa_msgq_handle handle) +{ + usb_osa_msgq_struct_t *msgq = (usb_osa_msgq_struct_t *)handle; + USB_OSA_SR_ALLOC(); + + if (!handle) + { + return kStatus_USB_OSA_Error; + } + USB_OSA_ENTER_CRITICAL(); + msgq->isUsed = 0; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_Success; +} + +usb_osa_status_t USB_OsaMsgqSend(usb_osa_msgq_handle handle, void *msg) +{ + usb_osa_msgq_struct_t *msgq = (usb_osa_msgq_struct_t *)handle; + usb_osa_msg_struct_t *msgEntity; + uint32_t *p; + uint32_t *q; + uint32_t count; + USB_OSA_SR_ALLOC(); + + if (!handle) + { + return kStatus_USB_OSA_Error; + } + USB_OSA_ENTER_CRITICAL(); + if (msgq->msgCount >= msgq->count) + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_Error; + } + + msgEntity = &msgq->msgs[msgq->index]; + p = (uint32_t *)&msgEntity->msg[0]; + q = (uint32_t *)msg; + + for (count = 0U; count < msgq->msgSize; count++) + { + p[count] = q[count]; + } + + if (0U == msgq->msgCount) + { + msgq->current = msgq->index; + } + + msgq->msgCount++; + msgq->index++; + msgq->index = msgq->index % msgq->count; + + USB_OSA_EXIT_CRITICAL(); + + return kStatus_USB_OSA_Success; +} + +usb_osa_status_t USB_OsaMsgqRecv(usb_osa_msgq_handle handle, void *msg, uint32_t timeout) +{ + usb_osa_msgq_struct_t *msgq = (usb_osa_msgq_struct_t *)handle; + usb_osa_msg_struct_t *msgEntity; + uint32_t *p; + uint32_t *q; + uint32_t count; + USB_OSA_SR_ALLOC(); + + if (!handle) + { + return kStatus_USB_OSA_Error; + } + USB_OSA_ENTER_CRITICAL(); + if (msgq->msgCount < 1U) + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_OSA_TimeOut; + } + + msgEntity = &msgq->msgs[msgq->current]; + q = (uint32_t *)&msgEntity->msg[0]; + p = (uint32_t *)msg; + + for (count = 0U; count < msgq->msgSize; count++) + { + p[count] = q[count]; + } + + msgq->msgCount--; + msgq->current++; + msgq->current = msgq->current % msgq->count; + + USB_OSA_EXIT_CRITICAL(); + + return kStatus_USB_OSA_Success; +} + +usb_osa_status_t USB_OsaMsgqCheck(usb_osa_msgq_handle handle, void *msg) +{ + usb_osa_msgq_struct_t *msgq = (usb_osa_msgq_struct_t *)handle; + uint32_t msgCount; + USB_OSA_SR_ALLOC(); + + if (!handle) + { + return kStatus_USB_OSA_Error; + } + + USB_OSA_ENTER_CRITICAL(); + msgCount = msgq->msgCount; + USB_OSA_EXIT_CRITICAL(); + + if (msgCount) + { + if (kStatus_USB_OSA_Success == USB_OsaMsgqRecv(msgq, msg, 0U)) + { + return kStatus_USB_OSA_Success; + } + } + + return kStatus_USB_OSA_Error; +} diff --git a/osa/usb_osa_bm.h b/osa/usb_osa_bm.h new file mode 100644 index 0000000..1758af2 --- /dev/null +++ b/osa/usb_osa_bm.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_OSA_BM_H__ +#define __USB_OSA_BM_H__ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define USB_OSA_SR_ALLOC() uint32_t usbOsaCurrentSr; +#define USB_OSA_ENTER_CRITICAL() USB_OsaEnterCritical(&usbOsaCurrentSr) +#define USB_OSA_EXIT_CRITICAL() USB_OsaExitCritical(usbOsaCurrentSr) + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +extern void USB_OsaEnterCritical(uint32_t *sr); +extern void USB_OsaExitCritical(uint32_t sr); + +#if defined(__cplusplus) +} +#endif + +#endif /* __USB_OSA_BM_H__ */ diff --git a/redlib/include/assert.h b/redlib/include/assert.h new file mode 100644 index 0000000..3c10aab --- /dev/null +++ b/redlib/include/assert.h @@ -0,0 +1,43 @@ +/* Copyright (C) Code Red Technologies Ltd. */ + +/* + * Copyright (C) Codemist 2007 + * + * A C Norman + * + */ +//***************************************************************************** +// +--+ +// | ++----+ +// +-++ | +// | | +// +-+--+ | +// | +--+--+ +// +----+ Portions copyright (c) 2010-11 Code Red Technologies Ltd. +// +//***************************************************************************** + +#include + +#ifndef __CODEMIST +#define __CODEMIST +#endif + +void __assertion_failed(char *_Expr) __attribute__ ((noreturn)); + +/* + * It is legal to reset NDEBUG and re-include hence the + * fact that this bit gets done every time it is included. This + * implementation follows the Rationale to the C99 standard. + */ + +#ifdef NDEBUG +# define assert(ignore) ((void)0) +#else +#define _ASSERT_STR(x) _ASSERT_VAL(x) +#define _ASSERT_VAL(x) #x +#define assert(expr) \ + ((expr) ? (void)0 : \ + __assertion_failed(__FILE__ ":" _ASSERT_STR(__LINE__) " : " #expr)) +#endif +/* end of assert.h */ diff --git a/redlib/include/ctype.h b/redlib/include/ctype.h new file mode 100644 index 0000000..7b0e0b9 --- /dev/null +++ b/redlib/include/ctype.h @@ -0,0 +1,123 @@ +/* (C) Code Red Technologies Ltd. 2007. + * Modified the macros. + * + * + * + * Copyright (C) Codemist 2007 + * + * A C Norman + */ +//***************************************************************************** +// +--+ +// | ++----+ +// +-++ | +// | | +// +-+--+ | +// | +--+--+ +// +----+ Portions copyright (c) 2010-11 Code Red Technologies Ltd. +// +//***************************************************************************** +#ifndef __CTYPE_H_INCLUDED +#define __CTYPE_H_INCLUDED + +#include + +#ifndef __CODEMIST +#define __CODEMIST +#endif + + +/* N.B. - keep in step with */ + +#define __S 1 /* whitespace */ +#define __P 2 /* punctuation */ +#define __B 4 /* blank */ +#define __L 8 /* lower case letter */ +#define __U 16 /* upper case letter */ +#define __N 32 /* (decimal) digit */ +#define __C 64 /* control chars */ +#define __X 128 /* A-F and a-f */ + +extern const unsigned char __ctype[]; + +#define isalnum(c) (__ctype[(c)+128] & (__U+__L+__N)) +#ifndef _Codemist +extern int (isalnum)(int __c); +#endif + /* non-0 iff c is alphabetic or numeric */ + +#define isalpha(c) (__ctype[(c)+128] & (__U+__L)) +#ifndef _Codemist +extern int (isalpha)(int __c); +#endif + /* non-0 iff c is alphabetic */ + +#define iscntrl(c) (__ctype[(c)+128] & __C) +#ifndef _Codemist +extern int (iscntrl)(int __c); +#endif + /* non-0 iff c is a control character - in the ASCII locale */ + /* this means (c < ' ') || (c > '~') */ + +#define isdigit(c) (__ctype[(c)+128] & __N) +#ifndef _Codemist +extern int (isdigit)(int __c); +#endif + /* non-0 iff c is a decimal digit */ + +#define isgraph(c) (__ctype[(c)+128] & (__L+__U+__N+__P)) +#ifndef _Codemist +extern int (isgraph)(int __c); +#endif + /* non-0 iff c is any printing character other than ' ' */ + +#define islower(c) (__ctype[(c)+128] & __L) +#ifndef _Codemist +extern int (islower)(int __c); +#endif + /* non-0 iff c is a lower-case letter */ + +#define isprint(c) (__ctype[(c)+128] & (__L+__U+__N+__P+__B)) +#ifndef _Codemist +extern int (isprint)(int __c); +#endif + /* non-0 iff c is a printing character - in the ASCII locale */ + /* this means 0x20 (space) -> 0x7E (tilde) */ + +#define ispunct(c) (__ctype[(c)+128] & __P) +#ifndef _Codemist +extern int (ispunct)(int __c); +#endif + /* non-0 iff c is a non-space, non-alpha-numeric, printing character */ + +#define isspace(c) (__ctype[(c)+128] & __S) +#ifndef _Codemist +extern int (isspace)(int __c); +#endif + /* non-0 iff c is a white-space char: ' ', '\f', '\n', '\r', '\t', '\v'. */ + +#define isupper(c) (__ctype[(c)+128] & __U) +#ifndef _Codemist +extern int (isupper)(int __c); +#endif + /* non-0 iff c is an upper-case letter */ + +#define isxdigit(c) (__ctype[(c)+128] & (__N+__X)) +#ifndef _Codemist +extern int (isxdigit)(int __c); +#endif + /* non-0 iff c is a digit, in 'a'..'f', or in 'A'..'F' */ + +extern int tolower(int __c); + /* if c is an upper-case letter then return the corresponding */ + /* lower-case letter, otherwise return c. */ + +extern int toupper(int __c); + /* if c is an lower-case letter then return the corresponding */ + /* upper-case letter, otherwise return c. */ + +extern int isblank(int __c); + +#endif /* __CTYPE_H_INCLUDED */ + +/* end of */ diff --git a/redlib/include/errno.h b/redlib/include/errno.h new file mode 100644 index 0000000..4592de4 --- /dev/null +++ b/redlib/include/errno.h @@ -0,0 +1,144 @@ +/* Copyright (C) Code Red Technologies Ltd. */ + +/* + * Copyright (C) Codemist 2007 + * + * A C Norman + */ +//***************************************************************************** +// +--+ +// | ++----+ +// +-++ | +// | | +// +-+--+ | +// | +--+--+ +// +----+ Portions copyright (c) 2010-11 Code Red Technologies Ltd. +// +//***************************************************************************** +#ifndef __ERRNO_H_INCLUDED +#define __ERRNO_H_INCLUDED + +#include + +#ifndef __CODEMIST +#define __CODEMIST +#endif + +#define EPERM 1 /* Not owner */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No children */ +#define EAGAIN 11 /* No more processes */ +#define ENOMEM 12 /* Not enough core */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Mount device busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory*/ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ + +/* math software */ +#define EDOM 33 /* Argument too large */ + /* + * if a domain error occurs (an input argument is outside the domain over + * which the mathematical function is defined) the integer expression errno + * acquires the value of the macro EDOM and HUGE_VAL is returned. EDOM may + * be used by non-mathematical functions. + */ +#define ERANGE 34 /* Result too large */ + /* + * a range error occurs if the result of a function can not be represented + * as a double value. If the result overflows (the magnitude of the result + * is so large that it cannot be represented in an object of the specified + * type), the function returns the value of the macro HUGE_VAL, with the + * same sign as the correct value of the function; the integer expression + * errno acquires the value of the macro ERANGE. If the result underflows + * (the magnitude of the result is so small that it cannot be represented + * in an object of the specified type), the function returns zero; the + * integer expression errno acquires the value of the macro ERANGE. ERANGE + * may be used by non-mathematical functions. + */ + +/* non-blocking and interrupt i/o */ +#define EWOULDBLOCK 35 /* Operation would block */ +#define EINPROGRESS 36 /* Operation now in progress */ +#define EALREADY 37 /* Operation already in progress */ +/* ipc/network software */ + + /* argument errors */ +#define ENOTSOCK 38 /* Socket operation on non-socket */ +#define EDESTADDRREQ 39 /* Destination address required */ +#define EMSGSIZE 40 /* Message too long */ +#define EPROTOTYPE 41 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 42 /* Protocol not available */ +#define EPROTONOSUPPORT 43 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 44 /* Socket type not supported */ +#define EOPNOTSUPP 45 /* Operation not supported on socket */ +#define EPFNOSUPPORT 46 /* Protocol family not supported */ +#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */ +#define EADDRINUSE 48 /* Address already in use */ +#define EADDRNOTAVAIL 49 /* Can't assign requested address */ + + /* operational errors */ +#define ENETDOWN 50 /* Network is down */ +#define ENETUNREACH 51 /* Network is unreachable */ +#define ENETRESET 52 /* Network dropped connection on reset */ +#define ECONNABORTED 53 /* Software caused connection abort */ +#define ECONNRESET 54 /* Connection reset by peer */ +#define ENOBUFS 55 /* No buffer space available */ +#define EISCONN 56 /* Socket is already connected */ +#define ENOTCONN 57 /* Socket is not connected */ +#define ESHUTDOWN 58 /* Can't send after socket shutdown */ +#define ETOOMANYREFS 59 /* Too many references: can't splice */ +#define ETIMEDOUT 60 /* Connection timed out */ +#define ECONNREFUSED 61 /* Connection refused */ + + /* */ +#define ELOOP 62 /* Too many levels of symbolic links */ +#define ENAMETOOLONG 63 /* File name too long */ + +/* should be rearranged */ +#define EHOSTDOWN 64 /* Host is down */ +#define EHOSTUNREACH 65 /* No route to host */ +#define ENOTEMPTY 66 /* Directory not empty */ + +/* quotas & mush */ +#define EPROCLIM 67 /* Too many processes */ +#define EUSERS 68 /* Too many users */ +#define EDQUOT 69 /* Disc quota exceeded */ + +/* Network File System */ +#define ESTALE 70 /* Stale NFS file handle */ +#define EREMOTE 71 /* Too many levels of remote in path */ + +#define ESIGNUM 99 + +#define EILSEQ 100 + +extern volatile int errno; + + +#endif /* __ERRNO_H_INCLUDED */ + +/* end of */ + diff --git a/redlib/include/float.h b/redlib/include/float.h new file mode 100644 index 0000000..ae60fcf --- /dev/null +++ b/redlib/include/float.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) Codemist 2007 + * + * A C Norman + */ +//***************************************************************************** +// +--+ +// | ++----+ +// +-++ | +// | | +// +-+--+ | +// | +--+--+ +// +----+ Portions copyright (c) 2010-11 Code Red Technologies Ltd. +// +//***************************************************************************** +#ifndef __FLOAT_H_INCLUDED +#define __FLOAT_H_INCLUDED + +#include + +#ifndef __CODEMIST +#define __CODEMIST +#endif + + +#define FLT_RADIX 2 + /* radix of exponent representation */ +#define FLT_ROUNDS 1 + /* + * The rounding mode for floating-point addition is characterised by the + * value of FLT_ROUNDS: + * -1 : indeterminable. + * 0 : towards zero. + * 1 : to nearest. + * 2 : towards positive infinity. + * 3 : towards negative infinity. + * ? : any other is implementation-defined. + */ + +#define FLT_MANT_DIG 24 + /* number of base-FLT_RADIX digits in the floating point mantissa */ + +/* The values that follow are not achieved under Acorn's FPE version 17 */ +/* but they should be correct in due course! */ + +#define FLT_DIG 6 + /* number of decimal digits of precision */ + +#define FLT_MIN_EXP (-125) + /* minimum negative integer such that FLT_RADIX raised to that power */ + /* minus 1 is a normalised floating-point number. */ + +#define FLT_MIN_10_EXP (-37) + /* minimum negative integer such that 10 raised to that power is in the */ + /* range of normalised floating-point numbers. */ + +#define FLT_MAX_EXP 128 + /* maximum integer such that FLT_RADIX raised to that power minus 1 is a */ + +#define FLT_MAX_10_EXP 38 + /* maximum integer such that 10 raised to that power is in the range of */ + /* representable finite floating-point numbers. */ + +#define FLT_MAX 3.40282347e+38F + /* maximum representable finite floating-point number. */ + +#define FLT_EPSILON 1.19209290e-7F + /* minimum positive floating point number x such that 1.0 + x != 1.0 */ + +#define FLT_MIN 1.17549435e-38F + /* minimum normalised positive floating-point number. */ + + + +#define FLT_MANT_DIG 24 +#define DBL_MANT_DIG 53 +#define LDBL_MANT_DIG 53 + /* number of base-FLT_RADIX digits in the floating point mantissa */ + +/* The values that follow are not achieved under Acorn's FPE version 17 */ +/* but they should be correct in due course! */ + +#define FLT_DIG 6 +#define DBL_DIG 15 +#define LDBL_DIG 15 + /* number of decimal digits of precision */ + +#define FLT_MIN_EXP (-125) +#define DBL_MIN_EXP (-1021) +#define LDBL_MIN_EXP (-1021) + /* minimum negative integer such that FLT_RADIX raised to that power */ + /* minus 1 is a normalised floating-point number. */ + +#define FLT_MIN_10_EXP (-37) +#define DBL_MIN_10_EXP (-307) +#define LDBL_MIN_10_EXP (-307) + /* minimum negative integer such that 10 raised to that power is in the */ + /* range of normalised floating-point numbers. */ + +#define FLT_MAX_EXP 128 +#define DBL_MAX_EXP 1024 +#define LDBL_MAX_EXP 1024 + /* maximum integer such that FLT_RADIX raised to that power minus 1 is a */ +#define FLT_MAX_10_EXP 38 +#define DBL_MAX_10_EXP 308 +#define LDBL_MAX_10_EXP 308 + /* maximum integer such that 10 raised to that power is in the range of */ + /* representable finite floating-point numbers. */ + +#define FLT_MAX 3.40282347e+38F +#define DBL_MAX 1.79769313486231571e+308 +#define LDBL_MAX 1.79769313486231571e+308L + /* maximum representable finite floating-point number. */ + +#define FLT_EPSILON 1.19209290e-7F +#define DBL_EPSILON 2.2204460492503131e-16 +#define LDBL_EPSILON 2.2204460492503131e-16L + /* minimum positive floating point number x such that 1.0 + x != 1.0 */ + +#define FLT_MIN 1.17549435e-38F +#define DBL_MIN 2.22507385850720138e-308 +#define LDBL_MIN 2.22507385850720138e-308L + /* minimum normalised positive floating-point number. */ + + + +#define DBL_MANT_DIG 53 +#define LDBL_MANT_DIG 53 + /* number of base-FLT_RADIX digits in the floating point mantissa */ + +#define DBL_DIG 15 +#define LDBL_DIG 15 + /* number of decimal digits of precision */ + +#define DBL_MIN_EXP (-1021) +#define LDBL_MIN_EXP (-1021) + /* minimum negative integer such that FLT_RADIX raised to that power */ + /* minus 1 is a normalised floating-point number. */ + +#define DBL_MIN_10_EXP (-307) +#define LDBL_MIN_10_EXP (-307) + /* minimum negative integer such that 10 raised to that power is in the */ + /* range of normalised floating-point numbers. */ + +#define DBL_MAX_EXP 1024 +#define LDBL_MAX_EXP 1024 + /* maximum integer such that FLT_RADIX raised to that power minus 1 is a */ + +#define DBL_MAX_10_EXP 308 +#define LDBL_MAX_10_EXP 308 + /* maximum integer such that 10 raised to that power is in the range of */ + /* representable finite floating-point numbers. */ + +#define DBL_MAX 1.79769313486231571e+308 +#define LDBL_MAX 1.79769313486231571e+308L + /* maximum representable finite floating-point number. */ + +#define DBL_EPSILON 2.2204460492503131e-16 +#define LDBL_EPSILON 2.2204460492503131e-16L + /* minimum positive floating point number x such that 1.0 + x != 1.0 */ + +#define DBL_MIN 2.22507385850720138e-308 +#define LDBL_MIN 2.22507385850720138e-308L + /* minimum normalised positive floating-point number. */ + + +#endif /* __FLOAT_H_INCLUDED */ + +/* end of */ diff --git a/redlib/include/limits.h b/redlib/include/limits.h new file mode 100644 index 0000000..c85a5a2 --- /dev/null +++ b/redlib/include/limits.h @@ -0,0 +1,81 @@ +/* Copyright (C) Code Red Technologies Ltd. */ + +/* + * Copyright (C) Codemist 2007 + * + * A C Norman + */ + +//***************************************************************************** +// +--+ +// | ++----+ +// +-++ | +// | | +// +-+--+ | +// | +--+--+ +// +----+ Portions copyright (c) 2010-11 Code Red Technologies Ltd. +// +//***************************************************************************** +// Portions Copyright(C) NXP Semiconductors, 2014 +//***************************************************************************** + +#ifndef __LIMITS_H_INCLUDED +#define __LIMITS_H_INCLUDED + +#include + +#ifndef __CODEMIST +#define __CODEMIST +#endif + + +#define CHAR_BIT 8 + /* max number of bits for smallest object that is not a bit-field (byte) */ +#define SCHAR_MIN (-128) + /* mimimum value for an object of type signed char */ +#define SCHAR_MAX 127 + /* maximum value for an object of type signed char */ +#define UCHAR_MAX 255 + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 + /* minimum value for an object of type char */ +#define CHAR_MAX 255 + /* maximum value for an object of type char */ +#else +#define CHAR_MIN (-128) + /* minimum value for an object of type char */ +#define CHAR_MAX 127 + /* maximum value for an object of type char */ +#endif + +/* maximum value for an object of type char */ +#define MB_LEN_MAX 1 + /* maximum number of bytes in a multibyte character, */ + /* for any supported locale */ + +#define SHRT_MIN (-0x8000) + /* minimum value for an object of type short int */ +#define SHRT_MAX 0x7fff + /* maximum value for an object of type short int */ +#define USHRT_MAX 65535U + /* maximum value for an object of type unsigned short int */ +#define INT_MIN (~0x7fffffff) /* -2147483648 and 0x80000000 are unsigned */ + /* minimum value for an object of type int */ +#define INT_MAX 0x7fffffff + /* maximum value for an object of type int */ +#define UINT_MAX 0xffffffff + /* maximum value for an object of type unsigned int */ +#define LONG_MIN (~0x7fffffff) + /* minimum value for an object of type long int */ +#define LONG_MAX 0x7fffffff + /* maximum value for an object of type long int */ +#define ULONG_MAX 0xffffffffU + /* maximum value for an object of type unsigned long int */ +#define LLONG_MIN (~0x7fffffffffffffffLL) +#define LLONG_MAX 0x7fffffffffffffffLL +#define ULLONG_MAX 0xffffffffffffffffULL + +#endif /* __LIMITS_H_INCLUDED */ + +/* end of */ diff --git a/redlib/include/locale.h b/redlib/include/locale.h new file mode 100644 index 0000000..532c86c --- /dev/null +++ b/redlib/include/locale.h @@ -0,0 +1,180 @@ +/* Copyright (C) Code Red Technologies Ltd. */ +/* + * Copyright (C) Codemist 2007 + * + * A C Norman + */ + +//***************************************************************************** +// +--+ +// | ++----+ +// +-++ | +// | | +// +-+--+ | +// | +--+--+ +// +----+ Portions copyright (c) 2010-11 Code Red Technologies Ltd. +// +//***************************************************************************** +#ifndef __LOCALE_H_INCLUDED +#define __LOCALE_H_INCLUDED + +#include + +#ifndef __CODEMIST +#define __CODEMIST +#endif + + +/* Handles national characteristics eg. USA month day year UK day month year */ + +#define LC_COLLATE 1 + /* affects the behaviour of the strcoll function */ +#define LC_CTYPE 2 + /* affects the behaviour of the character handling functions */ + /* (isdigit, isspace and isxdigit are not affected) */ +#define LC_MONETARY 4 + /* affects the monetary formatting information returned by the */ + /* localeconv function. */ +#define LC_NUMERIC 8 + /* affects the decimal-point character for the formatted input/output */ + /* functions and the string conversion functions */ +#define LC_TIME 16 + /* affects the behaviour of the strftime function */ +#define LC_ALL 31 + /* program's entire locale */ + +extern char *setlocale(int /*category*/, const char * /*locale*/); + /* + * Selects the appropriate piece of the program's locale as specified by the + * category and locale arguments. The setlocale function may be used to + * change or query the program's entire current locale or portions thereof. + * The effect of the category argument for each value is described above. + * A value of "C" for locale specifies the minimal environment for C + * translation; a value of "" for locale specifies the implementation-defined + * native environment. At program startup the equivalent of + * setlocale(LC_ALL, "C") is executed. + * + * Return value: + * If a pointer to string is given for locale and the selection can be + * honoured, the string associated with the specified category for the new + * locale is returned. If the selction can not be honoured, a null pointer + * is returned and the program's locale is not changed. + * A null pointer for locale causes the string associated with the category + * for the program's current locale to be returned and the program's locale + * is not changed. This enquiry can fail by returning a null pointer only if + * the category is LC_ALL and the most recent successful locale-setting call + * used a category other than LC_ALL. + * The string returned is such that a subsequent call with that string and + * its associated category will restore that part of the program's locale. + * The string returned shall not be modified by the program, but may be + * overwritten by a subsequent call to setlocale. + */ + +struct lconv { + char *decimal_point; + /* The decimal point character used to format non-monetary quantities */ + char *thousands_sep; + /* The character used to separate groups of digits to the left of the */ + /* decimal point character in formatted non-monetary quantities. */ + char *grouping; + /* A string whose elements indicate the size of each group of digits */ + /* in formatted non-monetary quantities. See below for more details. */ + char *int_curr_symbol; + /* The international currency symbol applicable to the current locale.*/ + /* The first three characters contain the alphabetic international */ + /* currency symbol in accordance with those specified in ISO 4217 */ + /* Codes for the representation of Currency and Funds. The fourth */ + /* character (immediately preceding the null character) is the */ + /* character used to separate the international currency symbol from */ + /* the monetary quantity. */ + char *currency_symbol; + /* The local currency symbol applicable to the current locale. */ + char *mon_decimal_point; + /* The decimal-point used to format monetary quantities. */ + char *mon_thousands_sep; + /* The separator for groups of digits to the left of the decimal-point*/ + /* in formatted monetary quantities. */ + char *mon_grouping; + /* A string whose elements indicate the size of each group of digits */ + /* in formatted monetary quantities. See below for more details. */ + char *positive_sign; + /* The string used to indicate a nonnegative-valued formatted */ + /* monetary quantity. */ + char *negative_sign; + /* The string used to indicate a negative-valued formatted monetary */ + /* quantity. */ + char int_frac_digits; + /* The number of fractional digits (those to the right of the */ + /* decimal-point) to be displayed in an internationally formatted */ + /* monetary quantities. */ + char frac_digits; + /* The number of fractional digits (those to the right of the */ + /* decimal-point) to be displayed in a formatted monetary quantity. */ + char p_cs_precedes; + /* Set to 1 or 0 if the currency_symbol respectively precedes or */ + /* succeeds the value for a nonnegative formatted monetary quantity. */ + char p_sep_by_space; + /* Set to 1 or 0 if the currency_symbol respectively is or is not */ + /* separated by a space from the value for a nonnegative formatted */ + /* monetary quantity. */ + char n_cs_precedes; + /* Set to 1 or 0 if the currency_symbol respectively precedes or */ + /* succeeds the value for a negative formatted monetary quantity. */ + char n_sep_by_space; + /* Set to 1 or 0 if the currency_symbol respectively is or is not */ + /* separated by a space from the value for a negative formatted */ + /* monetary quantity. */ + char p_sign_posn; + /* Set to a value indicating the position of the positive_sign for a */ + /* nonnegative formatted monetary quantity. See below for more details*/ + char n_sign_posn; + /* Set to a value indicating the position of the negative_sign for a */ + /* negative formatted monetary quantity. See below for more details. */ + + /* + * The elements of grouping amd mon_grouping are interpreted according to + * the following: + * CHAR_MAX No further grouping is to be performed. + * 0 The previous element is to be repeatedly used for the + * remainder of the digits. + * other The value is the number of digits that compromise the current + * group. The next element is examined to determine the size of + * the next group of digits to the left of the current group. + * + * The value of p_sign_posn and n_sign_posn is interpreted according to + * the following: + * 0 Parentheses surround the quantity and currency_symbol. + * 1 The sign string preceeds the quantity and currency_symbol. + * 2 The sign string succeeds the quantity and currency_symbol. + * 3 The sign string immediately preceeds the currency_symbol. + * 4 The sign string immediately succeeds the currency_symbol. + */ +}; + +extern struct lconv *localeconv(void); + /* + * Sets the components of an object with type struct lconv with values + * appropriate for the formatting of numeric quantities (monetary and + * otherwise) according to the rules of the current locale. + * The members of the structure with type char * are strings, any of which + * (except decimal_point) can point to "", to indicate that the value is not + * available in the current locale or is of zero length. The members with + * type char are nonnegative numbers, any of which can be CHAR_MAX to + * indicate that the value is not available in the current locale. + * The members included are described above. + * + * Return value: + * A pointer to the filled in object. The structure pointed to by the return + * value shall not be modified by the program, but may be overwritten by a + * subsequent call to the localeconv function. In addition, calls to the + * setlocale function with categories LC_ALL, LC_MONETARY, or LC_NUMERIC may + * overwrite the contents of the structure. + */ + +#ifndef NULL +# define NULL 0 +#endif + +#endif /* __LOCALE_H_INCLUDED */ + +/* end of locale.h */ diff --git a/redlib/include/math.h b/redlib/include/math.h new file mode 100644 index 0000000..c95c575 --- /dev/null +++ b/redlib/include/math.h @@ -0,0 +1,220 @@ +//******************************************************************* +// Copyright (C) Codemist 2007 +// +// Portions Copyright (C) Code Red Technologies Ltd., 2008-13 +// Portions Copyright (C) NXP Semiconductors, 2013-14 +//******************************************************************* + +#ifndef __MATH_H_INCLUDED +#define __MATH_H_INCLUDED + +#include + +#ifndef __CODEMIST +#define __CODEMIST +#endif + +typedef double float_t; +typedef double double_t; + +#ifndef HUGE_VAL +# define HUGE_VAL __huge_val +extern const double HUGE_VAL; +#endif + +#ifndef HUGE_VALF +# define HUGE_VALF __huge_valf +extern const double HUGE_VALF; +#endif + +#ifndef HUGE_VALL +# define HUGE_VALL __huge_vall +extern const double HUGE_VALL; +#endif + +#ifndef INFINITY +# define INFINITY __huge_val +extern const double INFINITY; +#endif + +#ifndef NAN +# define NAN __huge_val +extern const double NAN; +#endif + + +#undef FP_FAST_FMA +#undef FP_FAST_FMAF +#undef FP_FAST_FMAL + +#define FP_ILOGB0 INT_MIN +#define FP_ILOGBNAN INT_MIN + +#define MATH_ERRNO 1 +#define MATH_ERREXCEPT 2 +#define math_errhandling MATH_ERRNO + +/* #pragma STDC FP_CONTRACT on-off-switch */ + + +#define FP_INFINITE 4 +#define FP_NAN 3 +#define FP_NORMAL 2 +#define FP_SUBNORMAL 1 +#define FP_ZERO 0 + +extern int __fpclassifyf(float), __fpclassify(double), __fpclassifyl(long double); +extern int __isfinitef(float), __isfinite(double), __isfinitel(long double); +extern int __isinff(float), __isinf(double), __isinfl(long double); +extern int __isnanf(float), __isnan(double), __isnanl(long double); +extern int __isnormalf(float), __isnormal(double), __isnormall(long double); +extern int __signbitf(float), __signbit(double), __signbitl(long double); + +#define fpclassify(x) \ + ((sizeof (x) == sizeof (float)) ? __fpclassifyf(x) : \ + (sizeof (x) == sizeof (double)) ? __fpclassifyd(x) : \ + __fpclassifyl(x)) +#define isfinite(x) \ + ((sizeof (x) == sizeof (float)) ? __isfinitef(x) : \ + (sizeof (x) == sizeof (double)) ? __isfinited(x) : \ + __isfinitel(x)) +#define isinf(x) \ + ((sizeof (x) == sizeof (float)) ? __isinff(x) : \ + (sizeof (x) == sizeof (double)) ? __isinfd(x) : \ + __isinfl(x)) +#define isnan(x) \ + ((sizeof (x) == sizeof (float)) ? __isnanf(x) : \ + (sizeof (x) == sizeof (double)) ? __isnand(x) : \ + __isnanl(x)) +#define isnormal(x) \ + ((sizeof (x) == sizeof (float)) ? __isnormalf(x) : \ + (sizeof (x) == sizeof (double)) ? __isnormald(x) : \ + __isnormall(x)) +#define signbit(x) \ + ((sizeof (x) == sizeof (float)) ? __signbitf(x) : \ + (sizeof (x) == sizeof (double)) ? __signbitd(x) : \ + __signbitl(x)) + +// ================================================================== + +// Trigonometric functions +// ======================= + +// cos - Compute cosine +extern double cos(double __x); +extern float cosf(float __x); + +// sin - Compute sine +extern double sin(double __x); +extern float sinf(float __x); + +// tan - Compute tangent +extern double tan(double __x); +extern float tanf(float __x); + +// acos - Compute arc cosine +extern double acos(double __x); +extern float acosf(float __x); + +// asin - Compute arc sine +extern double asin(double __x); +extern float asinf(float __x); + +// atan - Compute arc tangent +extern double atan(double __x); +extern float atanf(float __x); + +// atan2 - Compute arc tangent with two parameters +extern double atan2(double __y, double __x); +extern float atan2f(float __y, float __x); + +// Hyperbolic functions +// ==================== + +// cosh - Compute hyperbolic cosine +extern double cosh(double __x); +extern float coshf(float __x); + +// sinh - Compute hyperbolic sine +extern double sinh(double __x); +extern float sinhf(float __x); + +// tanh - Compute hyperbolic tangent +extern double tanh(double __x); +extern float tanhf(float __x); + +// Exponential and logarithmic functions +// ===================================== + +// exp - Compute exponential function +extern double exp(double __x); +extern float expf(float __x); + +// frexp - Get significand and exponent +extern double frexp(double __value, int *__exp); +extern float frexpf(float __value, int *__exp); + +// ldexp - Generate number from significand and exponent +extern double ldexp(double __x, int __exp); +extern float ldexpf(float __x, int __exp); + +// log - Compute natural logarithm +extern double log(double __x); +extern float logf(float __x); + +// log10 - Compute common logarithm +extern double log10(double __x); +extern float log10f(float __x); + +// modf - Break into fractional and integral parts +extern double modf(double __value, double *iptr); +extern float modff(float __value, float *iptr); + +// Power functions +// =============== + +// pow - Raise to power +extern double pow(double __x, double __y); +extern float powf(float __x, float __y); + +// sqrt - Compute square root +extern double sqrt(double __x); +extern float sqrtf(float __x); + +// Rounding, absolute value and remainder functions +// ================================================ + +// ceil - Round up value +extern double ceil(double __x); +extern float ceilf(float __x); + +// fabs - Compute absolute value +extern double fabs(double __x); +extern float fabsf(float __x); + +// floor - Round down value +extern double floor(double __x); +extern float floorf(float __x); + +// fmod - Compute remainder of division +extern double fmod(double __x, double __y); +extern float fmodf(float __x, float __y); + +/* + * These are probably only sensibly dealt with my expanding them into + * intrinsics. The versions here are NOT GOOD. The requirement is that + * these apply to float, double or long double and do comparisons in a + * way that can never raise an exception even in the face of NaNs. The + * built-in operators (x > __y) etc may raise exceptions when faced with + * values that can not be compared. + */ +#define isgreater(x, y) ((x) > (y)) +#define isgreaterequal(x, y) ((x) >= (y)) +#define isless(x, y) ((x) < (y)) +#define islessequal(x, y) ((x) <= (y)) +#define islessgreater(x, y) ((x) != (y)) +#define isunordered(x, y) (0) + +#endif /* __MATH_H_INCLUDED */ + +/* end of */ diff --git a/redlib/include/setjmp.h b/redlib/include/setjmp.h new file mode 100644 index 0000000..9caddd6 --- /dev/null +++ b/redlib/include/setjmp.h @@ -0,0 +1,68 @@ +/* Copyright (C) Code Red Technologies Ltd. */ + +/* + * Copyright (C) Codemist 2007 + * + * A C Norman + */ + +//***************************************************************************** +// +--+ +// | ++----+ +// +-++ | +// | | +// +-+--+ | +// | +--+--+ +// +----+ Portions copyright (c) 2010-11 Code Red Technologies Ltd. +// +//***************************************************************************** + +#ifndef __SETJMP_H_INCLUDED +#define __SETJMP_H_INCLUDED + +#include + +#ifndef __CODEMIST +#define __CODEMIST +#endif + +#include + +typedef int jmp_buf[__JMP_BUF_SIZE]; + /* an array type suitable for holding the data + * needed to restore a calling environment. + */ + +extern int setjmp(jmp_buf /*env*/); + /* Saves its calling environment in its jmp_buf argument, for later use + * by the longjmp function. + * Returns: If the return is from a direct invocation, the setjmp function + * returns the value zero. If the return from a call to the + * longjmp function, the setjmp function returns a non zero value. + */ + +extern void longjmp(jmp_buf /*env*/, int /*val*/); + /* Restores the environment saved by the most recent call to setjmp in the + * same invocation of the program, with the corresponding jmp_buf argument. + * If there has been no such call, or if the function containing the call + * to setjmp has terminated execution (eg. with a return statement) in the + * interim, the behaviour is undefined. + * All accessible objects have values as of the time longjmp was called, + * except that the values of objects of automatic storage duration that do + * not have volatile type and have been changed between the setjmp and + * longjmp calls are indeterminate. + * As it bypasses the usual function call and return mechanism, the longjmp + * function shall execute correctly in contexts of interrupts, signals and + * any of their associated functions. However, if the longjmp function is + * invoked from a nested signal handler (that is, from a function invoked + * as a result of a signal raised during the handling of another signal), + * the behaviour is undefined. + * Returns: After longjmp is completed, program execution continues as if + * the corresponding call to setjmp had just returned the value + * specified by val. The longjmp function cannot cause setjmp to + * return the value 0; if val is 0, setjmp returns the value 1. + */ + +#endif /* __SETJMP_H_INCLUDED */ + +/* end of */ diff --git a/redlib/include/signal.h b/redlib/include/signal.h new file mode 100644 index 0000000..969d023 --- /dev/null +++ b/redlib/include/signal.h @@ -0,0 +1,94 @@ +/* Copyright (C) Code Red Technologies Ltd. */ + +/* + * Copyright (C) Codemist 2007 + * + * A C Norman + */ + +//***************************************************************************** +// +--+ +// | ++----+ +// +-++ | +// | | +// +-+--+ | +// | +--+--+ +// +----+ Portions copyright (c) 2010-11 Code Red Technologies Ltd. +// +//***************************************************************************** + +#ifndef __SIGNAL_H_INCLUDED +#define __SIGNAL_H_INCLUDED + +#include + +#ifndef __CODEMIST +#define __CODEMIST +#endif + +typedef unsigned char sig_atomic_t; + + /* + * Each of the following macros expand to distinct constant expressions that + * have the same type as the second argument to and the return value of the + * signal function, and whose value matches no declarable function. + */ +#define SIG_DFL (void (*)(int))0 +#define SIG_ERR (void (*)(int))(-1) +#define SIG_IGN (void (*)(int))1 + + /* + * Each of the following macros expand to a positive integral constant + * expression that is the signal number corresponding the the specified + * condition. + */ +#define NSIG 32 + +/* + * The signal numbers listed here need reviewing against the particular + * system that the library is running on top of... + */ + +#define SIGHUP 1 /* hangup */ +#define SIGINT 2 /* interrupt */ +#define SIGQUIT 3 /* quit */ +#define SIGILL 4 /* illegal instruction (not reset when caught) */ +#define SIGTRAP 5 /* trace trap (not reset when caught) */ +#define SIGABRT 6 +#define SIGIOT 6 /* IOT instruction */ +#define SIGEMT 7 /* EMT instruction */ +#define SIGFPE 8 /* floating point exception */ +#define FPE_INTDIV_TRAP (0x208>>3) /* Integer division by zero */ +#define FPE_FLTOVF_TRAP (0x1a0>>3) /* Floating overflow trap */ +#define FPE_FLTUND_TRAP (0x188>>3) /* Floating underflow trap */ +#define FPE_FLTDIV_TRAP (0x190>>3) /* Floating division by zero */ +#define FPE_FLTIOP_TRAP (0x1c0>>3) /* Floating invalid operand */ +#define FPE_FLTINX_TRAP (0x180>>3) /* Floating inexact result */ +#define SIGKILL 9 /* kill (cannot be caught or ignored) */ +#define SIGBUS 10 /* bus error */ +#define SIGSEGV 11 /* segmentation violation */ +#define SIGSYS 12 /* bad argument to system call */ +#define SIGPIPE 13 /* write on a pipe with no one to read it */ +#define SIGALRM 14 /* alarm clock */ +#define SIGTERM 15 /* software termination signal from kill */ +#define SIGURG 16 /* urgent condition on IO channel */ +#define SIGSTOP 17 /* sendable stop signal not from tty */ +#define SIGTSTP 18 /* stop signal from tty */ +#define SIGCONT 19 /* continue a stopped process */ +#define SIGCHLD 20 /* to parent on child stop or exit */ +#define SIGTTIN 21 /* to readers pgrp upon background tty read */ +#define SIGTTOU 22 /* like TTIN for output if (tp->t_local<OSTOP) */ +#define SIGIO 23 /* input/output possible signal */ +#define SIGXCPU 24 /* exceeded CPU time limit */ +#define SIGXFSZ 25 /* exceeded file size limit */ +#define SIGVTALRM 26 /* virtual time alarm */ +#define SIGPROF 27 /* profiling time alarm */ +#define SIGWINCH 28 /* window changed */ + + +extern void (*signal(int sig, void (*func)(int)))(int); +extern int raise(int sig); + +#endif /* __SIGNAL_H_INCLUDED */ + +/* end of */ diff --git a/redlib/include/stdarg.h b/redlib/include/stdarg.h new file mode 100644 index 0000000..abe9738 --- /dev/null +++ b/redlib/include/stdarg.h @@ -0,0 +1,30 @@ +/* (C) Code Red Technologies Ltd. 2008 + * + * Use the standard GCC variable argument builtins. + * + * + * + */ + +//***************************************************************************** +// +--+ +// | ++----+ +// +-++ | +// | | +// +-+--+ | +// | +--+--+ +// +----+ Portions copyright (c) 2010-11 Code Red Technologies Ltd. +// +//***************************************************************************** + +#ifndef _STDARG_H +#define _STDARG_H +#endif + +#include + +typedef __builtin_va_list va_list; + +#define va_start(v,l) __builtin_va_start((v),l) +#define va_end(v) __builtin_va_end(v) +#define va_arg(v,l)__builtin_va_arg((v),l) diff --git a/redlib/include/stdbool.h b/redlib/include/stdbool.h new file mode 100644 index 0000000..d779830 --- /dev/null +++ b/redlib/include/stdbool.h @@ -0,0 +1,26 @@ +//******************************************************************* +// +--+ +// | ++----+ +// +-++ | +// | | +// +-+--+ | +// | +--+--+ +// +----+ Copyright (c) 2011 Code Red Technologies Ltd. +// +// stdbool.h +// +//******************************************************************* + +#ifndef STDBOOL_H_ +#define STDBOOL_H_ + +#ifndef __cplusplus +//#define bool _bool +typedef unsigned char bool; +#define false 0 +#define true 1 +#endif /* ifndef __cplusplus */ + +#define __bool_true_false_are_defined 1 + +#endif /* STDBOOL_H_ */ diff --git a/redlib/include/stddef.h b/redlib/include/stddef.h new file mode 100644 index 0000000..1a80fad --- /dev/null +++ b/redlib/include/stddef.h @@ -0,0 +1,35 @@ +//******************************************************************* +// Copyright (C) Codemist 2007 +// +// Portions Copyright (c) Code Red Technologies Ltd., 2008-13 +// Portions Copyright(C) NXP Semiconductors, 2013-14 +//******************************************************************* + +#ifndef __STDDEF_H_INCLUDED +#define __STDDEF_H_INCLUDED + +#include + +#ifndef __CODEMIST +#define __CODEMIST +#endif + +#include + +typedef int ptrdiff_t; + +#ifndef WCHAR_T_DEFINED +#define WCHAR_T_DEFINED +typedef __WCHAR_TYPE__ wchar_t; +#endif + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#define offsetof(type, member_designator) \ + ((size_t)((char *)&(((type *)0)->member_designator) - (char *)0)) + +#endif /* __STDDEF_H_INCLUDED */ + +/* end of */ diff --git a/redlib/include/stdint.h b/redlib/include/stdint.h new file mode 100644 index 0000000..1cd65c7 --- /dev/null +++ b/redlib/include/stdint.h @@ -0,0 +1,320 @@ +//******************************************************************* +// Copyright (C) Codemist 2007 +// +// A C Norman +// +// Portions Copyright (c) Code Red Technologies Ltd., 2008-13 +// Portions Copyright(C) NXP Semiconductors, 2013-17 +//******************************************************************* + +#ifndef __STDINT_H_INCLUDED +#define __STDINT_H_INCLUDED + +#include + +#ifndef __CODEMIST +#define __CODEMIST +#endif + +#include + + +/* + * I will permit __SIZEOF_LONG_LONG not to exist if the"long long" + * type is not available on this system. + */ + + +typedef signed char int8_t; +typedef unsigned char uint8_t; +#define INT8_C(value) ((signed char)(value)) +#define UINT8_C(value) ((unsigned char)(value)) +typedef signed char int_least8_t; +typedef unsigned char uint_least8_t; +#define INT8_MIN (-0x80) +#define INT8_MAX 0x7f +#define UINT8_MAX 0xffU +#define INT_LEAST8_MIN (-0x80) +#define INT_LEAST8_MAX 0x7f +#define UINT_LEAST8_MAX 0xffU + +typedef int int_fast8_t; +typedef unsigned int uint_fast8_t; + + +#define INT_FAST8_MIN (-0x80000000) +#define INT_FAST8_MAX 0x7fffffff +#define UINT_FAST8_MAX 0xffffffffU + + + +#define __PRIdFAST8 "d" +#define __PRIiFAST8 "i" +#define __PRIoFAST8 "o" +#define __PRIuFAST8 "u" +#define __PRIxFAST8 "x" +#define __PRIXFAST8 "X" +#define __SCNdFAST8 "d" +#define __SCNiFAST8 "i" +#define __SCNoFAST8 "o" +#define __SCNuFAST8 "u" +#define __SCNxFAST8 "x" + + + +#define __PRId8 "hhd" +#define __PRIdLEAST8 "hhd" +#define __PRIi8 "hhi" +#define __PRIiLEAST8 "hhi" +#define __PRIo8 "hho" +#define __PRIoLEAST8 "hho" +#define __PRIu8 "hhu" +#define __PRIuLEAST8 "hhu" +#define __PRIx8 "hhx" +#define __PRIxLEAST8 "hhx" +#define __PRIX8 "hhX" +#define __PRIXLEAST8 "hhX" +#define __SCNd8 "hhd" +#define __SCNdLEAST8 "hhd" +#define __SCNi8 "hhi" +#define __SCNiLEAST8 "hhi" +#define __SCNo8 "hho" +#define __SCNoLEAST8 "hho" +#define __SCNu8 "hhu" +#define __SCNuLEAST8 "hhu" +#define __SCNx8 "hhx" +#define __SCNxLEAST8 "hhx" + + +typedef short int16_t; +typedef unsigned short uint16_t; +#define INT16_C(value) ((short)(value)) +#define UINT16_C(value) ((unsigned short)(value)) +typedef short int_least16_t; +typedef unsigned short uint_least16_t; +#define INT16_MIN (-0x8000) +#define INT16_MAX 0x7fff +#define UINT16_MAX 0xffffU +#define INT_LEAST16_MIN (-0x8000) +#define INT_LEAST16_MAX 0x7fff +#define UINT_LEAST16_MAX 0xffffU + +typedef int int_fast16_t; +typedef unsigned int uint_fast16_t; + +#define INT_FAST16_MIN (-0x80000000) +#define INT_FAST16_MAX 0x7fffffff +#define UINT_FAST16_MAX 0xffffffffU + +#define __PRIdFAST16 "d" +#define __PRIiFAST16 "i" +#define __PRIoFAST16 "o" +#define __PRIuFAST16 "o" +#define __PRIxFAST16 "x" +#define __PRIXFAST16 "X" +#define __SCNdFAST16 "d" +#define __SCNiFAST16 "i" +#define __SCNoFAST16 "o" +#define __SCNuFAST16 "u" +#define __SCNxFAST16 "x" + + +#define __PRId16 "hd" +#define __PRIdLEAST16 "hd" +#define __PRIi16 "hi" +#define __PRIiLEAST16 "hi" +#define __PRIo16 "ho" +#define __PRIoLEAST16 "ho" +#define __PRIu16 "hu" +#define __PRIuLEAST16 "hu" +#define __PRIx16 "hx" +#define __PRIxLEAST16 "hx" +#define __PRIX16 "hX" +#define __PRIXLEAST16 "hX" +#define __SCNd16 "hd" +#define __SCNdLEAST16 "hd" +#define __SCNi16 "hi" +#define __SCNiLEAST16 "hi" +#define __SCNo16 "ho" +#define __SCNoLEAST16 "ho" +#define __SCNu16 "hu" +#define __SCNuLEAST16 "hu" +#define __SCNx16 "hx" +#define __SCNxLEAST16 "hx" + +typedef int int32_t; +typedef unsigned int uint32_t; +#define INT32_C(value) ((int)(value)) +#define UINT32_C(value) ((unsigned int)(value)) +typedef int int_least32_t; +typedef unsigned int uint_least32_t; +typedef int int_fast32_t; +typedef unsigned int uint_fast32_t; +#define INT32_MIN (-0x80000000) +#define INT32_MAX 0x7fffffff +#define UINT32_MAX 0xffffffffU +#define INT_LEAST32_MIN (-0x80000000) +#define INT_LEAST32_MAX 0x7fffffff +#define UINT_LEAST32_MAX 0xffffffffU +#define INT_FAST32_MIN (-0x80000000) +#define INT_FAST32_MAX 0x7fffffff +#define UINT_FAST32_MAX 0xffffffffU +#define __PRId32 "d" +#define __PRIdLEAST32 "d" +#define __PRIdFAST32 "d" +#define __PRIi32 "i" +#define __PRIiLEAST32 "i" +#define __PRIiFAST32 "i" +#define __PRIo32 "o" +#define __PRIoLEAST32 "o" +#define __PRIoFAST32 "o" +#define __PRIu32 "u" +#define __PRIuLEAST32 "u" +#define __PRIuFAST32 "u" +#define __PRIx32 "x" +#define __PRIxLEAST32 "x" +#define __PRIxFAST32 "x" +#define __PRIX32 "X" +#define __PRIXLEAST32 "X" +#define __PRIXFAST32 "X" +#define __SCNd32 "d" +#define __SCNdLEAST32 "d" +#define __SCNdFAST32 "d" +#define __SCNi32 "i" +#define __SCNiLEAST32 "i" +#define __SCNiFAST32 "i" +#define __SCNo32 "o" +#define __SCNoLEAST32 "o" +#define __SCNoFAST32 "o" +#define __SCNu32 "u" +#define __SCNuLEAST32 "u" +#define __SCNuFAST32 "u" +#define __SCNx32 "x" +#define __SCNxLEAST32 "x" +#define __SCNxFAST32 "x" + + +typedef long long int64_t; +typedef unsigned long long uint64_t; +#define INT64_C(value) ((long long)(value)) +#define UINT64_C(value) ((unsigned long long)(value)) +typedef long long int_least64_t; +typedef unsigned long long uint_least64_t; +typedef long long int_fast64_t; +typedef unsigned long long uint_fast64_t; +#define INT64_MIN (-0x8000000000000000LL) +#define INT64_MAX 0x7fffffffffffffffLL +#define UINT64_MAX 0xffffffffffffffffULL +#define INT_LEAST64_MIN (-0x8000000000000000LL) +#define INT_LEAST64_MAX 0x7fffffffffffffffLL +#define UINT_LEAST64_MAX 0xffffffffffffffffULL +#define INT_FAST64_MIN (-0x8000000000000000LL) +#define INT_FAST64_MAX 0x7fffffffffffffffLL +#define UINT_FAST64_MAX 0xffffffffffffffffULL +#define __PRId64 "lld" +#define __PRIdLEAST64 "lld" +#define __PRIdFAST64 "lld" +#define __PRIi64 "lli" +#define __PRIiLEAST64 "lli" +#define __PRIiFAST64 "lli" +#define __PRIo64 "llo" +#define __PRIoLEAST64 "llo" +#define __PRIoFAST64 "llo" +#define __PRIu64 "llu" +#define __PRIuLEAST64 "llu" +#define __PRIuFAST64 "llu" +#define __PRIx64 "llx" +#define __PRIxLEAST64 "llx" +#define __PRIxFAST64 "llx" +#define __PRIX64 "llX" +#define __PRIXLEAST64 "llX" +#define __PRIXFAST64 "llX" +#define __SCNd64 "lld" +#define __SCNdLEAST64 "lld" +#define __SCNdFAST64 "lld" +#define __SCNi64 "lli" +#define __SCNiLEAST64 "lli" +#define __SCNiFAST64 "lli" +#define __SCNo64 "llo" +#define __SCNoLEAST64 "llo" +#define __SCNoFAST64 "llo" +#define __SCNu64 "llu" +#define __SCNuLEAST64 "llu" +#define __SCNuFAST64 "llu" +#define __SCNx64 "llx" +#define __SCNxLEAST64 "llx" +#define __SCNxFAST64 "llx" + +/* + * I see which of "int", "long" or "long long" is the same width as + * a pointer and use the first that I find. + */ + +typedef int intptr_t; +typedef unsigned int uintptr_t; + +#define INTPTR_MIN (-0x80000000) +#define INTPTR_MAX 0x7fffffff +#define UINTPTR_MAX 0xffffffffU + +#define __PRIdPTR "d" +#define __PRIiPTR "i" +#define __PRIoPTR "o" +#define __PRIuPTR "u" +#define __PRIxPTR "x" +#define __PRIXPTR "X" +#define __SCNdPTR "d" +#define __SCNiPTR "i" +#define __SCNoPTR "o" +#define __SCNuPTR "u" +#define __SCNxPTR "x" + +/* + * I only use "long long" for intmax_t if it is strictly wider than + * "long". I only use "long" if it is strictly wider than "int". + */ + +typedef long long intmax_t; +typedef unsigned long long uintmax_t; +#define __SIZEOF_INTMAX __SIZEOF_LONG_LONG + +#define INTMAX_MIN (-0x8000000000000000LL) +#define INTMAX_MAX 0x7fffffffffffffffLL +#define UINTMAX_MAX 0xffffffffffffffffULL + +#define INTMAX_C(value) ((long long)(value)) +#define UINTMAX_C(value) ((unsigned long long)(value)) +#define __PRIdMAX "lld" +#define __PRIiMAX "lli" +#define __PRIoMAX "llo" +#define __PRIuMAX "llu" +#define __PRIxMAX "llx" +#define __PRIXMAX "llX" +#define __SCNdMAX "lld" +#define __SCNiMAX "lli" +#define __SCNoMAX "llo" +#define __SCNuMAX "llu" +#define __SCNxMAX "llx" + +#define __SIZEOF_PTRDIFF 4 +#define PTRDIFF_MIN (-0x80000000) +#define PTRDIFF_MAX 0x7fffffff + +#define __SIZEOF_SIZE 4 +#define SIZE_MAX 0xffffffffU + + +#define WCHAR_MIN __WCHAR_MIN__ +#define WCHAR_MAX __WCHAR_MAX__ + +#define WINT_MIN INT32_MIN +#define WINT_MAX INT32_MAX + +#define SIG_ATOMIC_MIN 0 +#define SIG_ATOMIC_MAX 0xff + +#endif /* __STDINT_H_INCLUDED */ + +/* end of */ + + diff --git a/redlib/include/stdio.h b/redlib/include/stdio.h new file mode 100644 index 0000000..e771875 --- /dev/null +++ b/redlib/include/stdio.h @@ -0,0 +1,235 @@ +//******************************************************************* +// Copyright (C) Codemist 2007 +// +// Portions Copyright (C) Code Red Technologies Ltd., 2008-13 +// Portions Copyright (C) NXP Semiconductors, 2013-18 +//******************************************************************* + +#ifndef __STDIO_H_INCLUDED +#define __STDIO_H_INCLUDED + +#include + +#ifndef __CODEMIST +#define __CODEMIST +#endif + +#include + + +/* ANSI forbids va_list to be defined here */ +//typedef char *__va_list; /* keep in step with */ +#ifdef __GNUC__ +typedef __builtin_va_list ___gnuc_va_list; +typedef ___gnuc_va_list __va_list; +#else +typedef struct __va_list __va_list; +#endif + +/* I have put the FILE structure in libconfig.h */ + +typedef struct __FILE_struct FILE; + +typedef struct __ftpos_t_struct +{ + unsigned long __lo; +/* + * Anybody needing to support files larger than 4G would need to adjust + * this, eg inserting an extra "__hi" field or using a "long long" + * offset. + */ +} fpos_t; + +#ifndef NULL +#define NULL ((void *)0) +#endif + + + +#define __IOEOF 0x40 /* end-of-file reached */ +#define __IOERR 0x80 /* error occurred on stream */ + +#define _IOFBF 0x100 /* fully buffered IO */ +#define _IOLBF 0x200 /* line buffered IO */ +#define _IONBF 0x400 /* unbuffered IO */ + +#define BUFSIZ (256) /* system buffer size (as used by setbuf) */ +#define EOF (-1) + /* + * negative integral constant, indicates end-of-file, that is, no more + * input from a stream. + */ +/* It is not clear to me what value FOPEN_MAX should have, so I will + err in the cautious direction - ANSI requires it to be at least 8 */ +#define FOPEN_MAX 8 /* check re arthur/unix/mvs */ + /* + * an integral constant expression that is the minimum number of files that + * this implementation guarantees can be open simultaneously. + */ + +#define FILENAME_MAX 256 + /* + * an integral constant expression that is the size of an array of char + * large enough to hold the longest filename string. On modern systems + * the value 256 may not be large enough, but I feel that anybody using a + * file-name longer than that may be pushing their luck. + */ +#define L_tmpnam 32 + /* + * an integral constant expression that is the size of an array of char + * large enough to hold a temporary file name string generated by the + * tmpnam function. + */ + +#define SEEK_SET 0 /* start of stream (see fseek) */ +#define SEEK_CUR 1 /* current position in stream (see fseek) */ +#define SEEK_END 2 /* end of stream (see fseek) */ + +#define TMP_MAX 1000000000 + /* + * an integral constant expression that is the minimum number of unique + * file names that shall be generated by the tmpnam function. + */ + + +#define _SYS_OPEN 8 + /* + * Limit on number of files that can be opened at once + */ + +/* + * What happens here is that each thread gets their own "stdin", "stdout" + * and "stderr". And no thread should ever attempt to use a file opened by + * a different thread. + */ +extern __THREAD FILE __Ciob[]; + /* an array of file objects for use by the system. */ + +#define stdin (&__Ciob[0]) + /* pointer to a FILE object associated with standard input stream */ +#define stdout (&__Ciob[1]) + /* pointer to a FILE object associated with standard output stream */ +#define stderr (&__Ciob[2]) + /* pointer to a FILE object associated with standard error stream */ + +extern int remove(const char *filename); +extern int rename(const char *old, const char *new); +extern FILE *tmpfile(void); +extern char *tmpnam(char *s); +extern int fclose(FILE *stream); +extern int fflush(FILE *stream); +extern FILE *fopen(const char * restrict filename, + const char * restrict mode); +extern FILE *freopen(const char * restrict filename, + const char * restrict mode, + FILE * restrict stream); +extern void setbuf(FILE * restrict stream, + char * restrict buf); +extern int setvbuf(FILE * restrict stream, + char * restrict buf, + int mode, size_t size); +extern int fprintf(FILE * restrict stream, + const char * restrict format, ...); +extern int fscanf(FILE * restrict stream, + const char * restrict format, ...); +extern int printf(const char * restrict format, ...); +extern int scanf(const char * restrict format, ...); +extern int snprintf(char * restrict s, size_t n, + const char * restrict format, ...); +extern int sprintf(char * restrict s, + const char * restrict format, ...); +extern int sscanf(const char * restrict s, + const char * restrict format, ...); +extern int vfprintf(FILE * restrict stream, + const char * restrict format, __va_list arg); +extern int vfscanf(FILE * restrict stream, + const char * restrict format, __va_list arg); +extern int vprintf(const char * restrict format, __va_list arg); + +extern int vsnprintf(char * restrict s, size_t n, + const char * restrict format, __va_list arg); +extern int vsprintf(char * restrict s, + const char * restrict format, __va_list arg); +extern int fgetc(FILE *stream); +extern char *fgets(char * restrict s, int n, + FILE * restrict stream); +extern int fputc(int c, FILE *stream); +extern int fputs(const char * restrict s, + FILE * restrict stream); +extern int __filbuf(FILE *); +extern int getc(FILE *stream); +#define getc(p) \ + (--((p)->__icnt) >= 0 ? *((p)->__ptr)++ : __filbuf(p)) +extern int getchar(void); +#define getchar() getc(stdin) +extern char *gets(char *s); +extern int putc(int c, FILE *stream); +extern int __flsbuf(int /*c*/, FILE * /*stream*/); + /* + * SYSTEM USE ONLY, called by putc to flush buffer and or sort out flags. + * Returns: character put into buffer or EOF on error. + */ +#define putc(ch, p) \ + (--((p)->__ocnt) >= 0 ? (*((p)->__ptr)++ = (ch)) : __flsbuf(ch,p)) +extern int putchar(int c); +#define putchar(ch) putc(ch, stdout) +extern int puts(const char *s); +extern int ungetc(int c, FILE *stream); +extern size_t fread(void * restrict ptr, + size_t size, size_t nmemb, + FILE * restrict stream); +extern size_t fwrite(const void * restrict ptr, + size_t size, size_t nmemb, + FILE * restrict stream); +extern int fgetpos(FILE * restrict stream, + fpos_t * restrict pos); +extern int fseek(FILE *stream, long int offset, int whence); +extern int fsetpos(FILE *stream, const fpos_t *pos); +extern long int ftell(FILE *stream); +extern void rewind(FILE *stream); +extern void clearerr(FILE *stream); +extern int feof(FILE *stream); +#define feof(stream) ((stream)->__flag & __IOEOF) +extern int ferror(FILE *stream); +#define ferror(stream) ((stream)->__flag & __IOERR) +extern void perror(const char *s); + +/* CR: Here are the integer printf entry points */ +extern int _fprintf(FILE *fp, const char *fmt, ...); +extern int _printf(const char *fmt, ...); +extern int _sprintf(char *buff, const char *fmt, ...); +extern int _vprintf(const char * restrict format, __va_list arg); +extern int _vfprintf(FILE *p, const char *fmt, __va_list args); +extern int _vsprintf(char *buff, const char *fmt, __va_list args); +extern int _snprintf(char *buff, size_t limit, const char *fmt, ...); +extern int _vsnprintf(char *buff, size_t limit, const char *fmt, __va_list args); + +/* CR: Here are the character-by-character printf entry points */ +extern int _printf_char(const char *fmt, ...); +extern int printf_char(const char *fmt, ...); + +extern int puts_char(const char *s); + +#if defined (CR_INTEGER_PRINTF) +#define fprintf _fprintf +#define sprintf _sprintf +#define vfprintf _vfprintf +#define vsprintf _vsprintf +#define vprintf _vprintf +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#if defined (CR_PRINTF_CHAR) +#define printf _printf_char +#define puts puts_char +#else +#define printf _printf +#endif +#elif defined (CR_PRINTF_CHAR) +#define printf printf_char +#define puts puts_char + +#endif + +#endif /* __STDIO_H_INCLUDED */ + +/* end of */ diff --git a/redlib/include/stdlib.h b/redlib/include/stdlib.h new file mode 100644 index 0000000..dfe53bd --- /dev/null +++ b/redlib/include/stdlib.h @@ -0,0 +1,106 @@ +//******************************************************************* +// Copyright (C) Codemist 2007 +// +// Portions Copyright (c) Code Red Technologies Ltd., 2008-13 +// Portions Copyright(C) NXP Semiconductors, 2013-14 +//******************************************************************* + +#ifndef __STDLIB_H_INCLUDED +#define __STDLIB_H_INCLUDED + +#include + +#ifndef __CODEMIST +#define __CODEMIST +#endif + +#include + + +#ifndef WCHAR_T_DEFINED +#define WCHAR_T_DEFINED +typedef __WCHAR_TYPE__ wchar_t; +#endif + +#ifndef NULL +#define NULL ((void *)0) +#endif + +typedef struct div_t { int quot, rem; } div_t; + /* type of the value returned by the div function. */ +typedef struct ldiv_t { long int quot, rem; } ldiv_t; + /* type of the value returned by the ldiv function. */ +typedef struct lldiv_t { long long int quot, rem; } lldiv_t; + /* type of the value returned by the lldiv function. */ + +#define EXIT_FAILURE __EXIT_FAILURE +#define EXIT_SUCCESS __EXIT_SUCCESS + +#define RAND_MAX 0x7fffffff + /* + * an integral constant expression, the value of which is the maximum value + * returned by the rand function. + */ +#define MB_CUR_MAX 1 + /* + * a positive integer expression whose value is the maximum number of bytes + * in a multibyte character for the extended character set specified by the + * current locale (category LC_CTYPE), and whose value is never greater + * than MB_LEN_MAX. + */ +extern double atof(const char *nptr); +extern int atoi(const char *nptr); +extern long int atol(const char *nptr); + +extern double strtod(const char * restrict nptr, + char ** restrict endptr); +extern float strtof(const char * restrict nptr, + char ** restrict endptr); + +extern long int strtol(const char * restrict nptr, + char ** restrict endptr, int base); + +extern unsigned long int strtoul(const char * restrict nptr, + char ** restrict endptr, int base); + +extern int rand(void); +extern void srand(unsigned int seed); +extern void *calloc(size_t nmemb, size_t size); +extern void free(void *ptr); +extern void *malloc(size_t size); +extern void *realloc(void *ptr, size_t size); +extern void abort(void); +extern int atexit(void (*func)(void)); +extern void exit(int status); + +extern char *getenv(const char *name); +extern int system(const char *string); +extern void *bsearch(const void *key, const void *base, + size_t nmemb, size_t size, + int (*compar)(const void *, const void *)); +extern void qsort(void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *)); +extern int abs(int j); +extern long int labs(long int j); + +extern div_t div(int numer, int denom); +extern ldiv_t ldiv(long int numer, long int denom); + +extern int mblen(const char *s, size_t n); +extern int mbtowc(wchar_t * restrict pwc, + const char * restrict s, size_t n); +extern int wctomb(char *s, wchar_t wchar); +extern size_t mbstowcs(wchar_t * restrict pwcs, + const char * restrict s, size_t n); +extern size_t wcstombs(char * restrict s, + const wchar_t * restrict pwcs, size_t n); + +// Implementation of the non-standard 'itoa' and 'uitoa' functions, +// which support bases between 2 and 16 (2=binary, 10=decimal, +// 16=hexadecimal). +extern char * uitoa(unsigned int value, char *vstring, unsigned int base); +extern char * itoa(int value, char *vstring, unsigned int base); + +#endif /* __STDLIB_H_INCLUDED */ + +/* end of */ diff --git a/redlib/include/string.h b/redlib/include/string.h new file mode 100644 index 0000000..653048a --- /dev/null +++ b/redlib/include/string.h @@ -0,0 +1,71 @@ +//******************************************************************* +// Copyright (C) Codemist 2007 +// +// A C Norman +// +// Portions Copyright (c) Code Red Technologies Ltd., 2008-13 +// Portions Copyright (c) NXP Semiconductors, 2013-14 +//******************************************************************* +#ifndef __STRING_H_INCLUDED +#define __STRING_H_INCLUDED + +#include + +#ifndef __CODEMIST +#define __CODEMIST +#endif + +#include + +#ifndef __SIZE_T_DEFINED +#define __SIZE_T_DEFINED +#if __SIZEOF_INT < __SIZEOF_VOID_P +typedef unsigned long size_t; +#else +typedef unsigned int size_t; +#endif +#endif + +#ifndef NULL +#define NULL 0 +#endif + +extern void *memcpy(void * restrict __s1, + const void * restrict __s2, size_t __n); +extern void *memmove(void *__s1, const void *__s2, size_t __n); +extern char *strcpy(char * restrict __s1, + const char * restrict __s2); +extern char *strncpy(char * restrict __s1, + const char * restrict __s2, size_t __n); +extern char *strcat(char * restrict __s1, + const char * restrict __s2); +extern char *strncat(char * restrict __s1, + const char * restrict __s2, size_t __n); +extern int memcmp(const void *__s1, const void *__s2, size_t __n); +extern int strcmp(const char *__s1, const char *__s2); +extern int strcoll(const char *__s1, const char *__s2); +extern int strncmp(const char *__s1, const char *__s2, size_t __n); + size_t strxfrm(char * restrict __s1, + const char * restrict __s2, size_t ____n); +extern void *memchr(const void *__s, int __c, size_t ____n); +extern char *strchr(const char *__s, int __c); +extern size_t strcspn(const char *__s1, const char *__s2); +extern char *strpbrk(const char *__s1, const char *__s2); +extern char *strrchr(const char *s, int c); +extern size_t strspn(const char *__s1, const char *__s2); +extern char *strstr(const char *__s1, const char *__s2); +extern char *strtok(char * restrict __s1, + const char * restrict __s2); +extern void *memset(void *__s, int __c, size_t __n); +extern char *strerror(int __errnum); +extern size_t strlen(const char *__s); + +// ****************************************************** +// Non-standard case-insensitive string compare functions +// ****************************************************** +extern int strncasecmp(char const *s1, char const *s2, size_t n) ; +extern int strcasecmp(const char * s1, const char * s2); + +#endif /* __STRING_H_INCLUDED */ + +/* end of */ diff --git a/redlib/include/sys/libconfig-arm.h b/redlib/include/sys/libconfig-arm.h new file mode 100644 index 0000000..56aaabf --- /dev/null +++ b/redlib/include/sys/libconfig-arm.h @@ -0,0 +1,349 @@ +//******************************************************************* +// Copyright (C) Codemist 2007 +// +// A C Norman +// +// This file is modelled on "config.h" as used with the GNU autoconf +// tools, but is expected to be configured manually here. +// If one of the types shown is not present then just leave the +// corresponding symbol undefined. +// +// This varient is set up for x86 data sizes. +// +// Portions Copyright (c) Code Red Technologies Ltd., 2008-13 +// Portions Copyright (c) NXP Semiconductors, 2013-17 +//******************************************************************* + +#ifndef __SYS_LIBCONFIG_H_INCLUDED +#define __SYS_LIBCONFIG_H_INCLUDED + +/* code_red + * + * Allow use with non C99 builds. + */ + +#define restrict __restrict__ +/* + * This is some basic infrastructure for a study in making the + * library thread-safe. Decorating a data defintion with __THREAD is + * intended to cause the storage to be allocated on a per-thread basis. + * + * gcc supports a decoration "__thread" but does not implement it on all + * platforms, and in particular it is not available on Cygwin which is + * where my initial tetsing of this code has been done, so for now I + * will #define __TREAD to empty... + */ +#ifdef THREAD_LOCAL_STORE_AVAILABLE +#define __THREAD __thread +#else +#define __THREAD +#endif + +/* + * Critical regions are delimited by these two, which at present are defined + * as noops. The "do {} while (0)" construct does nothing but is such that + * a semicolon after it is called for... + */ +#define __START_CRITICAL_REGION() do {} while (0) +#define __END_CRITICAL_REGION() do {} while (0) + +/* The size of `char', as computed by sizeof. */ +#define __SIZEOF_CHAR 1 + +/* The size of `short int', as computed by sizeof. */ +#define __SIZEOF_SHORT 2 + +/* The size of `int', as computed by sizeof. */ +#define __SIZEOF_INT 4 + +/* The size of `long', as computed by sizeof. */ +#define __SIZEOF_LONG 4 + +/* The size of `long long', as computed by sizeof. */ +#define __SIZEOF_LONG_LONG 8 + +/* The size of `float', as computed by sizeof. */ +#define __SIZEOF_FLOAT 4 + +/* The size of `double', as computed by sizeof. */ +#define __SIZEOF_DOUBLE 8 + +/* The size of `long double', as computed by sizeof. */ +#define __SIZEOF_LONG_DOUBLE 12 + +/* The size of `float _Complex', as computed by sizeof. */ +#define __SIZEOF_FLOAT__COMPLEX 8 + +/* The size of `_Complex', as computed by sizeof. */ +#define __SIZEOF__COMPLEX 16 + +/* The size of `double _Complex', as computed by sizeof. */ +#define __SIZEOF_DOUBLE__COMPLEX 16 + +/* The size of `long double _Complex', as computed by sizeof. */ +#define __SIZEOF_LONG_DOUBLE__COMPLEX 24 + +/* The size of `void *', as computed by sizeof. */ +#define __SIZEOF_PTR 4 + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef __WORDS_BIGENDIAN */ + +/* The number of int-sized words needed to save status in a jmp_buf + The value "22" put in here right now is utterly arbitrary but dates back + to the amount of space used on an ARM once upon a time long ago. */ + +#define __JMP_BUF_SIZE 22 + +/* Failure and Success codes to return when a program completes */ +#define __EXIT_FAILURE 1 +#define __EXIT_SUCCESS 0 + +/* clock ticks per second */ +/* Code Red Technologies 2007 + * Officially the semihosting SWI returns a clock value + * in CentiSeconds + */ +#define __CLK_TCK 100 + +/* Defining these indicates that an 8-bit or 16-bit data type is liable + to lead to faster or more compact code than use of a 32-bit int. */ +/* #undef __EIGHT_BIT_MACHINE */ +/* #undef __SIXTEEN_BIT_MACHINE */ + + +/* + * @@@ from here down pollutes name-space etc... + */ + + +/* Specify byte-order. EVEN is for Intel etc, ODD is Motorola etc */ +#define BYTESEX_EVEN 1 +#undef BYTESEX_ODD + +/* Layout in memory for floating point values must be indicated here */ +// code_red +#define DOUBLE_EXP_LAST 1 +#undef OTHER_WORD_ORDER_FOR_FP_NUMBERS + + +#define MAXSTORE 0x03ffffff /* used only by alloc.c */ +#define HOST_LACKS_ALLOC 1 + +struct __FILE_struct +{ + unsigned char *__ptr; + int __icnt; /* two separate _cnt fields so we can police ... */ + int __ocnt; /* ... restrictions that read/write are fseek separated */ + int __flag; +/* + * The fields below here are for system use only. + */ + unsigned char *__base; /* buffer base */ +#ifndef FILEHANDLE +#define FILEHANDLE int +#endif + FILEHANDLE __file; /* file handle as used by lower level code */ + long __pos; /* position in file */ + int __bufsiz; /* maximum buffer size */ + int __signature; /* used with temporary files */ + unsigned char __lilbuf[2]; /* single byte buffer for them that want it */ + /* plus an unget char is put in __lilbuf[1] */ + long _lspos; /* what __pos should be (set after lazy seek) */ + unsigned char *__extent; /* extent of writes into the current buffer */ + int __buflim; /* used size of buffer */ + int __savedicnt; /* after unget contains old icnt */ + int __savedocnt; /* after unget contains old ocnt */ +}; + /* + * FILE is an object capable of recording all information needed to control + * a stream, such as its file position indicator, a pointer to its + * associated buffer, an error indicator that records whether a read/write + * error has occurred and an end-of-file indicator that records whether the + * end-of-file has been reached. + */ + + + +extern int _interrupts_off; +extern void _raise_stacked_interrupts(void); +extern void _postmortem(void); +extern void _mapstore(void); +extern void _Cwrite_profile(char *filename); + +extern void _init_alloc(void), _initio(void), + _terminateio(void), _lib_shutdown(void), _signal_init(void), + _exit_init(void); + +extern int _signal_real_handler(int sig); + +#ifndef __SIZE_T_DEFINED +#define __SIZE_T_DEFINED +#if __SIZEOF_INT < __SIZEOF_VOID_P +typedef unsigned long size_t; +#else +typedef unsigned int size_t; +#endif +#endif + +extern void *_Csys_alloc(size_t n); +extern void _init_user_alloc(void); +extern void _terminate_user_alloc(void); +extern void _Csys_msg(const char *); +extern void _deferredlazyseek(struct __FILE_struct *stream); +extern int _fflush(struct __FILE_struct *stream); +extern int _Cwritebuf(unsigned char *buf, int len, struct __FILE_struct *stream); +extern struct __FILE_struct *_fdopen(FILEHANDLE fh, const char *mode, struct __FILE_struct *iob); +extern int _Cread(char *ptr, int nbytes, struct __FILE_struct *stream); +extern int _Cwrite(const char *ptr, int nbytes, struct __FILE_struct *stream); +extern int _fillb2(struct __FILE_struct *stream); + +#define _exit(n) __sys_appexit() + +#ifndef FILEHANDLE +/* This is a bit of a hack for the Codemist simulator (see stdio.h). */ +typedef int FILEHANDLE; +#endif + +/* + * Note that on some machines where there is no "divide" instruction in the + * hardware these may best turn into procedure calls to kernel code... + */ +#define _kernel_sdiv10(x) ((x)/10) +#define _kernel_sdiv(x,y) ((y)/(x)) +#define _kernel_udiv10(v) ((unsigned)((v))/10) + +/* I/O stuff... */ + +//extern FILEHANDLE _Csys_open(const char *name, int openmode); + +#define NONHANDLE ((FILEHANDLE)(-1)) + +#ifndef __TIME_T_DEFINED +#define __TIME_T_DEFINED +typedef unsigned int time_t; /* date/time in unix secs past 1-Jan-70 */ +#endif + +#ifndef __CLOCK_T_DEFINED +#define __CLOCK_T_DEFINED +typedef unsigned int clock_t; /* cpu time type */ +#endif + +void __sys_appexit (void); +clock_t __sys_clock(void); +int __sys_close(int iFileHandle); +int __sys_flen(int handle); +int __sys_istty(int handle); +int __sys_open(const char *pcFileName, int iFileMode, int len); +int __sys_read(int iFileHandle, char *pcBuffer, int iLen); +int __sys_readc(void); +int __sys_remove(const char *pcFileName, int len); +int __sys_rename(const char *oldFileName, int oldlen, const char *newFileName, int newlen); +int __sys_seek(int handle, int pos); +time_t __sys_time(void); +int __sys_tmpnam(char *pcBuf, int iTargetId, int iBufLen); +int __sys_write(int iFileHandle, char *pcBuffer, int iLength); +void __sys_write0(char *pcBuffer); + +#define _Csys_istty_(fh) __sys_istty((int)fh) +#define _Csys_seek_(fh, pos) __sys_seek((int)fh,(int)pos) +#define _Csys_flen_(fh) __sys_flen((int)fh) +#define _ttywrite(buf, len, wh) __sys_write(0,(int)(buf),len) +#define _Csys_write_(fh,buf,len,mode) __sys_write(fh,buf,len) +extern int _Csys_read_(FILEHANDLE fh, unsigned char *buf, int len, int mode); +#define _Csys_close_(fh) __sys_close((int)(fh)) + +#define _Csys_open(name,mode,len) __sys_open(name,mode,len) +//extern void _Csys_tmpnam_(char *name, int sig); + + + +#if __SIZEOF_DOUBLE==4 +#define FLOAT64 long double +#else +#define FLOAT64 double +#endif + +#ifndef DOUBLE_EXP_LAST /* i.e. __sparc __nec etc */ +# ifdef BYTESEX_EVEN +typedef union +{ + //JR + struct + { + //JR + unsigned int mhi:20, x:11, s:1; + unsigned mlo; + } i; + FLOAT64 d; +} fp_number; +# else +typedef union {struct {unsigned int s:1, x:11, mhi:20; unsigned mlo; } i; + FLOAT64 d; } fp_number; +# endif +#else +# ifdef BYTESEX_EVEN + +typedef union +{ + struct + { + unsigned mlo; + unsigned int mhi:20, x:11, s:1; + } i; + FLOAT64 d; +} fp_number; + +# else +typedef union +{ + struct + { + unsigned mlo; + unsigned int s:1, x:11, mhi:20; + } i; + FLOAT64 d; +} fp_number; +# endif +#endif + +/* the object of the following macro is to adjust the floating point */ +/* variables concerned so that the more significant one can be squared */ +/* with NO LOSS OF PRECISION. It is only used when there is no danger */ +/* of over- or under-flow. */ + +/* This code is NOT PORTABLE but can be modified for use elsewhere */ +/* It should, however, serve for IEEE and IBM FP formats. */ + +#define _fp_normalize(high, low) \ + { fp_number temp; /* access to representation */ \ + double temp1; \ + temp.d = high; /* take original number */ \ + temp.i.mlo = 0; /* make low part of mantissa 0 */ \ + temp1 = high - temp.d; /* the bit that was thrown away */ \ + low += temp1; /* add into low-order result */ \ + high = temp.d; \ + } + +extern struct __FILE_struct *_fopen_string_file(const char *data, int length); + +extern int _number_of_exit_functions; +extern void (*_exitvector[])(void); + +/* + * The definitions here are a bit dodgy wrt all the possible mixtures of + * floating point widths. + */ +extern FLOAT64 _frexpl(FLOAT64, int *); +extern FLOAT64 _ldexpl(FLOAT64, int); + +extern double _sincos(double x, double y, int sign, int coscase); +extern double _tancot(double, int); +extern double _asinacos(double, int); + + +#endif /* __SYS_LIBCONFIG_H_INCLUDED */ + +/* end of */ + diff --git a/redlib/include/sys/libconfig.h b/redlib/include/sys/libconfig.h new file mode 100644 index 0000000..97997a6 --- /dev/null +++ b/redlib/include/sys/libconfig.h @@ -0,0 +1,29 @@ +/* Copyright (C) Code Red Technologies Ltd. */ +/* + * Copyright (C) Codemist 2007 + * + * A C Norman + * + * This file specified library configuation options, such as + * prseence or absence of floating point, datatype sizes and other + * stuff. It is implemented by chaining to a visibly system-specific + * version. I could, I imagine, use #ifdefs based on predefined macros + * to select between different sub-types. + * + */ +//***************************************************************************** +// +--+ +// | ++----+ +// +-++ | +// | | +// +-+--+ | +// | +--+--+ +// +----+ Portions copyright (c) 2010-11 Code Red Technologies Ltd. +// +//***************************************************************************** + +#include + + +/* end of */ + diff --git a/redlib/include/sys/redlib_version.h b/redlib/include/sys/redlib_version.h new file mode 100644 index 0000000..f9c9172 --- /dev/null +++ b/redlib/include/sys/redlib_version.h @@ -0,0 +1,21 @@ +//***************************************************************************** +// +--+ +// | ++----+ +// +-++ | +// | | +// +-+--+ | +// | +--+--+ +// +----+ Copyright (c) 2010 Code Red Technologies Ltd. +// +// NXP Semiconductors, 2013-17 +// +// redlib_version.h - provides Redlib versioning information +// +//***************************************************************************** +#ifndef REDLIB_VERSION_H_ +#define REDLIB_VERSION_H_ + +// * Version of Redlib interface (semihosting) in use +#define __REDLIB_INTERFACE_VERSION__ 30000 + +#endif /* REDLIB_VERSION_H_ */ diff --git a/redlib/include/time.h b/redlib/include/time.h new file mode 100644 index 0000000..a4a0c56 --- /dev/null +++ b/redlib/include/time.h @@ -0,0 +1,87 @@ +//******************************************************************* +// Copyright (C) Codemist 2007 +// +// Portions Copyright (c) Code Red Technologies Ltd., 2008-13 +// Portions Copyright (c) NXP Semiconductors, 2013-14 +//******************************************************************* + +#ifndef __TIME_H_INCLUDED +#define __TIME_H_INCLUDED + +#include + +#ifndef __CODEMIST +#define __CODEMIST +#endif + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#include + +#define CLOCKS_PER_SEC __CLK_TCK + +#ifndef __SIZE_T_DEFINED +#define __SIZE_T_DEFINED +#if __SIZEOF_INT < __SIZEOF_VOID_P +typedef unsigned long size_t; +#else +typedef unsigned int size_t; +#endif +#endif + +/* + * The types here are probably pretty dubious and would lead to + * significant risk of overflow. + */ + +#ifndef __CLOCK_T_DEFINED +#define __CLOCK_T_DEFINED +typedef unsigned int clock_t; /* cpu time type */ +#endif + +#ifndef __TIME_T_DEFINED +#define __TIME_T_DEFINED +typedef unsigned int time_t; /* date/time in unix secs past 1-Jan-70 */ +#endif + +#ifndef __STRUCT_TM_DEFINED +#define __STRUCT_TM_DEFINED + +struct tm +{ + int tm_sec; /* seconds after the minute, 0 to 60 + (0 - 60 allows for the occasional leap second) */ + int tm_min; /* minutes after the hour, 0 to 59 */ + int tm_hour; /* hours since midnight, 0 to 23 */ + int tm_mday; /* day of the month, 1 to 31 */ + int tm_mon; /* months since January, 0 to 11 */ + int tm_year; /* years since 1900 */ + int tm_wday; /* days since Sunday, 0 to 6 */ + int tm_yday; /* days since January 1, 0 to 365 */ + int tm_isdst; /* Daylight Savings Time flag */ +}; + /* struct tm holds the components of a calendar time, called the broken-down + * time. The value of tm_isdst is positive if Daylight Savings Time is in + * effect, zero if Daylight Savings Time is not in effect, and negative if + * the information is not available. + */ +#endif + +extern clock_t clock(void); +extern double difftime(time_t time1, time_t time0); +extern time_t mktime(struct tm *timeptr); +extern time_t time(time_t *timer); +extern char *asctime(const struct tm *timeptr); +extern char *ctime(const time_t *timer); +extern struct tm *gmtime(const time_t *timer); +extern struct tm *localtime(const time_t *timer); +extern size_t strftime(char * restrict s, + size_t maxsize, + const char * restrict format, + const struct tm * restrict timeptr); + +#endif /* __TIME_H_INCLUDED */ + +/* end of */ diff --git a/source/API/ADCAPI.h b/source/API/ADCAPI.h new file mode 100644 index 0000000..61ec45b --- /dev/null +++ b/source/API/ADCAPI.h @@ -0,0 +1,75 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* API TITLE: ADCAPI */ +/* DESCRIPTION: This API provides type definitions for objects and */ +/* functions required by Kernel managed AD conversion */ +/* initialisation, functions and events */ +/* */ +/* FILE NAME: ADCAPI.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef ADCAPI_H +#define ADCAPI_H + +#include "types.h" +#include "IOAPI.h" + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +typedef void (*ADCAPI_tpfResultCB)(IOAPI_tenEHIOResource, uint32);/*CR1_83*/ + +typedef enum +{ + ADCAPI_en1Sample, + ADCAPI_en4Samples, + ADCAPI_en8Samples, + ADCAPI_en16Samples, + ADCAPI_en32Samples +} ADCAPI_tenSamplesAv; + +typedef enum +{ + ADCAPI_enDiffGain1, + ADCAPI_enDiffGain2, + ADCAPI_enDiffGain4, + ADCAPI_enDiffGain8, + ADCAPI_enDiffGain16, + ADCAPI_enDiffGain32, + ADCAPI_enDiffGain64 +} ADCAPI_tenDiffGain; + +typedef enum +{ + ADCAPI_en1000Hz = 0, + ADCAPI_en500Hz = 1, + ADCAPI_en250Hz = 2, + ADCAPI_en125Hz = 3, + ADCAPI_en64Hz = 4, + ADCAPI_en32Hz = 5, + ADCAPI_en16Hz = 6, + ADCAPI_en8Hz = 7, + ADCAPI_en4Hz = 8, + ADCAPI_en2Hz = 9, + ADCAPI_en1Hz = 10, + ADCAPI_enTrigger1 = 11, + ADCAPI_enTrigger2 = 12, + ADCAPI_enTrigger3 = 13, + ADCAPI_enTrigger4 = 14, + ADCAPI_enTriggerCount +} ADCAPI_tenTrigger; + +typedef struct +{ + ADCAPI_tenSamplesAv enSamplesAv; + ADCAPI_tenDiffGain enDiffGain; + ADCAPI_tpfResultCB pfResultCB; + ADCAPI_tenTrigger enTrigger; +} ADCAPI_tstADCCB; + + +#endif //ADCAPI_H + diff --git a/source/API/CEMAPI.h b/source/API/CEMAPI.h new file mode 100644 index 0000000..3146201 --- /dev/null +++ b/source/API/CEMAPI.h @@ -0,0 +1,59 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* API TITLE: CEMAPI */ +/* DESCRIPTION: This API provides type definitions for objects and */ +/* functions required by Kernel Cyclic Event Manager */ +/* initialisation, functions and events */ +/* */ +/* FILE NAME: CEMAPI.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef CEMAPI_H +#define CEMAPI_H + + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +typedef uint16 CEMAPI_ttEventTime; +typedef void (*CEMAPI_tpfEventCB)(IOAPI_tenEHIOResource, CEMAPI_ttEventTime); + +typedef enum +{ + CEMAPI_enHardwareRising, + CEMAPI_enHardwareFalling, + CEMAPI_enHardwareAny +} CEMAPI_tenEventTrigger; + +typedef struct +{ + uint32 u32TriggerType; + IOAPI_tenEdgePolarity enEdgePolarity; + bool boFirstEdgeRising; +} CEM_tstPatternSetupCB; + +typedef struct +{ + uint32 u32CycleDuration; + puint32 pu32EventProgram; + puint32 pu32CallbackProgram; + IOAPI_tenEHIOResource enIOHardwareTrigger; +} IOAPI_tenCEMCycleCB; + + + + + + + + + + + +#endif //CEMAPI_H + diff --git a/source/API/CTRLAPI.h b/source/API/CTRLAPI.h new file mode 100644 index 0000000..444f910 --- /dev/null +++ b/source/API/CTRLAPI.h @@ -0,0 +1,72 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* API TITLE: CtrlAPI */ +/* DESCRIPTION: This API provides type definitions for objects and */ +/* functions required by Kernel managed controllers */ +/* initialisation, functions and events */ +/* */ +/* FILE NAME: CtrlAPI.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef CTRLAPI_H +#define CTRLAPI_H + +#include "types.h" +#include "build.h" + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +typedef void (*CTRLAPI_pfPIDResultCB)(uint32); +typedef sint16 CTRLAPI_ttPIDIDX;/*CR1_95*/ + +typedef enum +{ + CTRLAPI_enPID, + CTRLAPI_enFIC +} CTRLAPI_tenCTRLType; + +typedef enum +{ + CTRLAPI_enPID1ms = 0, + CTRLAPI_enPID2ms = 1, + CTRLAPI_enPID4ms = 2, + CTRLAPI_enPID8ms = 3, + CTRLAPI_enPID16ms = 4, + CTRLAPI_enPID32ms = 5, + CTRLAPI_enPID64ms = 6, + CTRLAPI_enPID128ms = 7, + CTRLAPI_enPID256ms = 8, + CTRLAPI_enPID512ms = 9, + CTRLAPI_enPID1024ms = 10, + CTRLAPI_enPIDCall = 11, +} CTRLAPI_tenPIDRate; + + +typedef struct +{ + sint32* pi32Target; + sint32* pi32Feedback; + sint32 i32Error; + sint32 i32OldError; + sint32 i32Integral; + sint32 i32IntegralInput; + uint8 u8PTerm; + uint8 u8ITerm; + uint8 u8DTerm; + sint32* pi32Output; + sint32 i32OutputMin; + sint32 i32OutputMax; + bool boNoWindUp; + bool boResetIntegrator; + bool boRun; + bool boReset; + CTRLAPI_tenPIDRate enPIDRate; + CTRLAPI_pfPIDResultCB pfResultCB; +} BUILD_PACKING CTRLAPI_tstPIDCB; + + +#endif //CTRLAPI_H + diff --git a/source/API/DACAPI.h b/source/API/DACAPI.h new file mode 100644 index 0000000..b56feff --- /dev/null +++ b/source/API/DACAPI.h @@ -0,0 +1,80 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* API TITLE: DACAPI */ +/* DESCRIPTION: This API provides type definitions for objects and */ +/* functions required by Kernel managed DA conversion */ +/* initialisation, functions and DA conversion */ +/* */ +/* FILE NAME: DACAPI.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef DACAPI_H +#define DACAPI_H + +#include "types.h" +#include "IOAPI.h" + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +typedef uint16 DACAPI_ttOutputVoltage;/*CR1_96*/ + +typedef enum +{ + DACAPI_enWaterMarkReached, + DACAPI_enPointerTop, + DACAPI_enPointerBottom +} DACAPI_tenEventType; + +typedef enum +{ + DACAPI_enHardwareTrigger = 0, + DACAPI_enSoftwareTrigger = 1 +} DACAPI_tenTriggerType; + +typedef enum +{ + DACAPI_enQueueDepth1 = 0, + DACAPI_enQueueDepth2 = 1, + DACAPI_enQueueDepth3 = 2, + DACAPI_enQueueDepth4 = 3, + DACAPI_enQueueDepth5 = 4, + DACAPI_enQueueDepth6 = 5, + DACAPI_enQueueDepth7 = 6, + DACAPI_enQueueDepth8 = 7, + DACAPI_enQueueDepth9 = 8, + DACAPI_enQueueDepth10 = 9, + DACAPI_enQueueDepth11 = 10, + DACAPI_enQueueDepth12 = 11, + DACAPI_enQueueDepth13 = 12, + DACAPI_enQueueDepth14 = 13, + DACAPI_enQueueDepth15 = 14, + DACAPI_enQueueDepth16 = 15 +} DACAPI_tenQueueDepth; + +typedef enum +{ + DACAPI_enWatermark1Word = 0, + DACAPI_enWatermark2Words = 1, + DACAPI_enWatermark3Words = 2, + DACAPI_enWatermark4Words = 3 +} DACAPI_tenWatermarkWords; + +typedef void (*DACAPI_tpfEventCB)(IOAPI_tenEHIOResource, DACAPI_tenEventType); + +typedef struct +{ + DACAPI_tenQueueDepth enQueueDepth; + DACAPI_tenWatermarkWords enWatermarkWords; + bool boWaterMarkEventEnable; + bool boPointerTopEventEnable; + bool boPointerBottomEventEnable; + DACAPI_tenTriggerType enTriggerType; + DACAPI_tpfEventCB pfEventCB; +} DACAPI_tstDACCB; + + +#endif //DACAPI_H + diff --git a/source/API/DIAGAPI.h b/source/API/DIAGAPI.h new file mode 100644 index 0000000..4ace764 --- /dev/null +++ b/source/API/DIAGAPI.h @@ -0,0 +1,72 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* API TITLE: DiagAPI */ +/* DESCRIPTION: This API provides type definitions for objects and */ +/* functions required by Kernel managed diagnostics */ +/* initialisation, functions and events */ +/* */ +/* FILE NAME: DiagAPI.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef DIAGAPI_H +#define DIAGAPI_H + +#include "types.h" + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +typedef enum +{ + DIAGAPI_enNoSession, + DIAGAPI_enExtendedSession, + DIAGAPI_enProgramming +} DIAGAPI_tenSession; + +typedef enum +{ + DIAGAPI_enSecLevelInactive, + DIAGAPI_enSecLevelOEM, + DIAGAPI_enSecLevelMDAC +} DIAGAPI_tenDiagSecurityLevel; + +typedef enum +{ + DIAGAPI_enStartRoutine, + DIAGAPI_enStopRoutine, + DIAGAPI_enResultsRoutine +} DIAGAPI_tenRoutineAction; + +typedef struct +{ + bool boTransferComplete; + uint16 u16CID; + puint8 pu8Data; + uint8 u8DataCount; +} DIAGAPI_tstDataTransferCB; + +typedef enum +{ + DIAGAPI_enDataWriteCB, + DIAGAPI_enDataReadCB, + DIAGAPI_enRoutineCB +} DIAGAPI_tenCallBackType; + +typedef enum +{ + DIAGAPI_enCBOK, + DIAGAPI_enRWSecurityError, + DIAGAPI_enRWParamNotFound, + DIAGAPI_enRWGenFail +} DIAGAPI_tenCBResult; + + +typedef DIAGAPI_tenCBResult (*DIAGAPI_tDataWriteCB)(uint16, puint8, uint8); +typedef DIAGAPI_tenCBResult (*DIAGAPI_tReadWriteCB)(uint16, puint8, uint8); +typedef DIAGAPI_tenCBResult (*DIAGAPI_tRoutineCB)(DIAGAPI_tenRoutineAction, puint8, uint8); + +#endif //DIAGAPI_H + diff --git a/source/API/IICAPI.h b/source/API/IICAPI.h new file mode 100644 index 0000000..f793f2e --- /dev/null +++ b/source/API/IICAPI.h @@ -0,0 +1,28 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* API TITLE: IICAPI */ +/* DESCRIPTION: This API provides type definitions for objects and */ +/* functions required by Kernel managed IIC resources */ +/* initialisation, functions and events */ +/* */ +/* FILE NAME: IICAPI.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef IICAPI_H +#define IICAPI_H + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +typedef struct +{ + uint32 u32BaudRateHz; + uint8 u8SlaveAddress; +} IICAPI_tstIICConfig; + + +#endif //IICAPI_H + diff --git a/source/API/IOAPI.h b/source/API/IOAPI.h new file mode 100644 index 0000000..6c9cf0b --- /dev/null +++ b/source/API/IOAPI.h @@ -0,0 +1,404 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* API TITLE: IOAPI */ +/* DESCRIPTION: This API provides type definitions for objects and */ +/* functions required by Kernel managed I/O */ +/* initialisation, functions and events */ +/* */ +/* FILE NAME: IOAPI.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef IOAPI_H +#define IOAPI_H + +#include "build.h" +#include +#include "PROTAPI.h" + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +typedef enum +{ + IOAPI_IO_RX = 0, + IOAPI_IO_TX = 1, + IOAPI_IO_MEM_READ = 2, + IOAPI_IO_MEM_WRITE = 3 +} IOAPI_enTransferType; +/*CR1_103*/ + +typedef enum +{ + IOAPI_enPortComms, + IOAPI_enPortSerialTransfer, + IOAPI_enPortNone +} IOAPI_tenPortMode; + +#if defined(BUILD_MK60) && defined(BUILD_ECUHOST_1_4) +typedef enum +{ + EH_IO_ADSE1 = 0, + EH_IO_ADSE2 = 1, + EH_IO_ADSE3 = 2, + EH_IO_ADSE4 = 3, + EH_IO_ADSE5 = 4, + EH_IO_ADSE6 = 5, + EH_IO_ADSE7 = 6, + EH_IO_ADSE8 = 7, + EH_IO_ADSE9 = 8, + EH_IO_ADSE10 = 9, + EH_IO_ADSE11 = 10, + EH_IO_ADSE12 = 11, + EH_IO_GPSE1 = 12, + EH_IO_GPSE2 = 13, + EH_IO_GPSE5 = 14, + EH_IO_GPSE6 = 15, + EH_IO_GPSE7 = 16, + EH_IO_GPSE8 = 17, + EH_IO_GPSE9 = 18, + EH_IO_GPSE10 = 19, + EH_I_ADD1 = 20, + EH_I_ADD2 = 21, + EH_I_ADD3 = 22, + EH_I_ADD4 = 23, + EH_I_ADD5 = 24, + EH_I_ADD6 = 25, + EH_I_ADD7 = 26, + EH_I_ADD8 = 27, + EH_IO_CAN2T = 28, + EH_IO_CAN2R = 29, + EH_I_CMP1 = 30, + EH_I_CMP2 = 31, + EH_I_CMP3 = 32, + IO_AD_Count = 33, + EH_IO_UART1_TX = 34, + EH_IO_UART1_RX = 35, + EH_IO_UART1_CTS = 36, + EH_IO_UART1_RTS = 37, + EH_IO_UART2_TX = 38, + EH_IO_UART2_RX = 39, + EH_IO_UART2_CTS = 40, + EH_IO_UART2_RTS = 41, + EH_IO_CAN1T = 42, + EH_IO_CAN1R = 43, + EH_IO_TMR1 = 44, + EH_IO_TMR2 = 45, + EH_IO_TMR3 = 46, + EH_IO_TMR4 = 47, + EH_IO_TMR5 = 48, + EH_IO_TMR6 = 49, + EH_IO_TMR7 = 50, + EH_IO_TMR8 = 51, + EH_IO_TMR9 = 52, + EH_IO_TMR10 = 53, + EH_IO_TMR11 = 54, + EH_IO_TMR12 = 55, + EH_IO_TMR13 = 56, + EH_IO_TMR14 = 57, + EH_IO_TMR15 = 58, + EH_IO_TMR16 = 59, + EH_IO_IIC1_SCL = 60, + EH_IO_IIC1_SDA = 61, + EH_I_CMP4 = 62, + EH_I_CMP5 = 63, + EH_O_DAC1 = 64, + EH_O_DAC2 = 65, + EH_IO_GP3 = 66, + EH_IO_GP4 = 67, + EH_IO_K33A = 68, + EH_IO_USB5V = 69, + IO_Total_Discrete_Count = 70, + EH_VIO_IIC1 = 100, + EH_VIO_IIC2 = 101, + EH_VIO_SPI1 = 102, + EH_VIO_SPI2 = 103, + EH_VIO_UART1 = 104, + EH_VIO_UART2 = 105, + EH_VIO_UART3 = 106, + EH_VIO_UART4 = 107, + EH_VIO_UART5 = 108, + EH_VIO_UART6 = 109, + EH_VIO_CAN1 = 110, + EH_VIO_CAN2 = 111, + EH_VIO_ENET_CH1 = 112, + EH_VIO_ENET_CH2 = 113, + EH_VIO_ENET_CH3 = 114, + EH_VIO_ENET_CH4 = 115, + EH_VIO_FTM0 = 116, + EH_VIO_FTM1 = 117, + EH_VIO_FTM2 = 118, + EH_VIO_FTM3 = 119, + IO_Total_Count, + EH_IO_Invalid +} IOAPI_tenEHIOResource; + +#define EH_FIRST_TMR EH_IO_TMR1 +#define EH_LAST_TMR EH_IO_TMR16 +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +typedef enum +{ + EH_IO_GPSE1 = 0, + EH_IO_GPSE2 = 1, + EH_IO_GPSE3 = 2, + EH_IO_GPSE4 = 3, + EH_IO_GPSE5 = 4, + EH_IO_GPSE6 = 5, + EH_IO_GPSE7 = 6, + EH_IO_GPSE8 = 7, + EH_I_ADD1 = 8, + EH_I_ADD2 = 9, + EH_I_CMP1 = 10, + EH_I_CMP2 = 11, + IO_AD_Count = 12, + EH_IO_CAN1T = 13, + EH_IO_CAN1R = 14, + EH_IO_UART1_TX = 15, + EH_IO_UART1_RX = 16, + EH_IO_UART1_CTS = 17, + EH_IO_UART1_RTS = 18, + EH_IO_UART2_TX = 19, + EH_IO_UART2_RX = 20, + EH_IO_SPI1_MISO = 21, + EH_IO_SPI1_MOSI = 22, + EH_IO_SPI1_CLK = 23, + EH_IO_SPI1_CS = 24, + EH_IO_TMR1 = 25, + EH_IO_TMR2 = 26, + EH_IO_TMR3 = 27, + EH_IO_TMR4 = 28, + EH_IO_TMR5 = 29, + EH_IO_TMR6 = 30, + EH_IO_TMR7 = 31, + EH_IO_TMR8 = 32, + EH_IO_TMR9 = 33, + EH_IO_TMR10 = 34, + EH_IO_TMR11 = 35, + EH_IO_TMR12 = 36, + EH_IO_TMR13 = 37, + EH_IO_TMR14 = 38, + EH_IO_TMR15 = 39, + EH_IO_TMR16 = 40, + EH_IO_TMR17 = 41, + EH_IO_TMR18 = 42, + EH_IO_IIC1_SCL = 43, + EH_IO_IIC1_SDA = 44, + EH_O_DAC1 = 45, + EH_O_DAC2 = 46, + EH_IO_GP1 = 47, + EH_IO_GP2 = 48, + EH_IO_GP3 = 49, + EH_IO_GP4 = 50, + EH_IO_GP5 = 51, + EH_IO_GP6 = 52, + EH_IO_GP7 = 53, + EH_IO_GP8 = 54, + EH_IO_GP9 = 55, + EH_IO_GP10 = 56, + EH_IO_GP11 = 57, + EH_IO_GP12 = 58, + EH_IO_GP13 = 59, + EH_IO_GP14 = 60, + EH_IO_K33A = 61, + EH_IO_USB5V = 62, + IO_Total_Discrete_Count, + EH_VIO_IIC1 = 100, + EH_VIO_IIC2 = 101, + EH_VIO_SPI1 = 102, + EH_VIO_SPI2 = 103, + EH_VIO_UART1 = 104, + EH_VIO_UART2 = 105, + EH_VIO_UART3 = 106, + EH_VIO_UART4 = 107, + EH_VIO_UART5 = 108, + EH_VIO_UART6 = 109, + EH_VIO_CAN1 = 110, + EH_VIO_USB = 111, + EH_VIO_ENET_CH1 = 112, + EH_VIO_ENET_CH2 = 113, + EH_VIO_ENET_CH3 = 114, + EH_VIO_ENET_CH4 = 115, + EH_VIO_FTM0 = 116, + EH_VIO_FTM1 = 117, + EH_VIO_FTM2 = 118, + EH_VIO_FTM3 = 119, + EH_VIO_ADC0 = 120, + EH_VIO_ADC1 = 121, + EH_VIO_ADC2 = 122, + EH_VIO_ADC3 = 123, + IO_Total_Count, + EH_IO_Invalid +} IOAPI_tenEHIOResource; + +#define EH_FIRST_TMR EH_IO_TMR1 +#define EH_LAST_TMR EH_IO_TMR18 +#define EH_FIRST_UART EH_VIO_UART1 +#define EH_LAST_UART EH_VIO_UART2 +#define EH_FIRST_IIC EH_VIO_IIC1 +#define EH_LAST_IIC EH_VIO_IIC2 +#define EH_FIRST_SPI EH_VIO_SPI1 +#define EH_LAST_SPI EH_VIO_SPI2 +#define EH_FIRST_CAN EH_VIO_CAN1 +#define EH_LAST_CAN EH_VIO_CAN1 +#define EH_FIRST_USB EH_VIO_USB +#define EH_LAST_USB EH_VIO_USB +#define EH_FIRST_VIO_COMMS EH_VIO_IIC1 +#define EH_LAST_VIO_COMMS EH_VIO_ENET_CH2 + +#endif //BUILD_MK64 + +typedef enum +{ + IOAPI_enDIOOutput, + IOAPI_enDIOInput, + IOAPI_enADSE, + IOAPI_enADD, + IOAPI_enDAC, + IOAPI_enCaptureCompare, + IOAPI_enPWM, + IOAPI_enIICBus, + IOAPI_enIISBus, + IOAPI_enSPIBus, + IOAPI_enUARTBus, + IOAPI_enCANBus, + IOAPI_enENETChannel, + IOAPI_enUSBChannel, + IOAPI_enTEPM +} IOAPI_tenEHIOType; + +typedef enum +{ + IOAPI_enEdgeRising, + IOAPI_enEdgeFalling, + IOAPI_enEdgeBoth +} IOAPI_tenEdgePolarity; + +typedef enum +{ + IOAPI_enLow, + IOAPI_enHigh, + IOAPI_enToggle, + IOAPI_enHiZ, + IOAPI_enError +} IOAPI_tenTriState; + +typedef enum +{ + IOAPI_enWeak, + IOAPI_enStrong +} IOAPI_tenDriveStrength; + +typedef void (*IOAPI_tpfTransferCB)(IOAPI_tenEHIOResource, puint8, uint32, IOAPI_enTransferType); + +typedef struct +{ + uint32 u32MasterAddress; + uint32 u32SlaveAddress; +} tstIICNetInfo; + +typedef struct +{ + uint32 u32Dummy1; + uint32 u32Dummy2; +} tstUARTNetInfo; + +typedef struct +{ + uint32 u32GlobalCANDiagAddress; + uint32 u32CANDiagAddress; + uint32 u32CANPriorityAddress[4]; + uint32 u32CANPriorityMask[4]; +} tstCANNetInfo; + +typedef struct +{ + uint16 u16RPCREQSourcePort; + uint16 u16RPCREQDestPort; +} tstLANNetInfo; + +typedef struct +{ + union + { + tstIICNetInfo stIICNetInfo; + tstCANNetInfo stCANNetInfo; + tstLANNetInfo stLANNetInfo; + tstUARTNetInfo stUARTNetInfo; + } uNetInfo; +} IOAPI_tstNetConfig; + +typedef struct +{ + IOAPI_tenEHIOResource enRXPin; + IOAPI_tenEHIOResource enTXPin; + IOAPI_tenEHIOResource enRTSPin; + IOAPI_tenEHIOResource enCTSPin; +} IOAPI_tstUARTPinInfo; + +typedef struct +{ + IOAPI_tenEHIOResource enRXPin; + IOAPI_tenEHIOResource enTXPin; +} IOAPI_tstCANPinInfo; +/*CR1_104*/ + +typedef struct +{ + IOAPI_tenEHIOResource enSDAPin; + IOAPI_tenEHIOResource enSCLPin; +} IOAPI_tstIICPinInfo; + +typedef struct +{ + IOAPI_tenEHIOResource enMOSIPin; + IOAPI_tenEHIOResource enMISOPin; + IOAPI_tenEHIOResource enSCKPin; + bool boCaptureRising; + bool boShiftRising; + bool boIdleHigh; + bool boDataIdleHigh; +} IOAPI_tstSPIPinInfo; + +typedef struct +{ + union + { + IOAPI_tstUARTPinInfo stUARTPinInfo; + IOAPI_tstIICPinInfo stIICPinInfo; + IOAPI_tstSPIPinInfo stSPIPinInfo; + IOAPI_tstCANPinInfo stCANPinInfo; + } uPinInfo; +} IOAPI_tstPinConfig; + +typedef struct +{ + IOAPI_tstNetConfig stNetConfig; + IOAPI_tstPinConfig stPinConfig; + IOAPI_tenPortMode enPortMode; + uint32 u32BaudRateHz; + uint32 u32TXPacketRateMs; + IOAPI_tenEHIOResource enVIOResource; + PROTAPI_tenLLProtocol enLLProtocol; + PROTAPI_tenNLProtocol enNLProtocol; + PROTAPI_tenTLProtocol enTLProtocol; + IOAPI_tpfTransferCB pfRXTransferCB; + IOAPI_tpfTransferCB pfTXTransferCB; +} IOAPI_tstPortConfigCB; + + +typedef struct +{ + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_enTransferType enTransferType; + IOAPI_tpfTransferCB pfCB; + void* pvData; + uint32 u32ByteCount; + bool boBlockingMode; +} IOAPI_tstTransferCB; + +#endif //IOAPI_H + diff --git a/source/API/MAPSAPI.h b/source/API/MAPSAPI.h new file mode 100644 index 0000000..412e49e --- /dev/null +++ b/source/API/MAPSAPI.h @@ -0,0 +1,45 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* API TITLE: MapsAPI */ +/* DESCRIPTION: This API provides type definitions for objects and */ +/* functions required by Kernel managed maps */ +/* initialisation, functions and events */ +/* */ +/* FILE NAME: MapsAPI.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef MAPSAPI_H +#define MAPSAPI_H + +#include +#include +#include "SPREADSAPI.h" + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +typedef sint16 MAPSAPI_ttMapIDX;/*CR1_118*/ +typedef void (*MAPSAPI_pfPIDResultCB)(sint32); + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wattributes" + +typedef struct +{ + void* pvMapData; + void* pvOutputData; + TYPE_tenDataType enDataType; + sint16 i16MapSizeX; + sint16 i16MapSizeY; + SPREADAPI_ttSpreadIDX tSpreadIDXX; + SPREADAPI_ttSpreadIDX tSpreadIDXY; + MAPSAPI_pfPIDResultCB pfResultCB; +} BUILD_PACKING MAPSAPI_tstMapCB; + +#pragma GCC diagnostic pop + +#endif //MAPSAPI_H + diff --git a/source/API/PIMAPI.h b/source/API/PIMAPI.h new file mode 100644 index 0000000..900ff18 --- /dev/null +++ b/source/API/PIMAPI.h @@ -0,0 +1,69 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* API TITLE: PIMAPI */ +/* DESCRIPTION: This API provides type definitions for objects and */ +/* functions required by Kernel managed port integration */ +/* initialisation, functions and events */ +/* */ +/* FILE NAME: PIMAPI.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef PIMAPI_H +#define PIMAPI_H + + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define PIMAPI_PORT_BIT_0 0x00000001 +#define PIMAPI_PORT_BIT_1 0x00000002 +#define PIMAPI_PORT_BIT_2 0x00000004 +#define PIMAPI_PORT_BIT_3 0x00000008 +#define PIMAPI_PORT_BIT_4 0x00000010 +#define PIMAPI_PORT_BIT_5 0x00000020 +#define PIMAPI_PORT_BIT_6 0x00000040 +#define PIMAPI_PORT_BIT_7 0x00000080 +#define PIMAPI_PORT_BIT_8 0x00000100 +#define PIMAPI_PORT_BIT_9 0x00000200 +#define PIMAPI_PORT_BIT_10 0x00000400 +#define PIMAPI_PORT_BIT_11 0x00000800 +#define PIMAPI_PORT_BIT_12 0x00001000 +#define PIMAPI_PORT_BIT_13 0x00002000 +#define PIMAPI_PORT_BIT_14 0x00004000 +#define PIMAPI_PORT_BIT_15 0x00008000 +#define PIMAPI_PORT_BIT_16 0x00010000 +#define PIMAPI_PORT_BIT_17 0x00020000 +#define PIMAPI_PORT_BIT_18 0x00040000 +#define PIMAPI_PORT_BIT_19 0x00080000 +#define PIMAPI_PORT_BIT_20 0x00100000 +#define PIMAPI_PORT_BIT_21 0x00200000 +#define PIMAPI_PORT_BIT_22 0x00400000 +#define PIMAPI_PORT_BIT_23 0x00800000 +#define PIMAPI_PORT_BIT_24 0x01000000 +#define PIMAPI_PORT_BIT_25 0x02000000 +#define PIMAPI_PORT_BIT_26 0x04000000 +#define PIMAPI_PORT_BIT_27 0x08000000 +#define PIMAPI_PORT_BIT_28 0x10000000 +#define PIMAPI_PORT_BIT_29 0x20000000 +#define PIMAPI_PORT_BIT_30 0x40000000 +#define PIMAPI_PORT_BIT_31 0x80000000 + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +typedef enum +{ + PIMAPI_enPHYS_PORT_A = 0, + PIMAPI_enPHYS_PORT_B = 1, + PIMAPI_enPHYS_PORT_C = 2, + PIMAPI_enPHYS_PORT_D = 3, + PIMAPI_enPHYS_PORT_E = 4, + PIMAPI_enVIRT_PORT_F, + PIMAPI_enPORT_Count, + PIMAPI_enPortInvalid +} PIMAPI_tenPort; + + +#endif //PIMAPI_H + diff --git a/source/API/PROTAPI.h b/source/API/PROTAPI.h new file mode 100644 index 0000000..c67282b --- /dev/null +++ b/source/API/PROTAPI.h @@ -0,0 +1,62 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* API TITLE: ProtAPI */ +/* DESCRIPTION: This API provides type definitions for objects and */ +/* functions required by Kernel managed protocol */ +/* initialisation, functions and events */ +/* */ +/* FILE NAME: ProtAPI.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef PROTAPI_H +#define PROTAPI_H + +#include "sys.h" + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +typedef enum +{ + PROTAPI_enTLKWP, + PROTAPI_enTLUDS, + PROTAPI_enTLUDS_UDP, + PROTAPI_enTLJ1939, + PROTAPI_enTLUDP, + PROTAPI_enTLNone +} PROTAPI_tenTLProtocol; +/*CR1_109*/ + +typedef enum +{ + PROTAPI_enISO15765, + PROTAPI_enISO15765_IP, + PROTAPI_enNLNone +} PROTAPI_tenNLProtocol; +/*CR1_109*/ + +typedef enum +{ + PROTAPI_enLLUARTPacked, + PROTAPI_enLLUARTSZDelim, + PROTAPI_enLLCAN11, + PROTAPI_enLLCAN29, + PROTAPI_enLL802_3, + PROTAPI_enUSB, + PROTAPI_enLLNone +} PROTAPI_tenLLProtocol; +/*CR1_109*/ + +typedef struct +{ + uint8 u8DLC; + uint32 u32ID; + uint32 u32DWH; + uint32 u32DWL; +} PROTAPI_tstCANMsg; + +#endif //PROTAPI_H + diff --git a/source/API/RESAPI.h b/source/API/RESAPI.h new file mode 100644 index 0000000..5eb15f9 --- /dev/null +++ b/source/API/RESAPI.h @@ -0,0 +1,33 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* API TITLE: ResourceAPI */ +/* DESCRIPTION: This API provides type definitions for off micro */ +/* resources */ +/* */ +/* */ +/* FILE NAME: SpreadsAPI.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#ifdef KERNEL + +#ifndef RESAPI_H +#define RESAPI_H + +#include + +typedef enum +{ + SDHC_MEM, + SPI_MEM, + RES_Count +} RES_tenResource; + +#endif // RESM_H + +#endif // KERNEL + diff --git a/source/API/SPREADSAPI.h b/source/API/SPREADSAPI.h new file mode 100644 index 0000000..307e287 --- /dev/null +++ b/source/API/SPREADSAPI.h @@ -0,0 +1,69 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* API TITLE: SpreadsAPI */ +/* DESCRIPTION: This API provides type definitions for objects and */ +/* functions required by Kernel managed spreads */ +/* initialisation, functions and events */ +/* */ +/* FILE NAME: SpreadsAPI.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef SPREADSAPI_H +#define SPREADSAPI_H + +#include +#include + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +typedef sint16 SPREADAPI_ttSpreadIDX;/*CR1_111*/ + +typedef struct +{ + uint16 u16SpreadIndex; + uint16 u16SpreadOffset; +} BUILD_PACKING tstSpreadResult; + +typedef struct +{ + union + { + tstSpreadResult stSpreadResult; + uint32 u32Data; + } uSpreadData; +} BUILD_PACKING SPREADAPI_tstSpreadResult; + +typedef void (*SPREADAPI_pfPIDResultCB)(SPREADAPI_tstSpreadResult); + +typedef enum +{ + SPREADAPI_enSpread1ms = 0, + SPREADAPI_enSpread2ms = 1, + SPREADAPI_enSpread4ms = 2, + SPREADAPI_enSpread8ms = 3, + SPREADAPI_enSpread16ms = 4, + SPREADAPI_enSpread32ms = 5, + SPREADAPI_enSpread64ms = 6, + SPREADAPI_enSpread128ms = 7, + SPREADAPI_enSpread256ms = 8, + SPREADAPI_enSpread512ms = 9, + SPREADAPI_enSpread1024ms = 10, + SPREADAPI_enSpreadCall = 11, +} SPREADAPI_tenSpreadRate; + +typedef struct +{ + void* pvSourceData; + void* pvSpreadData; + TYPE_tenDataType enDataType; + sint16 s16SpreadSize; + SPREADAPI_tenSpreadRate enSpreadRate; + SPREADAPI_pfPIDResultCB pfResultCB; +} BUILD_PACKING SPREADAPI_tstSpreadCB; + +#endif //SPREADSAPI_H + diff --git a/source/API/SYSAPI.h b/source/API/SYSAPI.h new file mode 100644 index 0000000..c1d358d --- /dev/null +++ b/source/API/SYSAPI.h @@ -0,0 +1,221 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. */ +/* All rights reserved. */ +/******************************************************************************/ +/* */ +/* API TITLE: SYSAPI */ +/* DESCRIPTION: This API provides type definitions for objects and */ +/* functions required for System calls */ +/* */ +/* FILE NAME: SYSAPI.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef SYSAPI_H +#define SYSAPI_H + +#include +#include "TASKAPI.h" + + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define SYSAPI_CALL_MASK_FAIL_RES_INIT 1u + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +typedef enum +{ + SYSAPI_enSetSVCDataPointer = 0x1000, + /* USER_vSVC(SYSAPI_enSetSVCDataPointer, SYSAPI_stSVCDataStruct*, NULL, NULL) */ + + SYSAPI_enSetClientStartTask = 0x1010, + /* USER_vSVC(SYSAPI_enSetClientStartTask, SYSAPI_tpfUserTaskFunction, TASKAPI_tenPriority*, TASKAPI_tenRateMs*) */ + + SYSAPI_enSetClientCyclicTask = 0x1011, + /* USER_vSVC(SYSAPI_enSetClientStartTask, SYSAPI_tpfUserTaskFunction, TASKAPI_tenPriority*, TASKAPI_tenRateMs*) */ + + SYSAPI_enSetClientTerminateTask = 0x1012, + /* USER_vSVC(SYSAPI_enSetClientStartTask, SYSAPI_tpfUserTaskFunction, TASKAPI_tenPriority*, TASKAPI_tenRateMs*) */ + + SYSAPI_enPopulateADArray = 0x1020, + /* USER_vSVC(SYSAPI_enPopulateADArray, NULL, NULL, NULL) TBC*/ + + SYSAPI_enRequestIOResource = 0x1030, + /* USER_vSVC(SYSAPI_enRequestIOResource, IOAPI_tenEHIOResource*, NULL, NULL) */ + + SYSAPI_enInitialiseIOResource = 0x1031, + /* USER_vSVC(SYSAPI_enInitialiseIOResource, IOAPI_tenEHIOResource*, IOAPI_tenEHIOType*, IOAPI_tenAsApplicable*) */ + + SYSAPI_enInitialiseCTRLResource = 0x1032, + /* USER_vSVC(SYSAPI_enInitialiseCTRLResource, CTRLAPI_tenCTRLType, CTRLAPI_tstPIDCB*, NULL) */ + + SYSAPI_enIterateCTRLResource = 0x1033, + /* USER_vSVC(SYSAPI_enIterateCTRLResource, CTRLAPI_tenCTRLType*, CTRLAPI_ttPIDIDX*, NULL) */ + + SYSAPI_enInitialiseSpreadResource = 0x1034, + /* USER_vSVC(SYSAPI_enInitialiseSpreadResource, SPREADAPI_tstSpreadCB*, NULL, NULL) */ + + SYSAPI_enCalculateSpread = 0x1035, + /* USER_vSVC(SYSAPI_enCalculateSpread, SPREADAPI_ttSpreadIDX*, NULL, NULL) */ + + SYSAPI_enInitialiseTableResource = 0x1036, + /* USER_vSVC(SYSAPI_enInitialiseTableResource, TABLEAPI_tstTableCB*, NULL, NULL) */ + + SYSAPI_enCalculateTable = 0x1037, + /* USER_vSVC(SYSAPI_enCalculateTable, TABLEAPI_ttTableIDX*, NULL, NULL) */ + + SYSAPI_enAssertDIOResource = 0x1050, + /* USER_vSVC(SYSAPI_enAssertDIOResource, IOAPI_tenEHIOResource*, IOAPI_tenTriState*, NULL) */ + + SYSAPI_enTriggerADQueue = 0x1051, + /* USER_vSVC(SYSAPI_enTriggerADQueue, ADCAPI_tenTrigger*, NULL, NULL) */ + + SYSAPI_enRequestIOBusTransfer = 0x1052, + /* USER_vSVC(SYSAPI_enRequestIOBusTransfer, IOAPI_tenEHIOResource*, IOAPI_tstTransferCB*, NULL) */ + + SYSAPI_enAppendTEPMQueue = 0x1053, + /* USER_vSVC(SYSAPI_enAppendTEPMQueue, IOAPI_tenEHIOResource*, TEPMAPI_tstTimedEvent*, TEPMAPI_ttEventCount*) */ + + SYSAPI_enWriteDACQueue = 0x1054, + /* USER_vSVC(SYSAPI_enWriteDACQueue, IOAPI_tenEHIOResource*, DACAPI_ttOutputVoltage*, NULL) */ + + SYSAPI_enSetDiagCallback = 0x1055, + /* USER_vSVC(SYSAPI_enSetDiagCallback, DIAGAPI_tenCallBackType*, DIAGAPI_tDataWriteCB*, NULL) */ + + SYSAPI_enGetTimerValue = 0x1060, + /* USER_vSVC(SYSAPI_enGetTimerValue, IOAPI_tenEHIOResource*, puint32*, NULL) */ + + SYSAPI_enGetCRC16 = 0x1061, + /* USER_vSVC(SYSAPI_enGetCRC16, NULL, NULL, NULL) TBC */ + + SYSAPI_enCheckPartition = 0x1062, + /* USER_vSVC(SYSAPI_enCheckPartition, NULL, NULL, NULL) */ + + SYSAPI_enSetupWorkingPage = 0x1063, + /* USER_vSVC(SYSAPI_enSetupWorkingPage, puint8*, uint16*, NULL) */ + + SYSAPI_enNVMWorkingCopy = 0x1064, + /* USER_vSVC(SYSAPI_enNVMWorkingCopy, bool*, uint16*, NULL) */ + + SYSAPI_enQueueCANMessage = 0x1065, + + SYSAPI_enConfigureUserTEPMInput = 0x1066, + + SYSAPI_enConfigureKernelTEPMOutput = 0x1067, + + SYSAPI_enSetupCrankTriggerEdgePattern = 0x1068, + + SYSAPI_enResetWatchdog = 0x1069, + + SYSAPI_enSetupSyncPointsPattern = 0x1070, + /* USER_vSVC(enResetWatchdog, uint16*, NULL, NULL) */ + + SYSAPI_enInitialiseMapResource = 0x1071, + /* USER_vSVC(SYSAPI_enInitialiseMapResource, MAPSAPI_tstMapCB*, NULL, NULL) */ + + SYSAPI_enCalculateMap = 0x1072, + /* USER_vSVC(SYSAPI_enCalculateMap, MAPSAPI_ttMapIDX*, NULL, NULL) */ + + SYSAPI_enGetSpreadResult = 0x1073, + /* USER_vSVC(SYSAPI_enGetSpreadResult, TABLEAPI_ttTableIDX*, NULL, NULL) */ + + SYSAPI_enGetDIOResource = 0x1074, + /* USER_vSVC(SYSAPI_enGetDIOResource, IOAPI_tenEHIOResource*, NULL, NULL) */ + + SYSAPI_enGetRawCommsBuffer = 0x1075, + /* USER_vSVC(SYSAPI_enGetRawCommsBuffer, IOAPI_tenEHIOResource*, NULL, NULL) */ + + SYSAPI_enTEPMAsyncRequest = 0x1076, + /* USER_vSVC(SYSAPI_enTEPMAsyncRequest, NULL, NULL, NULL) */ + + SYSAPI_enSetupSimpleCamSync = 0x1077, + /* USER_vSVC(SYSAPI_enSetupSimpleCamSync, IOAPI_tenEHIOResource*, bool, NULL) */ + + SYSAPI_enSetupWatchdog = 0x1078, + /* USER_vSVC(SYSAPI_enSetupWatchdog, puint32, uint32, NULL) */ + + SYSAPI_enGetMode1Buffer = 0x1079, + /* USER_vSVC(SYSAPI_enGetMode1Buffer, puint32, uint32, NULL) */ + + SYSAPI_enGetMode2Buffer = 0x107a, + /* USER_vSVC(SYSAPI_enGetMode2Buffer, puint32, uint32, NULL) */ + + SYSAPI_enGetMode3Buffer = 0x107b, + /* USER_vSVC(SYSAPI_enGetMode3Buffer, puint32, uint32, NULL) */ + + SYSAPI_enGetMode4Buffer = 0x107c, + /* USER_vSVC(SYSAPI_enGetMode4Buffer, puint32, uint32, NULL) */ + + SYSAPI_enGetMode6Buffer = 0x107d, + /* USER_vSVC(SYSAPI_enGetMode6Buffer, puint32, uint32, NULL) */ + + SYSAPI_enGetMode7Buffer = 0x107e, + /* USER_vSVC(SYSAPI_enGetMode7Buffer, puint32, uint32, NULL) */ + + SYSAPI_enGetByteQueue = 0x107f, + /* USER_vSVC(SYSAPI_enGetByteQueue, IOAPI_tenEHIOResource*, NULL, NULL) */ + + SYSAPI_enGetByteQueueBuffer = 0x1080, + /* USER_vSVC(SYSAPI_enGetByteQueueBuffer, IOAPI_tenEHIOResource*, NULL, NULL) */ + + SYSAPI_enSetFuelCuts = 0x1081, + /* USER_vSVC(SYSAPI_enSetFuelCuts, puint32, puint32, NULL) */ + + SYSAPI_enSetSparkCuts = 0x1082 + /* USER_vSVC(SYSAPI_enSetSparkCuts, puint32, puint32, NULL) */ +} SYSAPI_tenSVCID; + +typedef enum +{ + SYSAPI_enOK, + SYSAPI_enFail, + SYSAPI_enQueueFull, + SYSAPI_enBadArgument, + SYSAPI_enBadResource, + SYSAPI_enResourceAlreadyAllocated, + SYSAPI_enMasterResourceUninitialised, + SYSAPI_enMasterResourceMismatch, + SYSAPI_enBaudRateUnavailable, + SYSAPI_enResourceUnavailable, + SYSAPI_enBadCallback, + SYSAPI_enBadCRC16, + SYSAPI_enBadPartition, + SYSAPI_enBadNVMWorkingCopy +} SYSAPI_tenSVCResult; + +typedef enum +{ + SYSAPI_enStartOK, + SYSAPI_enResourceRequestFailed, + SYSAPI_enResourceInitFailed +} SYSAPI_tenStartResult; + +typedef uint32 SYSAPI_ttClientHandle; + +typedef struct +{ + SYSAPI_tenSVCResult enSVCResult; + SYSAPI_ttClientHandle tClientHandle;/*CR1_117*/ + SYSAPI_tenSVCID enSVCID; + void* pvArg1; + void* pvArg2; + void* pvArg3; + void* pvData; +} SYSAPI_tstSVCDataStruct; + +/* typedef of user start, run and terminate function pointers */ +typedef void (*SYSAPI_tpfUserTaskFunction)(uint32 * const pu32Arg);/*CR1_116*/ + +typedef struct +{ + SYSAPI_tpfUserTaskFunction pfStart; + SYSAPI_tpfUserTaskFunction pfRun; + SYSAPI_tpfUserTaskFunction pfTerminate; + SYSAPI_tpfUserTaskFunction pfCallBack; + TASKAPI_tenPriority enPriority; + TASKAPI_tenRateMs enRateMs; +} SYSAPI_tstUserModuleFunctions; + + +#endif // SYSAPI_H + diff --git a/source/API/TABLESAPI.h b/source/API/TABLESAPI.h new file mode 100644 index 0000000..320ef83 --- /dev/null +++ b/source/API/TABLESAPI.h @@ -0,0 +1,37 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* API TITLE: TablesAPI */ +/* DESCRIPTION: This API provides type definitions for objects and */ +/* functions required by Kernel managed tables */ +/* initialisation, functions and events */ +/* */ +/* FILE NAME: TablesAPI.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef TABLESAPI_H +#define TABLESAPI_H + +#include +#include + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +typedef sint16 TABLEAPI_ttTableIDX;/*CR1_118*/ +typedef void (*TABLEAPI_pfPIDResultCB)(sint32); + +typedef struct BUILD_PACKING +{ + void* pvTableData; + void* pvOutputData; + TYPE_tenDataType enDataType; + sint16 i16TableSize; + SPREADAPI_ttSpreadIDX tSpreadIDX;/*CR1_119*/ + TABLEAPI_pfPIDResultCB pfResultCB; +} TABLEAPI_tstTableCB; + +#endif //TABLESAPI_H + diff --git a/source/API/TASKAPI.h b/source/API/TASKAPI.h new file mode 100644 index 0000000..6fb16cf --- /dev/null +++ b/source/API/TASKAPI.h @@ -0,0 +1,48 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* API TITLE: TaskAPI */ +/* DESCRIPTION: This API provides type definitions for objects and */ +/* functions required by Kernel managed application tasks */ +/* initialisation, functions and events */ +/* */ +/* FILE NAME: TaskAPI.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef TASKAPI_H +#define TASKAPI_H + +#include + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +typedef enum +{ + TASKAPI_enTaskPrMaxAll = 0u, + TASKAPI_enTaskPrMaxCyc = 128u, + TASKAPI_enTaskPrLowest = 255u, +} TASKAPI_tenPriority;/*CR1_120*/ + +typedef enum +{ + TASKAPI_enTaskCycBad = 0u, + TASKAPI_enTask1ms = 1u, + TASKAPI_enTask2ms = 2u, + TASKAPI_enTask5ms = 5u, + TASKAPI_enTask10ms = 10u, + TASKAPI_enTask20ms = 20u, + TASKAPI_enTask25ms = 25u, + TASKAPI_enTask50ms = 50u, + TASKAPI_enTask100ms = 100u, + TASKAPI_enTask200ms = 200u, + TASKAPI_enTask250ms = 250u, + TASKAPI_enTaskCycNot = 255u +} TASKAPI_tenRateMs;/*CR1_120*/ + + +#endif //TASKAPI_H + + diff --git a/source/API/TEPMAPI.h b/source/API/TEPMAPI.h new file mode 100644 index 0000000..016ec00 --- /dev/null +++ b/source/API/TEPMAPI.h @@ -0,0 +1,139 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* API TITLE: TepmAPI */ +/* DESCRIPTION: This API provides type definitions for objects and */ +/* functions required by Kernel managed timed events */ +/* initialisation, functions and events */ +/* */ +/* FILE NAME: TepmAPI.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef TEPMAPI_H +#define TEPMAPI_H + +#ifdef KERNEL_WARNINGS + #warning define must match kernel value!!!! +#endif +#define TEPMAPI_nKernelEventsMax 4 +#define TEPMAPI_nUserEventsMax 4 +/*CR1_121*/ + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +typedef uint32 TEPMAPI_ttEventTime; +typedef void (*TEPMAPI_tpfEventCB)(IOAPI_tenEHIOResource, TEPMAPI_ttEventTime); +typedef uint32 TEPMAPI_ttEventCount; + +typedef enum +{ + TEPMAPI_enActionReset, + TEPMAPI_enSetHigh, + TEPMAPI_enSetLow, + TEPMAPI_enToggle, + TEPMAPI_enCapRising, + TEPMAPI_enCapFalling, + TEPMAPI_enCapAny, + TEPMAPI_enNoAction, + TEPMAPI_enEndProgram, + TEPMAPI_enResetProgram +} TEPMAPI_tenAction;/*CR1_122*/ + +typedef enum +{ + TEPMAPI_enMethodReset, + TEPMAPI_enGlobalLinkedTimeStep, + TEPMAPI_enGlobalLinkedFractionStep, + TEPMAPI_enGlobalLinkedFraction, + TEPMAPI_enHardLinkedTimeStep, + TEPMAPI_enHardLinkedFractionStep, + TEPMAPI_enGlobalAlarm, + TEPMAPI_enHardAlarm, + TEPMAPI_enMaxDelta, + TEPMAPI_enMinDelta, + TEPMAPI_enLinkPrimaryProgram, + TEPMAPI_enLinkVVT1Input, + TEPMAPI_enLinkVVT2Input, + TEPMAPI_enLinkVVT3Input, + TEPMAPI_enLinkVVT4Input, + TEPMAPI_enLinkFreqInput, + TEPMAPI_enLinkDutyInput +} TEPMAPI_tenMethod;/*CR1_122*/ + +typedef enum +{ + TEPMAPI_enDiv1 = 0, + TEPMAPI_enDiv2 = 1, + TEPMAPI_enDiv4 = 2, + TEPMAPI_enDiv8 = 3, + TEPMAPI_enDiv16 = 4, + TEPMAPI_enDiv32 = 5, + TEPMAPI_enDiv64 = 6, + TEPMAPI_enDiv128 = 7 +} TEPMAPI_tenPreScalar;/*CR1_122*/ + +typedef enum +{ + TEPMAPI_enCountUp = 0, + TEPMAPI_enCountUpDown = 1 +} TEPMAPI_tenCountType;/*CR1_122*/ + +typedef struct +{ + TEPMAPI_tenAction enAction; + TEPMAPI_tenMethod enMethod; + TEPMAPI_ttEventTime tEventTime; + TEPMAPI_tpfEventCB pfEventCB; +} TEPMAPI_tstTimedUserEvent;/*CR1_122*/ + +typedef struct +{ + TEPMAPI_tenAction enAction; + TEPMAPI_tenMethod enMethod; + TEPMAPI_ttEventTime* ptEventTime; + TEPMAPI_tpfEventCB pfEventCB; + TEPMAPI_ttEventTime tAccumulate; + TEPMAPI_ttEventTime* ptAccumulate; + IOAPI_tenEHIOResource enEHIOBitMirrorResource; +} TEPMAPI_tstTimedKernelEvent;/*CR1_122*/ + +typedef struct +{ + IOAPI_tenEHIOResource enEHIOResource; + TEPMAPI_tenPreScalar enPreScalar; + TEPMAPI_tenCountType enCountType; +} TEPMAPI_tstTEPMResourceCB;/*CR1_122*/ + +typedef struct +{ + TEPMAPI_tenAction enAction; + TEPMAPI_tenPreScalar enPreScalar; + bool boInterruptEnable; + bool boAsyncRequestEnable; + uint32 u32Sequence; + bool boRecursive; + IOAPI_tenEHIOResource enLinkedResource; +} TEPMAPI_tstTEPMChannelCB; + +typedef struct +{ + uint32 u32HighTime; + uint32 u32LowTime; + uint32 u32RisingTime; + uint32 u32FallingTime; + uint32 u32Delay; +} TEPMAPI_tstTimerMeasurements; + +typedef struct +{ + IOAPI_tenEHIOResource enEHIOResource; + bool boCamSyncHighLate; + uint32 u32CamSyncSampleToothCount; +} TEPMAPI_tstSimpleCamSync; + + +#endif //TEPMAPI_H + diff --git a/source/Client/AFM.c b/source/Client/AFM.c new file mode 100644 index 0000000..7ad99bc --- /dev/null +++ b/source/Client/AFM.c @@ -0,0 +1,190 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Air Flow Meter */ +/* DESCRIPTION: This code module initialises the required ADC */ +/* resources and functions for air flow measurement */ +/* */ +/* FILE NAME: AFM.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#define _AFM_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "AFM.h" +#include "MAP.h" + + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +bool AFM_boNewSample; +EXTERN GPM6_ttUg AFM_tManChargeMassOldUg; + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ +/******************************************************************************* +* Interface : AFM_vADCCallBack +* +* Implementation : Callback to receive the measured ADC value +* +* Parameter +* Par1 : enEHIOResource enum of the ADC resource +* Par2 : u32ADCResult the ADC conversion value +* +* Return Value : NIL +*******************************************************************************/ +static void AFM_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult); +SPREADAPI_ttSpreadIDX AFM_tSpreadBackupAirflowxIDX; +SPREADAPI_ttSpreadIDX AFM_tSpreadBackupAirflowyIDX; +MAPSAPI_ttMapIDX AFM_tMapBackupAirflowIDX; + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void AFM_vStart(puint32 const pu32Arg) +{ + AFM_boNewSample = FALSE; + +#ifdef BUILD_BSP_AFM_ANALOG + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenEHIOType enEHIOType; + ADCAPI_tstADCCB stADCCB; + + enEHIOResource = USERCAL_stRAMCAL.u16AFMADResource; + enEHIOType = IOAPI_enADSE; + stADCCB.enSamplesAv = ADCAPI_en32Samples; + stADCCB.pfResultCB = &AFM_vADCCallBack; + stADCCB.enTrigger = ADCAPI_enTrigger4; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stADCCB); + + if (SYSAPI_enOK != pstSVCDataStruct->enSVCResult) + { + *pu32Arg |= (uint32)SYSAPI_enResourceRequestFailed;/*CR1_13*/ + } + } + else + { + *pu32Arg |= (uint32)SYSAPI_enResourceInitFailed;/*CR1_13*/ + } +#endif + + AFM_tSensorHertz = 0; + + /* Request and initialise required Kernel managed spread for backup airflow x */ + AFM_tSpreadBackupAirflowxIDX = SETUP_tSetupSpread((void*)&CAM_u32RPMRaw, (void*)&USERCAL_stRAMCAL.aUserBackupAirflowxSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for backup airflow y */ + AFM_tSpreadBackupAirflowyIDX = SETUP_tSetupSpread((void*)&TPS_tThetaFiltered, (void*)&USERCAL_stRAMCAL.aUserBackupAirflowySpread, TYPE_enUInt32, 11, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed map for backup airflow */ + AFM_tMapBackupAirflowIDX = SETUP_tSetupMap((void*)&USERCAL_stRAMCAL.aUserBackupAirflowMap, (void*)&AFM_tAirFlowBackupRawUg, TYPE_enUInt32, 11, 11, AFM_tSpreadBackupAirflowxIDX, AFM_tSpreadBackupAirflowyIDX, NULL); +} + +void AFM_vRun(puint32 const pu32Arg) +{ + uint32 u32Temp; + uint8 u8ManifoldTimeConstantFilter; + SPREADAPI_tstSpreadResult* pstSpreadResultAirflowBackupX; + SPREADAPI_tstSpreadResult* pstSpreadResultAirflowBackupY; + uint32 u32TableIDXx = ~0; + uint32 u32TableIDXy = ~0; + + if (TRUE == AFM_boNewSample) + { + USER_xEnterCritical();/*CR1_16*/ + (void)USERMATH_u16SinglePoleLowPassFilter16((uint16)AFM_u32ADCRaw, AFM_nADFiltVal, + &AFM_u32ADCFiltered); + AFM_boNewSample = FALSE; + USER_xExitCritical();/*CR1_16*/ + + u32Temp = AFM_u32ADCFiltered * SENSORS_nADRefVolts; + u32Temp /= SENSORS_nADScaleMax; + u32Temp /= SENSORS_nVDivRatio; + + AFM_tSensorVolts = u32Temp; + + (void)BOOSTED_boIndexAndCalculateMap(AFM_tSpreadBackupAirflowxIDX, AFM_tSpreadBackupAirflowyIDX, AFM_tMapBackupAirflowIDX); + + u8ManifoldTimeConstantFilter = USERMATH_u8GetFilterFromTimeConstant(0x01, TPS_u32ManifoldVolumeTau ); + u8ManifoldTimeConstantFilter = ~u8ManifoldTimeConstantFilter; + u8ManifoldTimeConstantFilter++; + + AFM_tAirFlowBackupUg = USERMATH_u32SinglePoleLowPassFilter32(AFM_tAirFlowBackupRawUg, u8ManifoldTimeConstantFilter, &AFM_tAirFlowBackupUg); + + if (0 == TPS_u32ThrottleMovingCounter) + { + /* Get the current x spread for backup airflow */ + pstSpreadResultAirflowBackupX = BOOSTED_pstGetSpread(AFM_tSpreadBackupAirflowxIDX); + + /* Get the current x spread for backup airflow */ + pstSpreadResultAirflowBackupY = BOOSTED_pstGetSpread(AFM_tSpreadBackupAirflowyIDX); + + u32TableIDXx = (0x1000u > pstSpreadResultAirflowBackupX->uSpreadData.stSpreadResult.u16SpreadOffset) ? pstSpreadResultAirflowBackupX->uSpreadData.stSpreadResult.u16SpreadIndex : u32TableIDXx; + u32TableIDXx = (0xf000u < pstSpreadResultAirflowBackupX->uSpreadData.stSpreadResult.u16SpreadOffset) ? pstSpreadResultAirflowBackupX->uSpreadData.stSpreadResult.u16SpreadIndex + 1 : u32TableIDXx; + u32TableIDXy = (0x1000u > pstSpreadResultAirflowBackupY->uSpreadData.stSpreadResult.u16SpreadOffset) ? pstSpreadResultAirflowBackupY->uSpreadData.stSpreadResult.u16SpreadIndex : u32TableIDXy; + u32TableIDXy = (0xf000u < pstSpreadResultAirflowBackupY->uSpreadData.stSpreadResult.u16SpreadOffset) ? pstSpreadResultAirflowBackupY->uSpreadData.stSpreadResult.u16SpreadIndex + 1 : u32TableIDXy; + + /* If the indexes are valid then learn the new airflow */ + if ((0xffffffff != u32TableIDXx) && (0xffffffff != u32TableIDXy)) + { + u32Temp = AFM_tAirFlowAFMUg / 4 + (3 * USERCAL_stRAMCAL.aUserBackupAirflowMap[u32TableIDXx][u32TableIDXy]) / 4; + USERCAL_stRAMCAL.aUserBackupAirflowMap[u32TableIDXx][u32TableIDXy] = u32Temp; + } + } + } + + /* Calculate predicted VE method airflow */ + u32Temp = MAP_u16VE * USERCAL_stRAMCAL.u16CylinderCC * USERCAL_stRAMCAL.u8CylCount / 120; + u32Temp *= CAM_u32RPMRaw; + u32Temp /= 10000; + u32Temp *= MAP_tKiloPaFiltered; + u32Temp /= 10000; + + /* Correct for air temperature */ + u32Temp = (u32Temp * 2980 ) / ((ATS_tTempCPort / 100) + 2730); + AFM_tAirFlowVEUg = 1225 * u32Temp; + +#ifdef BUILD_BSP_AFM_FREQ + /* Calculate current running VE */ + u32Temp = USERCAL_stRAMCAL.u16CylinderCC * USERCAL_stRAMCAL.u8CylCount / 120; + u32Temp *= CAM_u32RPMFiltered; + u32Temp /= 10; + u32Temp *= MAP_tKiloPaFiltered; + u32Temp /= 10000; + u32Temp *= 1225; + u32Temp /= 1000; + AFM_u16LearnVE = AFM_tAirFlowAFMUg / u32Temp; +#endif +} + +void AFM_vTerminate(puint32 const pu32Arg) +{ + +} + + +void AFM_vCallBack(puint32 const pu32Arg) +{ + +} + + +static void __attribute__((used)) AFM_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult) +{ + AFM_u32ADCRaw = u32ADCResult; + AFM_boNewSample = TRUE; +} + + + +#endif //BUILD_USER diff --git a/source/Client/AFM.h b/source/Client/AFM.h new file mode 100644 index 0000000..1030204 --- /dev/null +++ b/source/Client/AFM.h @@ -0,0 +1,63 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Air Flow Meter Sensor Header File */ +/* DESCRIPTION: This code module initialises the required ADC */ +/* resources and functions for air flow measurement */ +/* */ +/* FILE NAME: AFM.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef AFM_H +#define AFM_H + +#include +#include "boosted.h" +#include "IOAPI.h" +#include "USER.h" +#include "units.h" + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define AFM_nVoltsFilteredInitVal (uint32)(0u) +#define AFM_nADFiltVal (0x10) + + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _AFM_C + #define EXTERN +#else + #define EXTERN extern +#endif + + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +EXTERN uint32 AFM_u32ADCRaw; +//ASAM mode=readvalue name="AFM Sensor ADC" type=uint32 offset=0 min=0 max=4095 m=1 b=0 units="dl" format=5.3 help="AFM Sensor ADC Counts" +EXTERN uint32 AFM_u32ADCFiltered; +EXTERN GPM6_ttHertz AFM_tSensorHertz;/*CR1_88*/ +//ASAM mode=readvalue name="AFM Sensor Frequency" type=uint32 offset=0 min=0 max=65535 m=1 b=0 units="Hz" format=5.3 help="AFM Sensor Flow" +EXTERN GPM6_ttVolts AFM_tSensorVolts;/*CR1_88*/ +//ASAM mode=readvalue name="AFM Sensor Voltage" type=uint32 offset=0 min=0 max=5 m=0.001 b=0 units="V" format=5.3 help="AFM Sensor Flow" +EXTERN GPM6_ttUg AFM_tAirFlowAFMUg; +//ASAM mode=readvalue name="AFM Sensor Mass Flow" type=uint32 offset=0 min=0 max=5 m=0.001 b=0 units="V" format=5.3 help="AFM Sensor Flow" +EXTERN GPM6_ttUg AFM_tAirFlowBackupUg; +//ASAM mode=readvalue name="AFM Sensor Mass Filtered Backup" type=uint32 offset=0 min=0 max=5 m=0.001 b=0 units="V" format=5.3 help="AFM Sensor Flow Filtered" +EXTERN GPM6_ttUg AFM_tAirFlowBackupRawUg; +EXTERN GPM6_ttUg AFM_tAirFlowAFMRawUg; +//ASAM mode=readvalue name="AFM Sensor Mass Flow Raw" type=uint32 offset=0 min=0 max=5 m=0.001 b=0 units="V" format=5.3 help="AFM Sensor Flow Raw" +EXTERN GPM6_ttUg AFM_tAirFlowVEUg; +EXTERN uint16 AFM_u16LearnVE; +//ASAM mode=readvalue name="AFM VE Learn" type=uint16 offset=0 min=0 max=2 m=0.001 b=0 units="dl" format=5.3 help="AFM VE Learn" + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void AFM_vStart(uint32 * const pu32Arg); +void AFM_vRun(uint32* const pu32Arg); +void AFM_vTerminate(uint32* const pu32Arg); +void AFM_vCallBack(puint32 const pu32Arg); + +#endif // AFM_H diff --git a/source/Client/ATS.c b/source/Client/ATS.c new file mode 100644 index 0000000..f45b0e2 --- /dev/null +++ b/source/Client/ATS.c @@ -0,0 +1,261 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Air Temperature */ +/* DESCRIPTION: This code module initialises the required ADC */ +/* resources and functions for air temperature */ +/* measurement */ +/* FILE NAME: ATS.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _ATS_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "ATS.h" +#include "CTS.h" + + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +bool ATS_boNewSample; +SPREADAPI_ttSpreadIDX ATS_tSpreadSensorIDX; +SPREADAPI_ttSpreadIDX ATS_tSpreadEnrichmentIDX; +TABLEAPI_ttTableIDX ATS_tTableSensorIDX; +TABLEAPI_ttTableIDX ATS_tTableEnrichmentIDX; + +sint32 ATS_i32Enrichment; +uint32 ATS_u32SampleCount; + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ +/******************************************************************************* +* Interface : ATS_vADCCallBack +* +* Implementation : Callback to receive the measured ADC value +* +* Parameter +* Par1 : enEHIOResource enum of the ADC resource +* Par2 : u32ADCResult the ADC conversion value +* +* Return Value : NIL +*******************************************************************************/ +static void ATS_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult); + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void ATS_vStart(puint32 const pu32Arg) +{ + ATS_u32ADCRaw = 0; + ATS_u32FuelMultiplier = 1000; + ATS_u32SampleCount = 0; + ATS_boNewSample = FALSE; + ATS_tTempCRaw = 20000; + + if (FALSE == USERCAL_stRAMCAL.boATSCANPrimary) + { + /* Request and initialise the ATS ADC input channel */ + SETUP_boSetupADSE(USERCAL_stRAMCAL.u16ATSADResource, IOAPI_enADSE, ADCAPI_en32Samples, &ATS_vADCCallBack, ADCAPI_enTrigger2, pu32Arg); + } + + /* Request and initialise required Kernel managed spread for air sensor */ + ATS_tSpreadSensorIDX = SETUP_tSetupSpread((void*)&ATS_tSensorVolts, (void*)&USERCAL_stRAMCAL.aUserCoolantSensorSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for air sensor */ + ATS_tTableSensorIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserCoolantSensorTable, (void*)&ATS_tTempCRaw, TYPE_enInt32, 17, ATS_tSpreadSensorIDX, NULL); + + /* Request and initialise required Kernel managed spread for air temp enrichment */ + ATS_tSpreadEnrichmentIDX = SETUP_tSetupSpread((void*)&ATS_tTempCPort, (void*)&USERCAL_stRAMCAL.aUserAirTempCorrectionSpread, TYPE_enInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for air temp enrichment */ + ATS_tTableEnrichmentIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserAirTempCorrectionTable, (void*)&ATS_i32Enrichment, TYPE_enUInt16, 17, ATS_tSpreadEnrichmentIDX, NULL); +} + +void ATS_vRun(puint32 const pu32Arg) +{ + uint32 u32Temp; + sint32 s32Temp; +#ifdef BUILD_ATS_PULLUP_SENSE + volatile static uint32 u32Delta; + static uint32 u32LowImpModeCount; + static uint32 u32HighImpModeCount; + static bool boHotMode; + static bool boColdMode; +#endif + static uint32 u32CANATSMsgCount = 0; + static uint8 u8CANATSOld = 0; + static uint32 u32RunCount; + + + if ((TRUE == ATS_boNewSample) || (true == SENSORS_boCANATSNewSample)) + { + ATS_u32SampleCount++; + + if (FALSE == USERCAL_stRAMCAL.boATSCANPrimary) + { + USER_xEnterCritical();/*CR1_16*/ + (void)USERMATH_u16SinglePoleLowPassFilter16((uint16)ATS_u32ADCRaw, ATS_nADFiltVal, + &ATS_u32ADCFiltered); + ATS_boNewSample = FALSE; + USER_xExitCritical();/*CR1_16*/ + +#ifdef BUILD_ATS_PULLUP_SENSE + if ((FALSE == SENSORS_boATSACBiasHigh) && ((0x100 * ATS_u32ADCRaw) > ATS_u32ADCFiltered)) + { + u32Temp = 0x100 * ATS_u32ADCRaw - ATS_u32ADCFiltered; + u32Delta = (u32Temp + 3 * u32Delta) / 4; + } + else if ((TRUE == SENSORS_boATSACBiasHigh) && ((0x100 * ATS_u32ADCRaw) < ATS_u32ADCFiltered)) + { + u32Temp = ATS_u32ADCFiltered - 0x100 * ATS_u32ADCRaw; + u32Delta = (u32Temp + 3 * u32Delta) / 4; + } + + if (0 == CAM_u32RPMRaw) + { + if (10000 < u32Delta) + { + u32HighImpModeCount = 40 > u32HighImpModeCount ? u32HighImpModeCount + 1 : u32HighImpModeCount; + u32LowImpModeCount = 2 < u32LowImpModeCount ? u32LowImpModeCount - 2 : 0; + } + + if (7000 > u32Delta) + { + u32LowImpModeCount = 40 > u32LowImpModeCount ? u32LowImpModeCount + 1 : u32LowImpModeCount; + u32HighImpModeCount = 2 < u32HighImpModeCount ? u32HighImpModeCount - 2 : 0; + } + + boColdMode = 35 < u32HighImpModeCount; + boHotMode = 35 < u32LowImpModeCount; + } + else + { + if (15000 < u32Delta) + { + u32HighImpModeCount = 1000 > u32HighImpModeCount ? u32HighImpModeCount + 1 : u32HighImpModeCount; + u32LowImpModeCount = 2 < u32LowImpModeCount ? u32LowImpModeCount - 2 : 0; + } + + if (10000 > u32Delta) + { + u32LowImpModeCount = 1000 > u32LowImpModeCount ? u32LowImpModeCount + 1 : u32LowImpModeCount; + u32HighImpModeCount = 2 < u32HighImpModeCount ? u32HighImpModeCount - 2 : 0; + } + + boColdMode = 500 < u32HighImpModeCount; + boHotMode = 500 < u32LowImpModeCount; + } + + + if (((FALSE == boHotMode) && (FALSE == boColdMode)) || + ((TRUE == boHotMode) && (TRUE == boColdMode))) + { + return; + } + +#endif //BUILD_BSP_ATS_PULLUP_SENSE + + u32Temp = ATS_u32ADCFiltered * SENSORS_nADRefVolts; + u32Temp /= SENSORS_nADScaleMax; + u32Temp /= SENSORS_nVDivRatio; + ATS_tSensorVolts = u32Temp; + + /* Calculate the current spread for air temp sensor */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&ATS_tSpreadSensorIDX, + NULL, NULL); + + /* Lookup the current spread for air temp sensor */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&ATS_tTableSensorIDX, + NULL, NULL); + } + else + { + if (0xff != SENSORS_u8CANATS) + { + ATS_tTempCRaw = 1000 * (sint32)(SENSORS_u8CANATS - 40); + SENSORS_boCANATSNewSample = FALSE; + + u32CANATSMsgCount++; + + if ((3 < u32CANATSMsgCount) && + (u8CANATSOld == SENSORS_u8CANATS) && + (0 != SENSORS_u8CANATS)) + { + ATS_boATSReady = TRUE; + } + else if (10 < u32CANATSMsgCount) + { + ATS_boATSReady = TRUE; + } + } + else + { + ATS_tTempCRaw = 0; + } + + u8CANATSOld = SENSORS_u8CANATS; + } + + + if ((0 == CAM_u32RPMRaw) || (TRUE == USERCAL_stRAMCAL.boATSCANPrimary)) + { + ATS_tTempCFiltered = ATS_tTempCRaw; + } + else + { + if (ATS_tTempCRaw < ATS_tTempCFiltered) + { + ATS_tTempCFiltered -= 50; + } + else if (ATS_tTempCRaw > ATS_tTempCFiltered) + { + ATS_tTempCFiltered += 50; + } + } + } + + if (0 == (u32RunCount % 0x20)) + { + u32Temp = 110000 > MAP_tKiloPaFiltered ? MAP_tKiloPaFiltered : 110000; + s32Temp = ((110 - ((sint32)u32Temp / 1000u)) * CTS_tTempCFiltered) + (((sint32)u32Temp / 1000u) * ATS_tTempCFiltered); + ATS_tTempCPort = s32Temp / 110; + + + /* Calculate the current spread for air temp enrichment */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&ATS_tSpreadEnrichmentIDX, + NULL, NULL); + + /* Lookup the current spread for air temp enrichment */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&ATS_tTableEnrichmentIDX, + NULL, NULL); + + s32Temp = ATS_i32Enrichment; + ATS_u32FuelMultiplier = (uint32)s32Temp; + } + + u32RunCount++; +} + +void ATS_vTerminate(puint32 const pu32Arg) +{ + +} + +void ATS_vCallBack(puint32 const pu32Arg) +{ + +} + +static void __attribute__((used)) ATS_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult) +{ + ATS_u32ADCRaw = u32ADCResult; + ATS_boNewSample = TRUE; +} + + +#endif //BUILD_USER diff --git a/source/Client/ATS.h b/source/Client/ATS.h new file mode 100644 index 0000000..935534d --- /dev/null +++ b/source/Client/ATS.h @@ -0,0 +1,55 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Coolant Temperature Header File */ +/* DESCRIPTION: This code module initialises the required ADC */ +/* resources and functions for coolant temperature */ +/* measurement */ +/* FILE NAME: ATS.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef ATS_H +#define ATS_H + +#include +#include "IOAPI.h" +#include "SENSORS.h" +#include "USER.h" + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define ATS_nADFiltVal (0x10) + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _ATS_C + #define EXTERN +#else + #define EXTERN extern +#endif + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +EXTERN uint32 ATS_u32ADCRaw; +EXTERN uint32 ATS_u32ADCFiltered; +//ASAM mode=readvalue name="Air Sensor Filtered ADC" type=uint32 offset=0 min=0 max=1048575 m=1 b=0 units="counts" format=5.3 help="ATS Sensor ADC" +EXTERN GPM6_ttVolts ATS_tSensorVolts;/*CR1_88*/ +//ASAM mode=readvalue name="ATS Sensor Voltage" type=uint32 offset=0 min=0 max=5 m=0.001 b=0 units="V" format=3.2 help="ATS Sensor Voltage" +EXTERN GPM6_ttTempC ATS_tTempCRaw; +EXTERN GPM6_ttTempC ATS_tTempCPort; +EXTERN GPM6_ttTempC ATS_tTempCFiltered; +//ASAM mode=readvalue name="Air Temperature" type=uint32 offset=0 min=0 max=200 m=0.001 b=0 units="degrees C" format=4.1 help="Air Temperature" +EXTERN uint32 ATS_u32FuelMultiplier; +EXTERN bool ATS_boATSReady; + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void ATS_vStart(uint32 * const pu32Arg); +void ATS_vRun(uint32* const pu32Arg); +void ATS_vTerminate(uint32* const pu32Arg); +void ATS_vThread(void); +void ATS_vCallBack(puint32 const pu32Arg); + +#endif // ATS_H + diff --git a/source/Client/BOOSTED.c b/source/Client/BOOSTED.c new file mode 100644 index 0000000..57d361a --- /dev/null +++ b/source/Client/BOOSTED.c @@ -0,0 +1,99 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Setup */ +/* DESCRIPTION: This code assist with the setup of kernel managed */ +/* resources */ +/* */ +/* FILE NAME: BOOSTED.c */ +/* REVISION HISTORY: 14-04-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _BOOSTED_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "BOOSTED.h" +#include "os.h" + + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ + + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ + + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +bool BOOSTED_boIndexAndCalculateMap(SPREADAPI_ttSpreadIDX tSpreadxIDX, SPREADAPI_ttSpreadIDX tSpreadyIDX, MAPSAPI_ttMapIDX tMapIDX) +{ + bool boRetVal = false; + + if ((-1 != tSpreadxIDX) && (-1 != tSpreadyIDX) && (-1 != tMapIDX)) + { + /* Calculate the current spread for Map IDXx */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&tSpreadxIDX, + NULL, NULL); + + /* Calculate the current spread for Map IDXy */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&tSpreadyIDX, + NULL, NULL); + + /* Lookup the current value for Map */ + USER_vSVC(SYSAPI_enCalculateMap, (void*)&tMapIDX, + NULL, NULL); + + boRetVal = true; + } + + return boRetVal; +} + +bool BOOSTED_boIndexAndCalculateTable(SPREADAPI_ttSpreadIDX tSpreadIDX, TABLEAPI_ttTableIDX tTableIDX) +{ + bool boRetVal = false; + + if (-1 != tSpreadIDX) + { + /* Calculate the current spread for Table IDX */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&tSpreadIDX, + NULL, NULL); + + /* Lookup the current value for Table */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&tTableIDX, + NULL, NULL); + + boRetVal = true; + } + + return boRetVal; +} + +SPREADAPI_tstSpreadResult* BOOSTED_pstGetSpread(SPREADAPI_ttSpreadIDX tSpreadxIDX) +{ + SPREADAPI_ttSpreadIDX stSpreadxIDX = tSpreadxIDX; + + USER_vSVC(SYSAPI_enGetSpreadResult, (void*)&stSpreadxIDX, + NULL, NULL); + + return OS_stSVCDataStruct.pvArg1; +} + +void BOOSTED_vResetSVCResult(void) +{ + pstSVCDataStruct->enSVCResult = SYSAPI_enOK; +} + +void BOOSTED_vEnableWatchdog(uint16 u16ReloadCount, uint16 u16WindowCount) +{ + USER_vSVC(SYSAPI_enSetupWatchdog, (void*)&u16ReloadCount, + (void*)&u16WindowCount, NULL); +} + +#endif //BUILD_USER diff --git a/source/Client/BOOSTED.h b/source/Client/BOOSTED.h new file mode 100644 index 0000000..b4a1c09 --- /dev/null +++ b/source/Client/BOOSTED.h @@ -0,0 +1,40 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Setup Header */ +/* DESCRIPTION: This code assist with the setup of kernel managed */ +/* resources */ +/* */ +/* FILE NAME: BOOSTED.c */ +/* REVISION HISTORY: 14-04-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef BOOSTED_H +#define BOOSTED_H + +#include +#include "IOAPI.h" +#include "MAPSAPI.h" +#include "USER.h" +#include "SYS.h" +#include "SPREADSAPI.h" +#include "TABLESAPI.h" +#include "TEPMAPI.h" + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ + + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ + + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +bool BOOSTED_boIndexAndCalculateMap(SPREADAPI_ttSpreadIDX, SPREADAPI_ttSpreadIDX, MAPSAPI_ttMapIDX); +bool BOOSTED_boIndexAndCalculateTable(SPREADAPI_ttSpreadIDX, TABLEAPI_ttTableIDX); +SPREADAPI_tstSpreadResult* BOOSTED_pstGetSpread(SPREADAPI_ttSpreadIDX); +void BOOSTED_vResetSVCResult(void); +void BOOSTED_vEnableWatchdog(uint16, uint16); + +#endif // BOOSTED_H + diff --git a/source/Client/BVM.c b/source/Client/BVM.c new file mode 100644 index 0000000..a228498 --- /dev/null +++ b/source/Client/BVM.c @@ -0,0 +1,176 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Battery Voltage */ +/* DESCRIPTION: This code module initialises the required ADC */ +/* resources and functions for battery voltage */ +/* measurement */ +/* FILE NAME: BVM.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#define _BVM_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include + +#ifdef BUILD_USER + +#include "BVM.h" + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +uint32 BVM_u32ADCRaw; +uint32 BVM_u32ADCFiltered; +uint32 BVM_u32ADCPreFiltered; +bool BVM_boNewSample; + + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ +/******************************************************************************* +* Interface : BVM_vADCCallBack +* +* Implementation : Callback to receive the measured ADC value +* +* Parameter +* Par1 : enEHIOResource enum of the ADC resource +* Par2 : u32ADCResult the ADC conversion value +* +* Return Value : NIL +*******************************************************************************/ +static void BVM_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult);/*CR1_11*//*CR1_10*/ + + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void BVM_vStart(uint32 * const pu32Arg) +{ + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenEHIOType enEHIOType; + ADCAPI_tstADCCB stADCCB; + + BVM_u32ADCFiltered = BVM_nVoltsFilteredInitVal;/*CR1_9*/ + BVM_u32ADCRaw = 0;/*CR1_9*//*CR1_15*/ + + enEHIOResource = BVM_nADInput; + enEHIOType = IOAPI_enADSE; + stADCCB.enSamplesAv = ADCAPI_en32Samples; + stADCCB.pfResultCB = &BVM_vADCCallBack; + stADCCB.enTrigger = ADCAPI_enTrigger4; + + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL);/*CR1_12*/ + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stADCCB); + + if (SYSAPI_enOK != pstSVCDataStruct->enSVCResult) + { + *pu32Arg |= (uint32)SYSAPI_enResourceRequestFailed;/*CR1_13*/ + } + } + else + { + *pu32Arg |= (uint32)SYSAPI_enResourceInitFailed;/*CR1_13*/ + } + +} + +void BVM_vRun(uint32* const pu32Arg) +{ + static uint32 u32SecondDerivativeLimitNeg = 0; + static uint32 u32SecondDerivativeLimitPos = 0; + + if (TRUE == BVM_boNewSample) + { + /* User can add filtering */ + BVM_u32ADCPreFiltered = USERMATH_u32SinglePoleLowPassFilter32(BVM_u32ADCRaw, 0x40, &BVM_u32ADCPreFiltered); + + if (BVM_u32ADCPreFiltered > BVM_u32ADCFiltered) + { + /* New sample higher than pre-filter */ + if (u32SecondDerivativeLimitPos < (BVM_u32ADCPreFiltered - BVM_u32ADCFiltered)) + { + u32SecondDerivativeLimitPos += BVM_nSecondDerivativeChangeLimit; + + if (u32SecondDerivativeLimitPos < (BVM_u32ADCPreFiltered - BVM_u32ADCFiltered)) + { + BVM_u32ADCFiltered += u32SecondDerivativeLimitPos; + } + else + { + BVM_u32ADCFiltered = BVM_u32ADCPreFiltered; + } + } + else + { + BVM_u32ADCFiltered = BVM_u32ADCPreFiltered; + } + + u32SecondDerivativeLimitNeg = BVM_nSecondDerivativeChangeLimit <= u32SecondDerivativeLimitNeg ? u32SecondDerivativeLimitNeg - BVM_nSecondDerivativeChangeLimit : 0; + u32SecondDerivativeLimitNeg = BVM_nSecondDerivativeChangeLimit <= u32SecondDerivativeLimitNeg ? u32SecondDerivativeLimitNeg - BVM_nSecondDerivativeChangeLimit : 0; + } + else if (BVM_u32ADCPreFiltered < BVM_u32ADCFiltered) + /* New sample lower than pre-filter */ + { + if (u32SecondDerivativeLimitNeg < (BVM_u32ADCFiltered - BVM_u32ADCPreFiltered)) + { + u32SecondDerivativeLimitNeg += BVM_nSecondDerivativeChangeLimit; + + if (u32SecondDerivativeLimitNeg < (BVM_u32ADCFiltered - BVM_u32ADCPreFiltered)) + { + BVM_u32ADCFiltered -= u32SecondDerivativeLimitNeg; + } + else + { + BVM_u32ADCFiltered = BVM_u32ADCPreFiltered; + } + } + else + { + BVM_u32ADCFiltered = BVM_u32ADCPreFiltered; + } + + u32SecondDerivativeLimitPos = BVM_nSecondDerivativeChangeLimit <= u32SecondDerivativeLimitPos ? u32SecondDerivativeLimitPos - BVM_nSecondDerivativeChangeLimit : 0; + u32SecondDerivativeLimitPos = BVM_nSecondDerivativeChangeLimit <= u32SecondDerivativeLimitPos ? u32SecondDerivativeLimitPos - BVM_nSecondDerivativeChangeLimit : 0; + } + else + { + u32SecondDerivativeLimitPos = BVM_nSecondDerivativeChangeLimit <= u32SecondDerivativeLimitPos ? u32SecondDerivativeLimitPos - BVM_nSecondDerivativeChangeLimit : 0; + u32SecondDerivativeLimitNeg = BVM_nSecondDerivativeChangeLimit <= u32SecondDerivativeLimitNeg ? u32SecondDerivativeLimitNeg - BVM_nSecondDerivativeChangeLimit : 0; + } + + BVM_u32ADCFiltered = (uint32)0x7fffffff < BVM_u32ADCFiltered ? 0 : BVM_u32ADCFiltered; + + BVM_tBattVolts = CONV_tADCToVolts(BVM_nADInput, BVM_u32ADCFiltered); + BVM_boNewSample = FALSE; + } +} + +void BVM_vTerminate(uint32* const pu32Arg) +{ + +} + +void BVM_vCallBack(uint32* const pu32Arg) +{ + +} + +static void BVM_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult) +{ + BVM_u32ADCRaw = u32ADCResult; + BVM_boNewSample = TRUE; +} + +#endif //BUILD_USER + + + + diff --git a/source/Client/BVM.h b/source/Client/BVM.h new file mode 100644 index 0000000..9aeaf2e --- /dev/null +++ b/source/Client/BVM.h @@ -0,0 +1,73 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Battery Voltage Header File */ +/* DESCRIPTION: This code module initialises the required ADC */ +/* resources and functions for battery voltage */ +/* measurement */ +/* FILE NAME: BVM.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#ifndef BVM_H +#define BVM_H + +#include +#include "ADCAPI.h" +#include "CONV.h" +#include "IOAPI.h" +#include "SYSAPI.h" +#include "UNITS.h" +#include "USER.h" +#include "USERMATH.h" + + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define BVM_nVoltsFilteredInitVal (uint32)(1000 * 12) +#define BVM_nSecondDerivativeChangeLimit 1 +/*CR1_87*/ + +#ifdef BUILD_SPARKDOG_PF +#define BVM_nADInput EH_IO_GPSE6 +#endif //BUILD_SPARKDOG_PF + +#ifdef BUILD_SPARKDOG_TEENSY_ADAPT +#define BVM_nADInput EH_IO_GPSE2 +#endif //BUILD_SPARKDOG_PF + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _BVM_C + #define EXTERN +#else + #define EXTERN extern +#endif //BUILD_MK60 + +#ifdef BUILD_MK60 +#define BVM_nRESAD EH_IO_GPSE7 +#endif + +#ifdef BUILD_MK64 +#define BVM_nRESAD EH_IO_UART1_CTS +#endif //BUILD_MK64 + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +EXTERN GPM6_ttVolts BVM_tBattVolts;/*CR1_88*/ +//ASAM mode=readvalue name="Battery Voltage" type=uint32 offset=0 min=0 max=20 m=0.001 b=0 units="V" format=5.3 help="Battery Voltage" + + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void BVM_vStart(uint32* const pu32Arg); +void BVM_vRun(uint32* const pu32Arg); +void BVM_vTerminate(uint32* const pu32Arg); +void BVM_vCallBack(uint32* const pu32Arg); +void BVM_vThread(void); + +#endif // BVM_H + diff --git a/source/Client/CAM.c b/source/Client/CAM.c new file mode 100644 index 0000000..03fe085 --- /dev/null +++ b/source/Client/CAM.c @@ -0,0 +1,174 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Cyclic Activity Manager */ +/* DESCRIPTION: This code module initialises the required */ +/* resources and functions for cyclic activites */ +/* */ +/* FILE NAME: CAM.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _CAM_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "FUEL.h" +#include "CAM.h" +#include "CTS.h" +#include "FME.h" + + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +uint32 CAM_u32RPMTimeout; + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ + + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void CAM_vStart(puint32 const pu32Arg) +{ + CAM_u32RPMTimeout = 0; + FUEL_boFuelPumpOn = TRUE; +} + +void CAM_vRun(puint32 const pu32Arg) +{ + uint32_t u32SeqIDX; + static uint32 u32EngineStoppedCounter = 0; + + + if ((CAM_nPeriodRPMTimeout / CAM_nPeriodMs) > CAM_u32RPMTimeout) + { + CAM_u32RPMTimeout++; + } + else + { + CAM_u32RPMRaw = 0; + CAM_u32RPMRawOld = 0; + } + + if (0 == CAM_u32RPMRaw) + { + if (USERCAL_stRAMCAL.u8FuelPumpPrimerTime <= CAM_u32EngineStoppedTimer) + { + FUEL_boFuelPumpOn = FALSE; + } + else + { + if (0 == (u32EngineStoppedCounter % (1000u / CAM_nPeriodMs))) + { + CAM_u32EngineStoppedTimer++; + } + + u32EngineStoppedCounter++; + } + } + else + { + CAM_u32EngineStoppedTimer = 0; + FUEL_boFuelPumpOn = TRUE; + + if (0 < u32EngineStoppedCounter) + { + u32EngineStoppedCounter--; + + if (0 == u32EngineStoppedCounter) + { + FME_vDiagClearHistory(); + } + } + } + + for (u32SeqIDX = 0; u32SeqIDX < 8; u32SeqIDX++) + { + if (USERCAL_stRAMCAL.au16SeqRPMLimit[u32SeqIDX] < (uint16)CAM_u32RPMRaw) + { + FUEL_aboSeqRevCutFlag[u32SeqIDX] = TRUE; + } + else if ((USERCAL_stRAMCAL.au16SeqRPMLimit[u32SeqIDX] - USERCAL_stRAMCAL.u16SeqRPMLimitHyst) > (uint16)CAM_u32RPMRaw) + { + FUEL_aboSeqRevCutFlag[u32SeqIDX] = FALSE; + } + } +} + +void CAM_vTerminate(puint32 const pu32Arg) +{ + +} + + +void CAM_vCallBack(puint32 const pu32Arg) +{ + +} + +void CAM_vEngineSpeedCB(TEPMAPI_ttEventTime tEventTime) +{ + uint32 u32Temp; + sint32 s32Temp; + + CAM_u32RPMRawOld = CAM_u32RPMRaw; + CAM_u32RPMRaw = CAM_xTicksToRPM(tEventTime); + + s32Temp = CAM_u32RPMRaw - CAM_u32RPMFiltered; + s32Temp = ABS(s32Temp); + + if (150 > s32Temp) + { + if (TRUE == TPS_boThrottleClosed) + { + CAM_u32RPMFiltered = (CAM_u32RPMRaw + 7 * CAM_u32RPMFiltered) / 8; + } + else + { + CAM_u32RPMFiltered = (CAM_u32RPMRaw + CAM_u32RPMFiltered) / 2; + + } + + CAM_u32RPMTransitionCounter = 0 < CAM_u32RPMTransitionCounter ? CAM_u32RPMTransitionCounter - 1 : 0; + } + else + { + CAM_u32RPMFiltered = (CAM_u32RPMRaw + CAM_u32RPMFiltered) / 2; + CAM_u32RPMTransitionCounter = CAM_nRPMTransitionCount; + } + + FUEL_vCalculateFuellingValues(); + CAM_u32RPMTimeout = 0; + + if (1000000 < CTS_i32StartEnrichmentScaled) + { + u32Temp = 1000 * (CTS_i32StartEnrichmentScaled - 1000000); + u32Temp /= 1050u; + u32Temp += 1000000; + CTS_i32StartEnrichmentScaled = u32Temp; + } + + if (1000000 < CTS_i32PostStartEnrichmentScaled) + { + u32Temp = 1000 * (CTS_i32PostStartEnrichmentScaled - 1000000); + u32Temp /= 1003u; + u32Temp += 1000000; + CTS_i32PostStartEnrichmentScaled = u32Temp; + } + + if (TPS_u32TipInEnrichment > 1000) + { + TPS_u32TipInEnrichment -= 1; + } + else + { + TPS_u32TipInEnrichment = 1000; + } +} + +#endif //BUILD_USER diff --git a/source/Client/CAM.h b/source/Client/CAM.h new file mode 100644 index 0000000..ceb1364 --- /dev/null +++ b/source/Client/CAM.h @@ -0,0 +1,57 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Cyclic Activity Manager Header File */ +/* DESCRIPTION: This code module initialises the required */ +/* resources and functions for cyclic activites */ +/* */ +/* FILE NAME: MAP.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef CAM_H +#define CAM_H + +#include +#include "FUEL.h" +#include "IOAPI.h" +#include "SENSORS.h" +#include "TEPMAPI.h" +#include "USER.h" + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define CAM_xTicksToRPM(x) ((60u * SENSORS_nFastFTMFreq) / (4 * x)) +#define CAM_nPeriodMs (10u) +#define CAM_nPeriodRPMTimeout (300u) +#define CAM_nRPMTransitionCount (10) + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _CAM_C + #define EXTERN +#else + #define EXTERN extern +#endif + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +EXTERN uint32 CAM_u32RPMRawOld; +EXTERN uint32 CAM_u32RPMRaw; +//ASAM mode=readvalue name="Engine Speed Raw" type=uint32 offset=0 min=0 max=10000 m=1 b=0 units="RPM" format=4.0 help="Engine Speed" +EXTERN uint32 CAM_u32RPMFiltered; +//ASAM mode=readvalue name="RPM Transition Counter" type=uint32 offset=0 min=0 max=10000 m=1 b=0 units="RPM" format=4.0 help="RPM Transition Counter" +EXTERN uint32 CAM_u32RPMTransitionCounter; +EXTERN uint32 CAM_u32EngineStoppedTimer; +//ASAM mode=readvalue name="Engine Stopped Timer" type=uint32 offset=0 min=0 max=10000 m=1 b=0 units="s" format=4.0 help="Engine Stopped Timer" + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void CAM_vStart(uint32 * const pu32Arg); +void CAM_vRun(uint32* const pu32Arg); +void CAM_vTerminate(uint32* const pu32Arg); +void CAM_vCallBack(puint32 const pu32Arg); +void CAM_vEngineSpeedCB(TEPMAPI_ttEventTime tEventTime); + +#endif // MAP_H + diff --git a/source/Client/CLO2.c b/source/Client/CLO2.c new file mode 100644 index 0000000..9013064 --- /dev/null +++ b/source/Client/CLO2.c @@ -0,0 +1,341 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: CLO2 */ +/* DESCRIPTION: This code module provides closed loop fuel functions */ +/* FILE NAME: CLO2.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _CLO2_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "CLO2.h" +#include "FUEL.h" + +/* LOCAL MACRO DEFINITIONS ****************************************************/ + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +uint32 CLO2_u32SensorStateBank[2]; +bool CLO2_boSensorState[2]; +uint32 CLO2_u32ReadyCount[2]; + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ + +/* LOCAL CONSTANT DEFINITIONS (STATIC) ****************************************/ + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ + +void CLO2_vInit(void) +{ + CLO2_u32STT[0] = 1000; + CLO2_u32STT[1] = 1000; + + CLO2_s32ISCESTTrim[0] = 0; + CLO2_s32ISCESTTrim[1] = 0; + + CLO2_au16AFRMeasured[0] = ~0; + CLO2_au16AFRMeasured[1] = ~0; + +#if 0 + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenEHIOType enEHIOType; + IOAPI_tenDriveStrength enDriveStrength; + uint32 u32Arg; + + /* Enable the Oxygen sensor bank 1 discrete input sensor type */ + enEHIOResource = CLO2_nOxBank1Pin; + enEHIOType = IOAPI_enDIOInput; + enDriveStrength = IOAPI_enStrong; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, &u32Arg); + + /* Enable the Oxygen sensor bank 2 discrete input sensor type */ + enEHIOResource = CLO2_nOxBank2Pin; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, &u32Arg); +#endif +} + +void CLO2_vFilterSensors(void) +{ +#if 0 + CLO2_boSensorState[0] = SETUP_vGetDigitalIO(CLO2_nOxBank1Pin); + + if (TRUE == CLO2_boSensorState[0]) + { + CLO2_u32SensorStateBank[0] = (7 * CLO2_u32SensorStateBank[0]) / 8; + } + else + { + CLO2_u32SensorStateBank[0] = (7 * CLO2_u32SensorStateBank[0] + 1000) / 8; + } + + CLO2_boSensorState[1] = SETUP_vGetDigitalIO(CLO2_nOxBank2Pin); + + if (TRUE == CLO2_boSensorState[1]) + { + CLO2_u32SensorStateBank[1] = (7 * CLO2_u32SensorStateBank[1]) / 8; + } + else + { + CLO2_u32SensorStateBank[1] = (7 * CLO2_u32SensorStateBank[1] + 1000) / 8; + } +#endif +} + +void CLO2_vRun(void) +{ + static bool aboSTTRichening[2]; + uint32 u32Temp; + uint32 u32SeqIDX; + bool boFuelCutActive = FALSE; + uint32 u32CLStep = TRUE == TPS_boThrottleClosed ? USERCAL_stRAMCAL.u32CLStepClosed : USERCAL_stRAMCAL.u32CLStepOpen; + uint32 u32CLInc = TRUE == TPS_boThrottleClosed ? USERCAL_stRAMCAL.u32CLIncClosed : USERCAL_stRAMCAL.u32CLIncOpen; + + /* Buffer the auto-tune diag variable */ + CLO2_u32AutoTuneVE = CLO2_au16AFRMeasured[0] + (FUEL_u16TAFR << 16); + + if ((0 != USERCAL_stRAMCAL.boUEGOCANPrimary) && + (EH_IO_Invalid == USERCAL_stRAMCAL.u16AFRADResource) && + (TRUE == SENSORS_aboCANUEGONewSample[0])) + { + CLO2_au16AFRMeasured[0] = SENSORS_au16CANAFR[0]; + SENSORS_aboCANUEGONewSample[0] = FALSE; + } + + if ((FALSE == USERCAL_stRAMCAL.u8CLO2Leftenable) && (FALSE == USERCAL_stRAMCAL.u8CLO2Leftenable)) + { + CLO2_u32STT[0] = 1000; + CLO2_u32STT[1] = 1000; + return; + } + + CLO2_u32ReadyCount[0] = (100000 > CLO2_u32ReadyCount[0]) && (0 < CAM_u32RPMRaw) ? + CLO2_u32ReadyCount[0] + 1 : CLO2_u32ReadyCount[0]; + CLO2_u32ReadyCount[1] = (100000 > CLO2_u32ReadyCount[1]) && (0 < CAM_u32RPMRaw) ? + CLO2_u32ReadyCount[1] + 1 : CLO2_u32ReadyCount[1]; + + for (u32SeqIDX = 0; u32SeqIDX < 8; u32SeqIDX++) + { + boFuelCutActive |= FUEL_aboSeqOverrunCutFlag[u32SeqIDX]; + } + + if (200 < CLO2_u32ReadyCount[0]) + { + if (((FUEL_u16TAFR < 1475) && (FUEL_u16TAFR > 1465)) && + (FALSE == boFuelCutActive)) + { + if (800 < CLO2_u32SensorStateBank[0]) + { + if ((TRUE == aboSTTRichening[0]) && (USERCAL_stRAMCAL.u32STTNegLimit < CLO2_u32STT[0])) CLO2_u32STT[0] -= u32CLStep; + + CLO2_u32STT[0] = USERCAL_stRAMCAL.u32STTNegLimit < CLO2_u32STT[0] ? CLO2_u32STT[0] - u32CLInc : CLO2_u32STT[0]; + aboSTTRichening[0] = FALSE; + } + else if (200 > CLO2_u32SensorStateBank[0]) + { + if ((FALSE == aboSTTRichening[0]) && (USERCAL_stRAMCAL.u32STTPosLimit > CLO2_u32STT[0])) CLO2_u32STT[0] += u32CLStep; + + CLO2_u32STT[0] = USERCAL_stRAMCAL.u32STTPosLimit > CLO2_u32STT[0] ? CLO2_u32STT[0] + u32CLInc : CLO2_u32STT[0]; + aboSTTRichening[0] = TRUE; + } + } + else + { + CLO2_u32STT[0] = 1000; + } + + /* If no CAN data yet then just set to neutral */ + SENSORS_u8CANSTT[0] = 0xff != SENSORS_u8CANSTT[0] ? SENSORS_u8CANSTT[0] : 0x80; + SENSORS_u8CANLTT[0] = 0xff != SENSORS_u8CANLTT[0] ? SENSORS_u8CANLTT[0] : 0x80; + } + + + if (200 < CLO2_u32ReadyCount[1]) + { + if (((FUEL_u16TAFR < 1475) && (FUEL_u16TAFR > 1465)) && + (FALSE == boFuelCutActive)) + { + if (800 < CLO2_u32SensorStateBank[1]) + { + if ((TRUE == aboSTTRichening[1]) && (USERCAL_stRAMCAL.u32STTNegLimit < CLO2_u32STT[1])) CLO2_u32STT[1] -= u32CLStep; + + CLO2_u32STT[1] = USERCAL_stRAMCAL.u32STTNegLimit < CLO2_u32STT[1] ? CLO2_u32STT[1] - u32CLInc : CLO2_u32STT[1]; + aboSTTRichening[1] = FALSE; + } + else if (200 > CLO2_u32SensorStateBank[1]) + { + if ((FALSE == aboSTTRichening[1]) && (USERCAL_stRAMCAL.u32STTPosLimit > CLO2_u32STT[1])) CLO2_u32STT[1] += u32CLStep; + + CLO2_u32STT[1] = USERCAL_stRAMCAL.u32STTPosLimit > CLO2_u32STT[1] ? CLO2_u32STT[1] + u32CLInc : CLO2_u32STT[1]; + aboSTTRichening[1] = TRUE; + } + } + else + { + CLO2_u32STT[1] = 1000; + } + + /* If no CAN data yet then just set to neutral */ + SENSORS_u8CANSTT[1] = 0xff != SENSORS_u8CANSTT[1] ? SENSORS_u8CANSTT[1] : 0x80; + SENSORS_u8CANLTT[1] = 0xff != SENSORS_u8CANLTT[1] ? SENSORS_u8CANLTT[1] : 0x80; + } + + +#ifdef BUILD_BSP_STT_CAN + const uint8_t au8BiasTable[256] = CLO2_nBiasTableData; + static bool aboSimRichening[2]; + volatile static uint8 au8STTLTT[2]; + volatile static uint8 au8Count[2]; + volatile static uint8 au8CountRichLimit[2]; + volatile static uint8 au8CountLeanLimit[2]; + static bool aboOutRich[2]; + static bool aboOutConfigured[2]; + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenEHIOType enEHIOType; + IOAPI_tenDriveStrength enDriveStrength; + uint32 u32Arg; + + + if ((0xff != SENSORS_u8CANSTT[0]) && (0xff != SENSORS_u8CANLTT[0])) + { + au8STTLTT[0] = 2 * SENSORS_u8CANSTT[0] + SENSORS_u8CANLTT[0]; + + au8CountRichLimit[0] = (au8BiasTable[au8STTLTT[0]]) / 15; + au8CountLeanLimit[0] = (256 - au8BiasTable[au8STTLTT[0]]) / 15; + + if (TRUE == aboSimRichening[0]) + { + if (++au8Count[0] > au8CountRichLimit[0]) + { + if ((TRUE == aboOutConfigured[0]) && + (FUEL_u16TAFR > 1465)) + { + SETUP_vSetDigitalIOLow(CLO2_nSwitchBank1Pin); + } + au8Count[0] = 0; + aboSimRichening[0] = FALSE; + } + } + else + { + if (++au8Count[0] > au8CountLeanLimit[0]) + { + if (TRUE == aboOutConfigured[0]) + { + SETUP_vSetDigitalIOHigh(CLO2_nSwitchBank1Pin); + } + + au8Count[0] = 0; + aboSimRichening[0] = TRUE; + } + } + } + + if ((0xff != SENSORS_u8CANSTT[1]) && (0xff != SENSORS_u8CANLTT[1])) + { + au8STTLTT[1] = 2 * SENSORS_u8CANSTT[1] + SENSORS_u8CANLTT[1]; + + au8CountRichLimit[1] = (au8BiasTable[au8STTLTT[1]]) / 15; + au8CountLeanLimit[1] = (256 - au8BiasTable[au8STTLTT[1]]) / 15; + + if (TRUE == aboSimRichening[1]) + { + if (++au8Count[1] > au8CountRichLimit[1]) + { + if ((TRUE == aboOutConfigured[1]) && + (FUEL_u16TAFR > 1465)) + { + SETUP_vSetDigitalIOLow(CLO2_nSwitchBank2Pin); + } + au8Count[1] = 0; + aboSimRichening[1] = FALSE; + } + } + else + { + if (++au8Count[1] > au8CountLeanLimit[1]) + { + if (TRUE == aboOutConfigured[1]) + { + SETUP_vSetDigitalIOHigh(CLO2_nSwitchBank2Pin); + } + + au8Count[1] = 0; + aboSimRichening[1] = TRUE; + } + } + } + + CLO2_u32STTAvg[0] = ((3 * CLO2_u32STTAvg[0]) / 4) + CLO2_u32STT[0] / 4; + CLO2_u32STTAvg[1] = ((3 * CLO2_u32STTAvg[1]) / 4) + CLO2_u32STT[1] / 4; + + CLO2_u32STTAvg[0] = CLO2_u32STT[0] > CLO2_u32STTAvg[0] ? CLO2_u32STTAvg[0] + 1 : CLO2_u32STTAvg[0]; + CLO2_u32STTAvg[1] = CLO2_u32STT[1] > CLO2_u32STTAvg[1] ? CLO2_u32STTAvg[1] + 1 : CLO2_u32STTAvg[1]; + + + if ((FALSE == aboOutConfigured[0]) && (TRUE == aboOutReady[0])) + { + enEHIOResource = CLO2_nSwitchBank1Pin; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, &u32Arg); + aboOutConfigured[0] = TRUE; + } + + if ((FALSE == aboOutConfigured[1]) && (TRUE == aboOutReady[1])) + { + enEHIOResource = CLO2_nSwitchBank2Pin; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, &u32Arg); + aboOutConfigured[1] = TRUE; + } +#endif + + if (TRUE == TPS_boThrottleClosed) + { + if (1000 < CLO2_u32STT[0]) + { + CLO2_s32ISCESTTrim[0] = + ~(((CLO2_u32STT[0] - 1000) * USERCAL_stRAMCAL.u32CLO2ESTTrimPos) / (1000 - USERCAL_stRAMCAL.u32STTPosLimit)); + } + else + { + CLO2_s32ISCESTTrim[0] = + (((1000 - CLO2_u32STT[0]) * USERCAL_stRAMCAL.u32CLO2ESTTrimNeg) / (1000 - USERCAL_stRAMCAL.u32STTNegLimit)); + } + } + else + { + CLO2_s32ISCESTTrim[0] = 0; + } + + if ((TRUE == TPS_boThrottleClosed) && (IAC_enClosedLoop == IAC_enControlState)) + { + if (CLO2_u32STTAvg[1] < CLO2_u32STT[1]) + { + u32Temp = (((CLO2_u32STT[1] - CLO2_u32STTAvg[1]) * USERCAL_stRAMCAL.u32CLO2ESTTrimPos) / 5); + u32Temp = USERCAL_stRAMCAL.u32CLO2ESTTrimPos < u32Temp ? USERCAL_stRAMCAL.u32CLO2ESTTrimPos : u32Temp; + CLO2_s32ISCESTTrim[1] = ~u32Temp; + } + else + { + u32Temp = (((CLO2_u32STTAvg[1] - CLO2_u32STT[1]) * USERCAL_stRAMCAL.u32CLO2ESTTrimNeg) / 5); + u32Temp = USERCAL_stRAMCAL.u32CLO2ESTTrimNeg < u32Temp ? USERCAL_stRAMCAL.u32CLO2ESTTrimNeg : u32Temp; + CLO2_s32ISCESTTrim[1] = u32Temp; + } + } + else + { + CLO2_s32ISCESTTrim[1] = 0; + } +} + +#endif //BUILD_USER + + + diff --git a/source/Client/CLO2.h b/source/Client/CLO2.h new file mode 100644 index 0000000..9590fd2 --- /dev/null +++ b/source/Client/CLO2.h @@ -0,0 +1,78 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: CLO2 Header File */ +/* DESCRIPTION: This code module provides closed loop fuel functions */ +/* FILE NAME: CLO2.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef CLO2_H +#define CLO2_H + +#include "IOAPI.h" +#include "types.h" +#include "SETUP.h" +#include "SENSORS.h" +#include "TPS.h" + + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _CLO2_C + #define EXTERN +#else + #define EXTERN extern +#endif + +#define CLO2_nBiasTableData \ +{\ +38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,\ +38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,\ +38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,\ +38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,\ +38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,\ +38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,\ +68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,\ +98,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128,\ +128,130,132,134,136,138,140,142,144,146,148,150,152,154,156,158,\ +158,160,162,164,166,168,170,172,174,176,178,180,182,184,186,188,\ +188,190,192,194,196,198,200,202,204,206,208,210,212,214,216,218,\ +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,\ +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,\ +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,\ +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,\ +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218} + + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +EXTERN uint32 CLO2_u32STTAvg[2]; +EXTERN uint32 CLO2_u32STT[2]; +//ASAM mode=readvalue name="STT Bank 1" type=uint32 offset=0 min=0 max=1500 m=1 b=0 units="dl" format=4.0 help="Short Term Trim Bank1" +//ASAM mode=readvalue name="STT Bank 2" type=uint32 offset=4 min=0 max=1500 m=1 b=0 units="dl" format=4.0 help="Short Term Trim Bank2" +EXTERN uint32 CLO2_u32LTT[2]; +EXTERN sint32 CLO2_s32ISCESTTrim[2]; +EXTERN uint16 CLO2_au16AFRMeasured[2]; +EXTERN uint16 CLO2_au16AFRDisplayMeasured[2]; +//ASAM mode=readvalue name="AFR Measured 1" type=uint16 offset=0 min=5 max=100 m=0.001 b=0 units="dl" format=4.2 help="Measured AFR Bank1" +//ASAM mode=readvalue name="AFR Measured 2" type=uint16 offset=2 min=5 max=100 m=0.001 b=0 units="dl" format=4.2 help="Measured AFR Bank2" +EXTERN uint32 CLO2_u32AutoTuneVE; +//ASAM mode=readvalue name="VE AUTOTUNE DIAG" type=uint32 offset=0 min=5 max=100 m=0.01 b=0 units="dl" format=4.2 help="Autotune VE Diag" + + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void CLO2_vInit(void); +void CLO2_vRun(void); +void CLO2_vFilterSensors(void); + + +#endif // CLO2_H + diff --git a/source/Client/CONV.c b/source/Client/CONV.c new file mode 100644 index 0000000..234f047 --- /dev/null +++ b/source/Client/CONV.c @@ -0,0 +1,149 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Conversion */ +/* DESCRIPTION: This code module provides data conversion functions */ +/* functions for the user application */ +/* FILE NAME: CONV.c */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/* */ +/* */ +/* */ +/******************************************************************************/ + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include + +#ifdef BUILD_USER + +#include "conv.h" + + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +GPM6_ttVolts CONV_tADCToVolts(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult) +{ + GPM6_ttVolts tVolts;/*CR1_17*/ + +#ifdef BUILD_SPARKDOG_PF + switch (enEHIOResource) + { + case EH_IO_GPSE1: + case EH_IO_GPSE2: + case EH_IO_GPSE3: + case EH_IO_GPSE4: + case EH_IO_GPSE5: + case EH_IO_GPSE7: + case EH_IO_GPSE8: + { + tVolts = USERCAL_stRAMCAL.userCalADRefH * u32ADCResult; + tVolts = (101 * tVolts) / (4095 * 50); + break; + } + case EH_IO_GPSE6: + { + tVolts = USERCAL_stRAMCAL.userCalADRefH * u32ADCResult; + tVolts = (144 * tVolts) / (4095 * 22); + break; + } + default: + { + tVolts = 0;/*CR1_17*/ + } + } +#endif //BUILD_SPARKDOG_PF + +#ifdef BUILD_SPARKDOG_TEENSY_ADAPT + switch (enEHIOResource) + { + case EH_IO_GPSE1: + case EH_IO_GPSE3: + case EH_IO_GPSE4: + case EH_IO_GPSE5: + case EH_IO_GPSE6: + case EH_IO_GPSE7: + case EH_IO_GPSE8: + case EH_IO_TMR15: + case EH_IO_TMR16: + { + tVolts = USERCAL_stRAMCAL.userCalADRefH * u32ADCResult; + tVolts = (101 * tVolts) / (4095 * 50); + break; + } + case EH_IO_GPSE2: + { + tVolts = USERCAL_stRAMCAL.userCalADRefH * u32ADCResult; + tVolts = (144 * tVolts) / (4095 * 22); + break; + } + case EH_IO_IIC1_SCL: + { + tVolts = (34u * USERCAL_stRAMCAL.userCalVRef445) / 33u + - (USERCAL_stRAMCAL.userCalADRefH * u32ADCResult) / (32000); + break; + } + case EH_IO_UART1_CTS: + { + tVolts = (220u * u32ADCResult) / 69888u; + break; + } + default: + { + tVolts = 0;/*CR1_17*/ + } + } +#endif //BUILD_SPARKDOG_TEENSY_ADAPT + + return tVolts; +} + +GPM6_ttOhms CONV_tADCToOhms(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult) +{ + GPM6_ttOhms Ohms; + + switch (enEHIOResource) + { + case EH_I_ADD1: + { + Ohms = 9 * (u32ADCResult + 8600); + break; + } + default: + { + Ohms = 0; + break; + } + } + + return Ohms; +} + +GPM6_ttOhms CONV_tVoltsAmpsToOhms(GPM6_ttVolts tVolts, GPM6_ttAmps tAmps)/*CR1_17*/ +{ + GPM6_ttOhms tOhms = GPM6_ttOhmsMAXVAL; + + if (0 != tAmps)/*CR1_20*/ + { + tOhms = (tVolts * 1000u) / tAmps;/*CR1_17*/ + } + + return tOhms; +} + +GPM6_ttAmps CONV_tOhmsVoltsToAmps(GPM6_ttOhms tOhms, GPM6_ttVolts tVolts)/*CR1_17*/ +{ + GPM6_ttAmps tAmps = GPM6_ttAmpsMAXVAL; + + if (0 != tOhms)/*CR1_20*/ + { + tAmps = (tVolts * 1000u) / tOhms;/*CR1_17*/ + } + + return tAmps; +} + +#endif //BUILD_USER diff --git a/source/Client/CONV.h b/source/Client/CONV.h new file mode 100644 index 0000000..4254ea7 --- /dev/null +++ b/source/Client/CONV.h @@ -0,0 +1,67 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Conversion Header File */ +/* DESCRIPTION: This code module provides data conversion functions */ +/* functions for the user application */ +/* FILE NAME: CONV.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#ifndef CONV_H +#define CONV_H + +#include +#include +#include +#include +#include +#include +#include "ioapi.h"/*CR1_94*/ +#include "units.h" + + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +/******************************************************************************* +* Interface : +* +* Implementation : +* +* Return Value : +*******************************************************************************/ +GPM6_ttVolts CONV_tADCToVolts(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult);/*CR1_1*/ + +/******************************************************************************* +* Interface : +* +* Implementation : +* +* Return Value : +*******************************************************************************/ +GPM6_ttOhms CONV_tVoltsAmpsToOhms(GPM6_ttVolts tVolts, GPM6_ttAmps tAmps);/*CR1_1*/ + +/******************************************************************************* +* Interface : +* +* Implementation : +* +* Return Value : +*******************************************************************************/ +GPM6_ttAmps CONV_tOhmsVoltsToAmps(GPM6_ttOhms tOhms, GPM6_ttVolts tVolts);/*CR1_1*/ + +/******************************************************************************* +* Interface : +* +* Implementation : +* +* Return Value : +*******************************************************************************/ +GPM6_ttOhms CONV_tADCToOhms(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult);/*CR1_67*/ + +#endif // CONV_H + diff --git a/source/Client/CTS.c b/source/Client/CTS.c new file mode 100644 index 0000000..d0dde2d --- /dev/null +++ b/source/Client/CTS.c @@ -0,0 +1,369 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Coolant Temperature */ +/* DESCRIPTION: This code module initialises the required ADC */ +/* resources and functions for coolant temperature */ +/* measurement */ +/* FILE NAME: CTS.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _CTS_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "CTS.h" +#include "RELAYS.h" + + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +bool CTS_boNewSample; +SPREADAPI_ttSpreadIDX CTS_tSpreadSensorIDX; +SPREADAPI_ttSpreadIDX CTS_tSpreadEnrichmentIDX; +SPREADAPI_ttSpreadIDX CTS_tSpreadStartEnrichmentIDX; +SPREADAPI_ttSpreadIDX CTS_tSpreadPostStartEnrichmentIDX; +SPREADAPI_ttSpreadIDX CTS_tSpreadPrimerIDX; +TABLEAPI_ttTableIDX CTS_tTableSensorIDX; +TABLEAPI_ttTableIDX CTS_tTableEnrichmentIDX; +TABLEAPI_ttTableIDX CTS_tTableStartEnrichmentIDX; +TABLEAPI_ttTableIDX CTS_tTablePostStartEnrichmentIDX; +TABLEAPI_ttTableIDX CTS_tTablePrimerIDX; + +sint32 CTS_i32Enrichment; +sint32 CTS_i32StartEnrichment; +sint32 CTS_i32PostStartEnrichment; +uint32 CTS_u32SampleCount; + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ +/******************************************************************************* +* Interface : CTS_vADCCallBack +* +* Implementation : Callback to receive the measured ADC value +* +* Parameter +* Par1 : enEHIOResource enum of the ADC resource +* Par2 : u32ADCResult the ADC conversion value +* +* Return Value : NIL +*******************************************************************************/ +static void CTS_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult); + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void CTS_vStart(puint32 const pu32Arg) +{ + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenEHIOType enEHIOType; + IOAPI_tenDriveStrength enDriveStrength; + CTS_u32ADCRaw = 0; + CTS_u32FuelMultiplier = 1000; + CTS_u32SampleCount = 0; + CTS_boNewSample = FALSE; + CTS_i32StartEnrichment = 1000; + CTS_i32StartEnrichmentScaled = 1000 * 1000; + CTS_i32PostStartEnrichmentScaled = 1000 * 1000; + + if (FALSE == USERCAL_stRAMCAL.boCTSCANPrimary) + { + /* Request and initialise the CTS ADC input channel */ + SETUP_boSetupADSE(USERCAL_stRAMCAL.u16CTSADResource, IOAPI_enADSE, ADCAPI_en32Samples, &CTS_vADCCallBack, ADCAPI_enTrigger2, pu32Arg); + } + + /* Request and initialise required Kernel managed spread for coolant sensor */ + CTS_tSpreadSensorIDX = SETUP_tSetupSpread((void*)&CTS_tSensorVolts, (void*)&USERCAL_stRAMCAL.aUserCoolantSensorSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for coolant sensor */ + CTS_tTableSensorIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserCoolantSensorTable, (void*)&CTS_tTempCRaw, TYPE_enInt32, 17, CTS_tSpreadSensorIDX, NULL); + + /* Request and initialise required Kernel managed spread for coolant enrichment */ + CTS_tSpreadEnrichmentIDX = SETUP_tSetupSpread((void*)&CTS_tTempCFiltered, (void*)&USERCAL_stRAMCAL.aUserCoolantEnrichmentSpread, TYPE_enInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for coolant enrichment */ + CTS_tTableEnrichmentIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserCoolantEnrichmentTable, (void*)&CTS_i32Enrichment, TYPE_enInt32, 17, CTS_tSpreadEnrichmentIDX, NULL); + + /* Request and initialise required Kernel managed spread for coolant starting enrichment */ + CTS_tSpreadStartEnrichmentIDX = SETUP_tSetupSpread((void*)&CTS_tTempCFiltered, (void*)&USERCAL_stRAMCAL.aUserCoolantStartEnrichmentSpread, TYPE_enInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for coolant starting enrichment */ + CTS_tTableStartEnrichmentIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserCoolantStartEnrichmentTable, (void*)&CTS_i32StartEnrichment, TYPE_enInt32, 17, CTS_tSpreadStartEnrichmentIDX, NULL); + + /* Request and initialise required Kernel managed spread for coolant post starting enrichment */ + CTS_tSpreadPostStartEnrichmentIDX = SETUP_tSetupSpread((void*)&CTS_tTempCFiltered, (void*)&USERCAL_stRAMCAL.aUserCoolantPostStartEnrichmentSpread, TYPE_enInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for coolant post starting enrichment */ + CTS_tTablePostStartEnrichmentIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserCoolantPostStartEnrichmentTable, (void*)&CTS_i32PostStartEnrichment, TYPE_enInt32, 17, CTS_tSpreadPostStartEnrichmentIDX, NULL); + + /* Request and initialise required Kernel managed spread for primer */ + CTS_tSpreadPrimerIDX = SETUP_tSetupSpread((void*)&CTS_tTempCFiltered, (void*)&USERCAL_stRAMCAL.aUserPrimerSpread, TYPE_enInt32, 11, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for primer */ + CTS_tTablePrimerIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserPrimerTable, (void*)&CTS_u32Primer, TYPE_enUInt32, 11, CTS_tSpreadPrimerIDX, NULL); + + /* Setup thermofan relay */ + if (EH_IO_Invalid != USERCAL_stRAMCAL.enThermoFanRelay) + { + enEHIOResource = USERCAL_stRAMCAL.enThermoFanRelay; + enEHIOType = IOAPI_enDIOOutput; + enDriveStrength = IOAPI_enWeak; + + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + SETUP_vSetDigitalIOLow(enEHIOResource); + } +} + +void CTS_vRun(puint32 const pu32Arg) +{ + uint32 u32Temp; + sint32 s32Temp; + IOAPI_tenTriState enTriState; + IOAPI_tenEHIOResource enEHIOResource; + RELAY_tenBit enBit; +#ifdef BUILD_CTS_PULLUP_SENSE + volatile static uint32 u32Delta; + static uint32 u32LowImpModeCount; + static uint32 u32HighImpModeCount; + static bool boHotMode; + static bool boColdMode; +#endif + static uint32 u32CANCTSMsgCount = 0; + static uint8 u8CANCTSOld = 0; + + + if ((TRUE == CTS_boNewSample) || (true == SENSORS_boCANCTSNewSample)) + { + CTS_u32SampleCount++; + + if (FALSE == USERCAL_stRAMCAL.boCTSCANPrimary) + { + USER_xEnterCritical();/*CR1_16*/ + (void)USERMATH_u16SinglePoleLowPassFilter16((uint16)CTS_u32ADCRaw, CTS_nADFiltVal, + &CTS_u32ADCFiltered); + CTS_boNewSample = FALSE; + USER_xExitCritical();/*CR1_16*/ + +#ifdef BUILD_CTS_PULLUP_SENSE + if ((FALSE == SENSORS_boCTSACBiasHigh) && ((0x100 * CTS_u32ADCRaw) > CTS_u32ADCFiltered)) + { + u32Temp = 0x100 * CTS_u32ADCRaw - CTS_u32ADCFiltered; + u32Delta = (u32Temp + 3 * u32Delta) / 4; + } + else if ((TRUE == SENSORS_boCTSACBiasHigh) && ((0x100 * CTS_u32ADCRaw) < CTS_u32ADCFiltered)) + { + u32Temp = CTS_u32ADCFiltered - 0x100 * CTS_u32ADCRaw; + u32Delta = (u32Temp + 3 * u32Delta) / 4; + } + + if (0 == CAM_u32RPMRaw) + { + if (10000 < u32Delta) + { + u32HighImpModeCount = 40 > u32HighImpModeCount ? u32HighImpModeCount + 1 : u32HighImpModeCount; + u32LowImpModeCount = 2 < u32LowImpModeCount ? u32LowImpModeCount - 2 : 0; + } + + if (7000 > u32Delta) + { + u32LowImpModeCount = 40 > u32LowImpModeCount ? u32LowImpModeCount + 1 : u32LowImpModeCount; + u32HighImpModeCount = 2 < u32HighImpModeCount ? u32HighImpModeCount - 2 : 0; + } + + boColdMode = 35 < u32HighImpModeCount; + boHotMode = 35 < u32LowImpModeCount; + } + else + { + if (15000 < u32Delta) + { + u32HighImpModeCount = 1000 > u32HighImpModeCount ? u32HighImpModeCount + 1 : u32HighImpModeCount; + u32LowImpModeCount = 2 < u32LowImpModeCount ? u32LowImpModeCount - 2 : 0; + } + + if (10000 > u32Delta) + { + u32LowImpModeCount = 1000 > u32LowImpModeCount ? u32LowImpModeCount + 1 : u32LowImpModeCount; + u32HighImpModeCount = 2 < u32HighImpModeCount ? u32HighImpModeCount - 2 : 0; + } + + boColdMode = 500 < u32HighImpModeCount; + boHotMode = 500 < u32LowImpModeCount; + } + + + if (((FALSE == boHotMode) && (FALSE == boColdMode)) || + ((TRUE == boHotMode) && (TRUE == boColdMode))) + { + return; + } + +#endif //BUILD_BSP_CTS_PULLUP_SENSE + + u32Temp = CTS_u32ADCFiltered * SENSORS_nADRefVolts; + u32Temp /= SENSORS_nADScaleMax; + u32Temp /= SENSORS_nVDivRatio; + CTS_tSensorVolts = u32Temp; + + /* Calculate the current spread for coolant sensor */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&CTS_tSpreadSensorIDX, + NULL, NULL); + + /* Lookup the current spread for coolant sensor */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&CTS_tTableSensorIDX, + NULL, NULL); + } + else + { + if (0xff != SENSORS_u8CANCTS) + { + CTS_tTempCRaw = 1000 * (sint32)(SENSORS_u8CANCTS - 40); + SENSORS_boCANCTSNewSample = FALSE; + + u32CANCTSMsgCount++; + + if ((3 < u32CANCTSMsgCount) && + (u8CANCTSOld == SENSORS_u8CANCTS) && + (0 != SENSORS_u8CANCTS)) + { + CTS_boCTSReady = TRUE; + } + else if (10 < u32CANCTSMsgCount) + { + CTS_boCTSReady = TRUE; + } + } + else + { + CTS_tTempCRaw = 0; + } + + u8CANCTSOld = SENSORS_u8CANCTS; + } + + + if (((0 == CAM_u32RPMRaw) && (10000 < BVM_tBattVolts)) || (TRUE == USERCAL_stRAMCAL.boCTSCANPrimary)) + { + /* If at key on but not cranking, or CAN data */ + CTS_tTempCFiltered = CTS_tTempCRaw; + } + else if (400 < CAM_u32RPMRaw) + { + if (CTS_tTempCRaw < CTS_tTempCFiltered) + { + CTS_tTempCFiltered -= 500; + } + else if (CTS_tTempCRaw > CTS_tTempCFiltered) + { + CTS_tTempCFiltered += 500; + CTS_tTempCFiltered = CTS_MAXVAL <= CTS_tTempCFiltered ? CTS_MAXVAL : CTS_tTempCFiltered; + } + } + + + /* Calculate the current spread for coolant enrichment */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&CTS_tSpreadEnrichmentIDX, + NULL, NULL); + + /* Lookup the current spread for coolant enrichment */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&CTS_tTableEnrichmentIDX, + NULL, NULL); + + + (void)BOOSTED_boIndexAndCalculateTable(CTS_tSpreadPrimerIDX, CTS_tTablePrimerIDX); + + +#ifdef BUILD_CTS_PULLUP_SENSE + if (TRUE == boHotMode) + { + CTS_tTempCFiltered = 60000; + } +#endif + + /* Decrease the enrichment linearly at higher rpm */ + if (1500 < CAM_u32RPMRaw) + { + u32Temp = 7500 - CAM_u32RPMRaw; + } + else + { + u32Temp = 6000; + } + + s32Temp = CTS_i32Enrichment - 1000; + s32Temp *= u32Temp; + s32Temp /= 6000; + s32Temp += 1000; + s32Temp *= (CTS_i32StartEnrichmentScaled / 1000); + s32Temp /= 1000; + s32Temp *= (CTS_i32PostStartEnrichmentScaled / 1000); + s32Temp /= 1000; + CTS_u32FuelMultiplier = (uint32)s32Temp; + + if ((50 < CTS_u32SampleCount) && (0 == CAM_u32RPMRaw)) + { + /* Calculate the current spread for starting coolant enrichment */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&CTS_tSpreadStartEnrichmentIDX, + NULL, NULL); + + /* Lookup the current spread for starting coolant enrichment */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&CTS_tTableStartEnrichmentIDX, + NULL, NULL); + + /* Calculate the current spread for post starting coolant enrichment */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&CTS_tSpreadPostStartEnrichmentIDX, + NULL, NULL); + + /* Lookup the current spread for post starting coolant enrichment */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&CTS_tTablePostStartEnrichmentIDX, + NULL, NULL); + + CTS_i32StartEnrichmentScaled = 1000 * CTS_i32StartEnrichment; + CTS_i32PostStartEnrichmentScaled = 1000 * CTS_i32PostStartEnrichment; + } + } + + CTS_boRadFanOn = USERCAL_stRAMCAL.s32RadFanOnTemp < CTS_tTempCFiltered ? TRUE : CTS_boRadFanOn; + CTS_boRadFanOn = USERCAL_stRAMCAL.s32RadFanOffTemp > CTS_tTempCFiltered ? FALSE : CTS_boRadFanOn; + + + if (EH_IO_Invalid != USERCAL_stRAMCAL.enThermoFanRelay) + { + enEHIOResource = USERCAL_stRAMCAL.enThermoFanRelay; + enTriState = TRUE == CTS_boRadFanOn ? IOAPI_enHigh : IOAPI_enLow; + + if (EH_IO_IIC1_SDA > enEHIOResource) + { + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, + (void*)&enTriState, (void*)NULL); + } + else + { + enBit = 1 << (enEHIOResource - EH_IO_IIC1_SDA); + RELAYS_vOutputBit(enBit, IOAPI_enHigh == enTriState); + } + } +} + +void CTS_vTerminate(puint32 const pu32Arg) +{ + +} + +void CTS_vCallBack(puint32 const pu32Arg) +{ + +} + +static void CTS_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult) +{ + CTS_u32ADCRaw = u32ADCResult; + CTS_boNewSample = TRUE; +} + + +#endif //BUILD_USER diff --git a/source/Client/CTS.h b/source/Client/CTS.h new file mode 100644 index 0000000..cd97f83 --- /dev/null +++ b/source/Client/CTS.h @@ -0,0 +1,62 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Coolant Temperature Header File */ +/* DESCRIPTION: This code module initialises the required ADC */ +/* resources and functions for coolant temperature */ +/* measurement */ +/* FILE NAME: CTS.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef CTS_H +#define CTS_H + +#include +#include "IOAPI.h" +#include "SENSORS.h" +#include "USER.h" + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define CTS_nADFiltVal (0x10) +#define CTS_nFanRelayOutput (RELAY_BIT0) + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _CTS_C + #define EXTERN +#else + #define EXTERN extern +#endif + +#define CTS_MAXVAL 130000 + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +EXTERN uint32 CTS_u32ADCRaw; +EXTERN uint32 CTS_u32ADCFiltered; +//ASAM mode=readvalue name="Coolant Sensor Filtered ADC" type=uint32 offset=0 min=0 max=1048575 m=1 b=0 units="counts" format=5.3 help="CTS Sensor ADC" +EXTERN GPM6_ttVolts CTS_tSensorVolts;/*CR1_88*/ +//ASAM mode=readvalue name="CTS Sensor Voltage" type=uint32 offset=0 min=0 max=5 m=0.001 b=0 units="V" format=3.2 help="CTS Sensor Voltage" +EXTERN GPM6_ttTempC CTS_tTempCRaw; +EXTERN GPM6_ttTempC CTS_tTempCFiltered; +//ASAM mode=readvalue name="Coolant Temperature" type=uint32 offset=0 min=0 max=200 m=0.001 b=0 units="degrees C" format=4.1 help="Coolant Temperature" +EXTERN uint32 CTS_u32Primer; +//ASAM mode=readvalue name="Primer" type=uint32 offset=0 min=0 max=200 m=0.001 b=0 units="us" format=4.1 help="Start Primer" +EXTERN uint32 CTS_u32FuelMultiplier; +EXTERN sint32 CTS_i32StartEnrichmentScaled; +EXTERN sint32 CTS_i32PostStartEnrichmentScaled; +EXTERN bool CTS_boCTSReady; +EXTERN bool CTS_boRadFanOn; + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void CTS_vStart(uint32 * const pu32Arg); +void CTS_vRun(uint32* const pu32Arg); +void CTS_vTerminate(uint32* const pu32Arg); +void CTS_vThread(void); +void CTS_vCallBack(puint32 const pu32Arg); + +#endif // CTS_H + diff --git a/source/Client/DIAG.c b/source/Client/DIAG.c new file mode 100644 index 0000000..206f747 --- /dev/null +++ b/source/Client/DIAG.c @@ -0,0 +1,801 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Diagnostics */ +/* DESCRIPTION: This code module initialises the required comms */ +/* resources for and provides functions for diagnostics */ +/* FILE NAME: DIAG.c */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _USERDIAG_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "diag.h" +#include "PERUART.h" + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +const USERDIAG_tstIdentifierIB USERDIAG_rastIdentifierIB[] = USER_DIAG_nCIDInfo; +DIAGAPI_tenDiagSecurityLevel USERDIAG_enSecLevel; +uint32 USERDIAG_u32GlobalTimeTick; +//ASAM mode=readvalue name="DIAGGlobalTimeTick" type=uint32 offset=0 min=0 max=10000 m=1 b=0 units="dl" format=6.0 help="Data Logging Global Time Tick" +puint8 USERDIAG_pu8Mode1Data; +puint8 USERDIAG_pu8Mode2Data; +puint8 USERDIAG_pu8Mode3Data; +puint8 USERDIAG_pu8Mode4Data; +puint8 USERDIAG_pu8Mode6Data; +puint8 USERDIAG_pu8Mode7Data; +uint16 USERDIAG_rau16Mode1DataOffsets[MODE1_PIDS_COUNT] = USERDIAG_nMode1PIDOffsets; +const uint8 USERDIAG_rau8Codes648[] = USERDIAG_nCodes648; +const uint8 USERDIAG_rau8Codes1152[] = USERDIAG_nCodes1152; + +CQUEUE_tstQueue* DIAG_pstUARTQueue; +uint8* DIAG_pu8UARTBuffer; + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ +/******************************************************************************* +* Interface : DIAG_vNTOH +* +* Implementation : Network to Host data endianness conversion +* +* Parameter +* Par1 : Pointer to the data +* Par2 : Datacount +* Par3 : Datasize in bytes +* +* Return Value : Nil +*******************************************************************************/ +static void DIAG_vNTOH(puint8 pu8Data, uint8 u8DataCount, uint8 u8DataSize); +static SPREADAPI_ttSpreadIDX USERDIAG_stGetSpreadIDX(puint8 pu8Data); + +/* TODO +static void USERDIAG_vSnapShot(uint16); +*/ + +/******************************************************************************* +* Interface : USERDIAG_i16GetCIDParamAddress +* +* Implementation : Serach for the index of a CID within a CID info table +* +* Parameter +* Par1 : The CID being searched for +* +* Return Value : Index of the found data, -1 for failed to find +*******************************************************************************/ +static sint16 USERDIAG_i16GetCIDParamAddress(uint16); + + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void USERDIAG_vStart(puint32 const pu32Arg) +{ + IOAPI_tenEHIOType enEHIOType; + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tstPortConfigCB stPortConfigCB; + DIAGAPI_tenCallBackType enCallBackType; + uint32 u32DiagSpreadsIDX; + + USERDIAG_u32GlobalTimeTick = 0; + DIAG_u8EngagedGearReport = 255; + + BOOSTED_vResetSVCResult(); + + for (u32DiagSpreadsIDX = 0; u32DiagSpreadsIDX < DIAG_nSPREADSRECORDSMAX; u32DiagSpreadsIDX++) + { + DIAG_astIDXAddressPairs[u32DiagSpreadsIDX].pData = NULL; + DIAG_astIDXAddressPairs[u32DiagSpreadsIDX].tSpreadIDX = ~0; + } + + for (u32DiagSpreadsIDX = 0; u32DiagSpreadsIDX < DIAG_nSPREADSMAX; u32DiagSpreadsIDX++) + { + DIAG_apu8SpreadTableAddresses[DIAG_nSPREADSMAX] = NULL; + } + + +#ifdef USERDIAG_nEnableUART + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + /* Setup the USERDIAG UART resources */ + enEHIOResource = EH_VIO_UART1; + + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, NULL, NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stPortConfigCB.enPortMode = IOAPI_enPortComms; + stPortConfigCB.u32BaudRateHz = USERDIAG_nUARTFrequency; + stPortConfigCB.enVIOResource = EH_VIO_UART1; + stPortConfigCB.stPinConfig.uPinInfo.stUARTPinInfo.enRXPin = EH_IO_UART1_RX; + stPortConfigCB.stPinConfig.uPinInfo.stUARTPinInfo.enTXPin = EH_IO_UART1_TX; + stPortConfigCB.stPinConfig.uPinInfo.stUARTPinInfo.enRTSPin = EH_IO_Invalid; + stPortConfigCB.stPinConfig.uPinInfo.stUARTPinInfo.enCTSPin = EH_IO_Invalid; + stPortConfigCB.enLLProtocol = PROTAPI_enLLNone; + stPortConfigCB.enNLProtocol = PROTAPI_enNLNone; + stPortConfigCB.enTLProtocol = PROTAPI_enTLNone; + stPortConfigCB.pfRXTransferCB = NULL; + stPortConfigCB.pfTXTransferCB = NULL; + enEHIOType = IOAPI_enUARTBus; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stPortConfigCB); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + enCallBackType = DIAGAPI_enDataWriteCB; + USER_vSVC(SYSAPI_enSetDiagCallback, (void*)&enCallBackType, (void*)USERDIAG_boWriteDataCallBack, NULL); + } + } + + /* Let's not TX in interrupt mode */ + UARTHA_vDisableTXInterrupt(enEHIOResource); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + USER_vSVC(SYSAPI_enGetByteQueue, (void*)&enEHIOResource, NULL, NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + DIAG_pstUARTQueue = (CQUEUE_tstQueue*)pstSVCDataStruct->pvArg1; + } + } + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + USER_vSVC(SYSAPI_enGetByteQueueBuffer, (void*)&enEHIOResource, NULL, NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + DIAG_pu8UARTBuffer = (uint8*)((CQUEUE_tstQueue*)pstSVCDataStruct->pvArg1); + } + } + } +#endif + +#ifdef USERDIAG_nEnableCAN + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + /* Setup the USERDIAG CAN resources */ + enEHIOResource = EH_VIO_CAN1; + + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, NULL, NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stPortConfigCB.enPortMode = IOAPI_enPortComms; + stPortConfigCB.u32BaudRateHz = USERDIAG_nCAN1Frequency; + stPortConfigCB.enVIOResource = EH_VIO_CAN1; + stPortConfigCB.stPinConfig.uPinInfo.stCANPinInfo.enRXPin = EH_IO_CAN1R; + stPortConfigCB.stPinConfig.uPinInfo.stCANPinInfo.enTXPin = EH_IO_CAN1T; + stPortConfigCB.stNetConfig.uNetInfo.stCANNetInfo.u32GlobalCANDiagAddress = 0x7df; + stPortConfigCB.stNetConfig.uNetInfo.stCANNetInfo.u32CANDiagAddress = 0x7e0; + stPortConfigCB.stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityAddress[0] = 80; + stPortConfigCB.stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityAddress[1] = 1440; + stPortConfigCB.stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityAddress[2] = 1088; + stPortConfigCB.stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityAddress[3] = 428; + stPortConfigCB.stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityMask[0] = 0x7ff; + stPortConfigCB.stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityMask[1] = 0x7ff; + stPortConfigCB.stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityMask[2] = 0x7ff; + stPortConfigCB.stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityMask[3] = 0x7ff; + stPortConfigCB.enLLProtocol = PROTAPI_enLLCAN11; + stPortConfigCB.enNLProtocol = PROTAPI_enISO15765; + stPortConfigCB.enTLProtocol = PROTAPI_enTLUDS; + stPortConfigCB.pfRXTransferCB = NULL; + stPortConfigCB.pfTXTransferCB = NULL; + enEHIOType = IOAPI_enCANBus; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stPortConfigCB); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + enCallBackType = DIAGAPI_enDataWriteCB; + USER_vSVC(SYSAPI_enSetDiagCallback, (void*)&enCallBackType, (void*)USERDIAG_boWriteDataCallBack, NULL); + } + } + } +#endif + + +#ifdef USERDIAG_nEnableUSB +if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) +{ + /* Setup the USERDIAG USB resources */ + enEHIOResource = EH_VIO_USB; + + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, NULL, NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stPortConfigCB.enPortMode = IOAPI_enPortComms; + stPortConfigCB.enVIOResource = EH_VIO_USB; + stPortConfigCB.enLLProtocol = PROTAPI_enUSB; + stPortConfigCB.enNLProtocol = PROTAPI_enISO15765; + stPortConfigCB.enTLProtocol = PROTAPI_enTLUDS; + stPortConfigCB.pfRXTransferCB = NULL; + stPortConfigCB.pfTXTransferCB = NULL; + enEHIOType = IOAPI_enUSBChannel; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stPortConfigCB); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + enCallBackType = DIAGAPI_enDataWriteCB; + USER_vSVC(SYSAPI_enSetDiagCallback, (void*)&enCallBackType, (void*)USERDIAG_boWriteDataCallBack, NULL); + } + } + + USERDIAG_pu8Mode1Data = NULL; + USERDIAG_pu8Mode2Data = NULL; + USERDIAG_pu8Mode3Data = NULL; + USERDIAG_pu8Mode4Data = NULL; + USERDIAG_pu8Mode6Data = NULL; + USERDIAG_pu8Mode7Data = NULL; + + USER_vSVC(SYSAPI_enGetMode1Buffer, NULL, NULL, NULL); + USERDIAG_pu8Mode1Data = pstSVCDataStruct->pvArg1; + + if (NULL != USERDIAG_pu8Mode1Data) + { + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_Supported1]] = 0xff; + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_Supported1] + 1] = 0xff; + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_Supported1] + 2] = 0xff; + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_Supported1] + 3] = 0xff; + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_Mode1Supported2]] = 0xff; + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_Mode1Supported2] + 1] = 0xff; + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_Mode1Supported2] + 2] = 0xff; + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_Mode1Supported2] + 3] = 0xff; + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_Mode1Supported3]] = 0xff; + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_Mode1Supported3] + 1] = 0xff; + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_Mode1Supported3] + 2] = 0xff; + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_Mode1Supported3] + 3] = 0xff; + } +} +#endif + +#ifdef USERDIAG_nEnableENET + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + /* Setup the USERDIAG ENET resources */ + enEHIOResource = EH_VIO_ENET_CH1; + + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, NULL, NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stPortConfigCB.enPortMode = IOAPI_enPortComms; + stPortConfigCB.enVIOResource = EH_VIO_ENET_CH1; + stPortConfigCB.enLLProtocol = PROTAPI_enLL802_3; + stPortConfigCB.enNLProtocol = PROTAPI_enISO15765_IP; + stPortConfigCB.enTLProtocol = PROTAPI_enTLUDS_UDP; + stPortConfigCB.stNetConfig.uNetInfo.stLANNetInfo.u16RPCREQSourcePort = USERDIAG_nRPCUDSREQSourcePort; + stPortConfigCB.stNetConfig.uNetInfo.stLANNetInfo.u16RPCREQDestPort = USERDIAG_nRPCUDSREQDestPort; + stPortConfigCB.pfRXTransferCB = NULL; + stPortConfigCB.pfTXTransferCB = NULL; + enEHIOType = IOAPI_enENETChannel; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stPortConfigCB); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + enCallBackType = DIAGAPI_enDataWriteCB; + USER_vSVC(SYSAPI_enSetDiagCallback, (void*)&enCallBackType, (void*)USERDIAG_boWriteDataCallBack, NULL); + } + } + } +#endif +} + +void USERDIAG_vRun(puint32 const pu32Arg) +{ + static uint32 u32SpreadIDX; + SPREADAPI_ttSpreadIDX tSpreadIDX; + SPREADAPI_tstSpreadResult* pstSpreadResult; + PROTAPI_tstCANMsg stCANMsg; + IOAPI_tenEHIOResource enEHIOResource; + static uint8 u8Counter10; + static uint8 u8Counter20; + static uint8 u8Counter1000; + static uint8 u8UARTSeq; + uint32 u32Temp; + uint8 u8Temp; + static uint8 u8UARTChecksum; + static uint8 au8UARTInBuffer[4]; + + USERDIAG_u32GlobalTimeTick++; + + if (DIAG_nSPREADSMAX > u32SpreadIDX) + { + if (NULL != DIAG_apu8SpreadTableAddresses[u32SpreadIDX]) + { + tSpreadIDX = USERDIAG_stGetSpreadIDX(DIAG_apu8SpreadTableAddresses[u32SpreadIDX]); + + if (-1 != tSpreadIDX) + { + pstSpreadResult = BOOSTED_pstGetSpread(tSpreadIDX); + DIAG_astSpreadResult[u32SpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex = pstSpreadResult->uSpreadData.stSpreadResult.u16SpreadIndex; + DIAG_astSpreadResult[u32SpreadIDX].uSpreadData.stSpreadResult.u16SpreadOffset = pstSpreadResult->uSpreadData.stSpreadResult.u16SpreadOffset; + } + else + { + /* Just copy the raw uint32 data because this is not a spread */ + DIAG_astSpreadResult[u32SpreadIDX].uSpreadData.u32Data = *(uint32*)DIAG_apu8SpreadTableAddresses[u32SpreadIDX]; + } + } + + u32SpreadIDX++; + } + else + { + u32SpreadIDX = 0; + } + + if (NULL != USERDIAG_pu8Mode1Data) + { + switch (USERDIAG_u32GlobalTimeTick % 10) + { + case 0: + { + + + break; + } + + + case 1: + { + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_RPM]] = (4 * CAM_u32RPMRaw) / 0x100; + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_RPM] + 1] = (4 * CAM_u32RPMRaw) & 0xff; + + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_IAT]] = (uint8)(((sint32)40000 + ATS_tTempCFiltered) / 1000); + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_ECT]] = (uint8)(((sint32)40000 + CTS_tTempCFiltered) / 1000); + + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_TPS]] = (uint8)(TPS_tThetaFiltered / 352); + + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_MAP]] = (uint8)(MAP_tKiloPaFiltered / 1000); + + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_IgnAdvance]] = (uint8)((EST_tIgnitionAdvanceMtheta / 500) + 128); + + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_CalcEngineLoad]] = (uint8)(((MAP_tKiloPaFiltered / 1000) * CAM_u32RPMRaw) / 10000); + + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_STT_Bank1]] = (uint8)(3 + (CLO2_u32STT[0] / 8)); + + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_STT_Bank2]] = (uint8)(3 + (CLO2_u32STT[1] / 8)); + + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_LTT_Bank1]] = 0x80; + + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_LTT_Bank2]] = 0x80; + + USERDIAG_pu8Mode1Data[USERDIAG_rau16Mode1DataOffsets[MODE1_FuelPressure]] = (uint8)(USERCAL_stRAMCAL.u16ReturnlessPressureKPa / 33); + + break; + } + } + } + + if ((2 == (USERDIAG_u32GlobalTimeTick % 10)) && (TRUE == DIAG_u8PowerModeActive)) + { + /* 10 millisecond group */ + stCANMsg.u8DLC = 8; + stCANMsg.u32ID = 640; + + if (400 > CAM_u32RPMFiltered) + { + stCANMsg.u32DWH = 0x01000000; + stCANMsg.u32DWL = 0; + + u32Temp = TPS_tThetaFiltered / 300; + stCANMsg.u32DWL |= u32Temp; + stCANMsg.u32DWL |= (u32Temp << 24); + u32Temp = TPS_tThetaFiltered / 251; + stCANMsg.u32DWL |= (u32Temp << 8); + + if (6000 < TPS_tThetaFiltered) + { + u32Temp = (TPS_tThetaFiltered - 6000) / 100; + stCANMsg.u32DWL |= (u32Temp << 16); + stCANMsg.u32DWH &= 0x00ffffff; + } + + DIAG_u8PedalPositionReport = (TPS_tThetaFiltered - 6000) / 100; + } + else + { + stCANMsg.u32DWH = 0x01000000 + (((CAM_u32RPMFiltered * 4) % 0x100) << 8) + (CAM_u32RPMFiltered * 4) / 0x100; + stCANMsg.u32DWL = 0; + stCANMsg.u32DWH |= ((TORQUE_u32OutputTorqueModified & 0xff) << 16); + + DIAG_u8PedalPositionReport = TORQUE_u32TorquePedalEstimateScaled / 100; + + stCANMsg.u32DWL |= (TORQUE_u32OutputTorqueEstimate & 0xff); + stCANMsg.u32DWL |= ((TORQUE_u32OutputTorqueEstimate & 0xff) << 24); + stCANMsg.u32DWL |= ((TORQUE_u32IdleStabilisationTorque & 0xff) << 8); + + u32Temp = DIAG_u8PedalPositionReport; + stCANMsg.u32DWL |= (u32Temp << 16); + + if (6000 < TPS_tThetaFiltered) + { + stCANMsg.u32DWH &= 0x00ffffff; + } + } + + enEHIOResource = EH_VIO_CAN1; + USER_vSVC(SYSAPI_enQueueCANMessage, (void*)&enEHIOResource, (void*)&stCANMsg, (void*)NULL);/*CR1_12*/ + + stCANMsg.u8DLC = 8; + stCANMsg.u32ID = 896; + stCANMsg.u32DWL = 0x0000fe00; + stCANMsg.u32DWH = 0x20830000; + USER_vSVC(SYSAPI_enQueueCANMessage, (void*)&enEHIOResource, (void*)&stCANMsg, (void*)NULL);/*CR1_12*/ + + stCANMsg.u8DLC = 8; + stCANMsg.u32ID = 1160; + + if (28800 < MAP_tKiloPaFiltered) + { + if (174500 > MAP_tKiloPaFiltered) + { + u32Temp = ((MAP_tKiloPaFiltered - 28800) / 573) << 8; + u32Temp = u32Temp | ((u32Temp) << 8); + } + else + { + u32Temp = 0xfefe00; + } + } + else + { + u32Temp = 0; + } + + u32Temp |= ((u8Counter10 << 28) + 126); + stCANMsg.u32DWH = u32Temp; + + stCANMsg.u32DWL = 0xfeffff00; + USER_DIAG_APPEND_XOR(); + USER_vSVC(SYSAPI_enQueueCANMessage, (void*)&enEHIOResource, (void*)&stCANMsg, (void*)NULL);/*CR1_12*/ + + u8Counter10 = (u8Counter10 + 1) % 0x10; + } + + if ((6 == (USERDIAG_u32GlobalTimeTick % 20)) && (TRUE == DIAG_u8PowerModeActive)) + { + /* 20 millisecond group */ + stCANMsg.u8DLC = 8; + stCANMsg.u32ID = 866; + stCANMsg.u32DWH = (u8Counter20 << 24) + 166; + stCANMsg.u32DWL = 0xfe000000; + enEHIOResource = EH_VIO_CAN1; + + if (8 <= u8Counter20) + { + stCANMsg.u32DWL += (u8Counter20 + 72); + } + else + { + stCANMsg.u32DWL += (u8Counter20 + 88); + } + + USER_vSVC(SYSAPI_enQueueCANMessage, (void*)&enEHIOResource, (void*)&stCANMsg, (void*)NULL);/*CR1_12*/ + + stCANMsg.u32ID = 644; + stCANMsg.u8DLC = 6; + stCANMsg.u32DWL = 0; + stCANMsg.u32DWH = (u8Counter20 << 24) + (u8Counter20 << 16); + USER_vSVC(SYSAPI_enQueueCANMessage, (void*)&enEHIOResource, (void*)&stCANMsg, (void*)NULL);/*CR1_12*/ + + stCANMsg.u8DLC = 8; + stCANMsg.u32ID = 648; + + stCANMsg.u32DWH = USERDIAG_rau8Codes648[u8Counter20] << 24; + stCANMsg.u32DWH |= ((32 << 8) + 6); + + if (0 <= CTS_tTempCFiltered) + { + u32Temp = CTS_tTempCFiltered / 500; + stCANMsg.u32DWH |= (u32Temp << 16); + } + + if (TRUE == SENSORS_boBrakePedalPressed) + { + stCANMsg.u32DWH |= 0x0300; + } + + stCANMsg.u32DWL = (76 << 16) + ((TORQUE_u32TorqueModelEstimateScaled & 0xff) << 8) + + TORQUE_u32TorqueModelEstimateScaled / 0x100; + + USER_vSVC(SYSAPI_enQueueCANMessage, (void*)&enEHIOResource, (void*)&stCANMsg, (void*)NULL);/*CR1_12*/ + + stCANMsg.u32ID = 1152; + stCANMsg.u32DWH = USERDIAG_rau8Codes1152[u8Counter20] << 24; + stCANMsg.u32DWH |= (44 << 16); + stCANMsg.u32DWL = (24 << 24) + (4 << 8); + USER_DIAG_APPEND_XOR(); + USER_vSVC(SYSAPI_enQueueCANMessage, (void*)&enEHIOResource, (void*)&stCANMsg, (void*)NULL);/*CR1_12*/ + + stCANMsg.u32ID = 1162; + stCANMsg.u32DWL = u8Counter20 << 4; + stCANMsg.u32DWH = (u8Counter20 << 28) + (2 << 24) + 2; + USER_vSVC(SYSAPI_enQueueCANMessage, (void*)&enEHIOResource, (void*)&stCANMsg, (void*)NULL);/*CR1_12*/ + + stCANMsg.u32ID = 1416; + stCANMsg.u32DWH = (232 << 24) + (60 << 16) + (127 << 8) + 135; + stCANMsg.u32DWL = (52 << 24) + 153; + USER_vSVC(SYSAPI_enQueueCANMessage, (void*)&enEHIOResource, (void*)&stCANMsg, (void*)NULL);/*CR1_12*/ + + u8Counter20 = (u8Counter20 + 1) % 0x10; + } + + if ((8 == (USERDIAG_u32GlobalTimeTick % 1000)) && (TRUE == DIAG_u8PowerModeActive)) + { + stCANMsg.u8DLC = 8; + stCANMsg.u32ID = 1408; + stCANMsg.u32DWH = u8Counter1000 << 24; + stCANMsg.u32DWL = 0; + enEHIOResource = EH_VIO_CAN1; + u8Counter1000 = (u8Counter1000 + 1) % 0x10; + USER_vSVC(SYSAPI_enQueueCANMessage, (void*)&enEHIOResource, (void*)&stCANMsg, (void*)NULL);/*CR1_12*/ + } + + + + /* UART data */ + else if (19 == (USERDIAG_u32GlobalTimeTick % 64)) + { + u8Temp = 0x3f & USERCAL_stRAMCAL.u8DBSlaveConfig; + UARTHA_vSendChar(EH_VIO_UART1, u8Temp + u8UARTSeq); + u8UARTChecksum += (u8Temp + u8UARTSeq); + u8UARTSeq -= 0x40; + } + else if (27 == (USERDIAG_u32GlobalTimeTick % 64)) + { + u8Temp = 0x3f & TORQUE_u16ETCScale; + UARTHA_vSendChar(EH_VIO_UART1, u8Temp + u8UARTSeq); + u8UARTChecksum += (u8Temp + u8UARTSeq); + u8UARTSeq -= 0x40; + } + else if (35 == (USERDIAG_u32GlobalTimeTick % 64)) + { + switch (USERCAL_stRAMCAL.u16DiagType) + { + case 0: + { + if (0x1234 == USERCAL_stRAMCAL.u16ETCOverrideKeys) + { + u8Temp = (uint8)USERCAL_stRAMCAL.u16ETCOverride; + } + else if ((0 != TORQUE_u16GearShiftCount) && (TRUE == TORQUE_boDownShift)) + { + u8Temp = (TORQUE_u16RevMatchRPM - 800) / 300; + } + else + { + if (100000 > MAP_tKiloPaFiltered)//todo chatters here + { + u8Temp = 0x3f & IAC_u8SlaveTarget; + } + else + { + u8Temp = MAP_u8PressureThrottleTrim; + } + } + + break; + } + case 1: + { + if (0 != CAM_u32RPMFiltered) + { + u8Temp = 0x3f & IAC_u8SlaveTarget; + } + else + { + /* ISC neutral point */ + u8Temp = 0x18; + } + + break; + } + default: + { + u8Temp = 0; + break; + } + } + + UARTHA_vSendChar(EH_VIO_UART1, u8Temp + u8UARTSeq); + u8UARTChecksum += (u8Temp + u8UARTSeq); + u8UARTSeq -= 0x40; + } + else if (43 == (USERDIAG_u32GlobalTimeTick % 64)) + { + UARTHA_vSendChar(EH_VIO_UART1, u8UARTSeq + (0x3f & u8UARTChecksum)); + u8UARTChecksum = 0; + u8UARTSeq = 0xc0; + } + + + + + if (FALSE == CQUEUE_xIsEmpty(DIAG_pstUARTQueue)) + { + uint8 u8Temp = DIAG_pu8UARTBuffer[DIAG_pstUARTQueue->u32Tail]; + CQUEUE_xRemoveItem(DIAG_pstUARTQueue); + + au8UARTInBuffer[3 - (u8Temp >> 6)] = u8Temp; + + if (0xc0 == (u8Temp & 0xc0)) + { + u8Temp = au8UARTInBuffer[1]; + u8Temp += au8UARTInBuffer[2]; + u8Temp += au8UARTInBuffer[3]; + + if (au8UARTInBuffer[1] == (u8Temp & 0x3f)) + { + + + } + } + } +} + +/* TODO +static void USERDIAG_vSnapShot(uint16 u16FreezeDTC) +{ + memcpy(USERDIAG_pu8Mode2Data, USERDIAG_pu8Mode1Data, USERDIAG_nMode1BufferSize); + USERDIAG_pu8Mode2Data[USERDIAG_rau16Mode1DataOffsets[MODE1_FreezeDTC]] = u16FreezeDTC / 0x100; + USERDIAG_pu8Mode2Data[USERDIAG_rau16Mode1DataOffsets[MODE1_FreezeDTC] + 1] = u16FreezeDTC / 0x100; +} +*/ + +static SPREADAPI_ttSpreadIDX USERDIAG_stGetSpreadIDX(puint8 pu8Data) +{ + SPREADAPI_ttSpreadIDX tSpreadIDX = -1; + uint32 u32AddressPairIDX; + + for (u32AddressPairIDX = 0; u32AddressPairIDX < DIAG_nSPREADSRECORDSMAX; u32AddressPairIDX++) + { + if (pu8Data == DIAG_astIDXAddressPairs[u32AddressPairIDX].pData) + { + tSpreadIDX = DIAG_astIDXAddressPairs[u32AddressPairIDX].tSpreadIDX; + break; + } + } + + return tSpreadIDX; +} + +void USERDIAG_vAddIDXAddressPair(USERDIAG_tstSpreadIDXAddressPair* pstSpreadIDXAddressPair) +{ + uint32 u32DiagSpreadsIDX; + + for (u32DiagSpreadsIDX = 0; u32DiagSpreadsIDX < DIAG_nSPREADSRECORDSMAX; u32DiagSpreadsIDX++) + { + if (NULL == DIAG_astIDXAddressPairs[u32DiagSpreadsIDX].pData) + { + DIAG_astIDXAddressPairs[u32DiagSpreadsIDX].pData = pstSpreadIDXAddressPair->pData; + DIAG_astIDXAddressPairs[u32DiagSpreadsIDX].tSpreadIDX = pstSpreadIDXAddressPair->tSpreadIDX; + break; + } + } +} + + +void USERDIAG_vTerminate(puint32 const pu32Arg) +{ + +} + +void USERDIAG_vCallBack(uint32* const pu32Arg) +{ + +} + +DIAGAPI_tenCBResult USERDIAG_boReadDataCallBack(uint16 u16CID, puint8 pu8Data, uint8 u8DataCount) +{ + return DIAGAPI_enCBOK;/*CR1_25*/ +} + +DIAGAPI_tenCBResult USERDIAG_boWriteDataCallBack(uint16 u16CID, puint8 pu8Data, uint8 u8DataCount) +{ + sint16 i16CIDIDX; + DIAGAPI_tenCBResult enCBResult = DIAGAPI_enRWGenFail; + + i16CIDIDX = USERDIAG_i16GetCIDParamAddress(u16CID); + + if (-1 != i16CIDIDX) + { + if (USERDIAG_enSecLevel >= USERDIAG_rastIdentifierIB[i16CIDIDX].enSecLevel) + { + DIAG_vNTOH(pu8Data, u8DataCount, USERDIAG_rastIdentifierIB[i16CIDIDX].u8DataSize); + memcpy((void*)USERDIAG_rastIdentifierIB[i16CIDIDX].pu8Data, + (void*)pu8Data, USERDIAG_rastIdentifierIB[i16CIDIDX].u8DataCount); + enCBResult = DIAGAPI_enCBOK; + } + else + { + enCBResult = DIAGAPI_enRWSecurityError; + } + } + else + { + enCBResult = DIAGAPI_enRWParamNotFound; + } + + return enCBResult; +} + +DIAGAPI_tenCBResult USERDIAG_boRoutineControl(DIAGAPI_tenRoutineAction enRoutineAction, puint8 pu8Data, uint8 u8DataCount) +{ + return DIAGAPI_enCBOK;/*CR1_25*/ +} + +static sint16 USERDIAG_i16GetCIDParamAddress(uint16 u16CID) +{ + uint16 u16IDX; + sint16 i16CIDIDX = -1; + + for (u16IDX = 0; + u16IDX < (sizeof(USERDIAG_rastIdentifierIB) / sizeof(USERDIAG_tstIdentifierIB)); + u16IDX++) + { + if (u16CID == USERDIAG_rastIdentifierIB[u16IDX].u16CID) + { + i16CIDIDX = u16IDX; + break; + } + } + + return i16CIDIDX; +} + +static void DIAG_vNTOH(puint8 pu8Data, uint8 u8DataCount, uint8 u8DataSize) +{ + uint32 u32Temp; + uint16 u16Temp; + + if ((4 > u8DataSize) && (0 == (u8DataCount % u8DataSize)))/*CR1_28*//*CR1_29*/ + { + while (0 < u8DataCount) + { + switch ((u8DataCount & 0x03) % u8DataSize)/*CR1_27*/ + { + case 0: + { + memcpy((void*)&u32Temp, (void*)pu8Data, 4); + *pu8Data++ = (uint8)((u32Temp & 0xff000000) >> 24); + *pu8Data++ = (uint8)((u32Temp & 0xff0000) >> 16); + *pu8Data++ = (uint8)((u32Temp & 0xff00) >> 8); + *pu8Data++ = (uint8)((u32Temp & 0xff) >> 0); + u8DataCount -= 4; + break; + } + case 2: + { + memcpy((void*)&u16Temp, (void*)pu8Data, 2); + *pu8Data++ = (uint8)((u16Temp & 0xff00) >> 8); + *pu8Data++ = (uint8)((u16Temp & 0xff) >> 0); + u8DataCount -= 2; + break; + } + case 1: + { + u8DataCount = 0; + } + } + } + } +} + +#endif //BUILD_USER + + diff --git a/source/Client/DIAG.h b/source/Client/DIAG.h new file mode 100644 index 0000000..a09b229 --- /dev/null +++ b/source/Client/DIAG.h @@ -0,0 +1,388 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Diagnostics Header File */ +/* DESCRIPTION: This code module initialises the required comms */ +/* resources for and provides functions for diagnostics */ +/* FILE NAME: DIAG.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef USERDIAG_H +#define USERDIAG_H + +#include +#include +#include "ADCAPI.h" +#include "BVM.h" +#include "DIAGAPI.h" +#include "IOAPI.h" +#include "SYSAPI.h" +#include "UNITS.h" +#include "USER.h" + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +/******************************************************************************* +* Description : Type to hold a CID configuration +*******************************************************************************/ +typedef struct +{ + uint16 u16CID; + puint8 pu8Data; + uint8 u8DataCount; + uint8 u8DataSize; + DIAGAPI_tenDiagSecurityLevel enSecLevel; +} USERDIAG_tstIdentifierIB; + +typedef struct +{ + SPREADAPI_ttSpreadIDX tSpreadIDX; + uint8* pData; +} USERDIAG_tstSpreadIDXAddressPair; + +typedef enum +{ + MODE1_Supported1, + MODE1_StatSinceDTCClear, + MODE1_FreezeDTC, + MODE1_FuelSysStatus, + MODE1_CalcEngineLoad, + MODE1_ECT, + MODE1_STT_Bank1, + MODE1_LTT_Bank1, + MODE1_STT_Bank2, + MODE1_LTT_Bank2, + MODE1_FuelPressure, + MODE1_MAP, + MODE1_RPM, + MODE1_VSS, + MODE1_IgnAdvance, + MODE1_IAT, + MODE1_MAFMassPerSec, + MODE1_TPS, + MODE1_CmdSecAirStatus, + MODE1_O2SensorsPresent, + MODE1_O2Sensor1StatSTFT, + MODE1_O2Sensor2StatSTFT, + MODE1_O2Sensor3StatSTFT, + MODE1_O2Sensor4StatSTFT, + MODE1_O2Sensor5StatSTFT, + MODE1_O2Sensor6StatSTFT, + MODE1_O2Sensor7StatSTFT, + MODE1_O2Sensor8StatSTFT, + MODE1_OBDStandards, + MODE1_O2SensorsPreset4Bank, + MODE1_AuxInputStat, + MODE1_RunTimeStart, + \ + MODE1_Mode1Supported2, + MODE1_DistMIL, + MODE1_RailPressure, + MODE1_GaugePressure, + MODE1_O2Sensor1AFEquivalence, + MODE1_O2Sensor2AFEquivalence, + MODE1_O2Sensor3AFEquivalence, + MODE1_O2Sensor4AFEquivalence, + MODE1_O2Sensor5AFEquivalence, + MODE1_O2Sensor6AFEquivalence, + MODE1_O2Sensor7AFEquivalence, + MODE1_O2Sensor8AFEquivalence, + MODE1_CommandEGR, + MODE1_EGRError, + MODE1_CommandEvap, + MODE1_FuelLevelInput, + MODE1_OKWarmUps, + MODE1_DistSinceOK, + MODE1_EvapPressure, + MODE1_AbsolutePressure, + MODE1_O2Sensor1AFEquivalenceB, + MODE1_O2Sensor2AFEquivalenceB, + MODE1_O2Sensor3AFEquivalenceB, + MODE1_O2Sensor4AFEquivalenceB, + MODE1_O2Sensor5AFEquivalenceB, + MODE1_O2Sensor6AFEquivalenceB, + MODE1_O2Sensor7AFEquivalenceB, + MODE1_O2Sensor8AFEquivalenceB, + MODE1_Catalyst1Temp_Bank1, + MODE1_Catalyst2Temp_Bank1, + MODE1_Catalyst1Temp_Bank2, + MODE1_Catalyst2Temp_Bank2, + \ + MODE1_Mode1Supported3, + MODE1_1, + MODE1_2, + MODE1_3, + MODE1_4, + MODE1_5, + MODE1_6, + MODE1_7, + MODE1_8, + MODE1_9, + MODE1_10, + MODE1_11, + MODE1_12, + MODE1_13, + MODE1_14, + MODE1_15, + MODE1_16, + MODE1_17, + MODE1_18, + MODE1_19, + MODE1_20, + MODE1_21, + MODE1_22, + MODE1_23, + MODE1_24, + MODE1_25, + MODE1_26, + MODE1_27, + MODE1_28, + MODE1_29, + MODE1_30, + MODE1_31, + MODE1_Mode1Supported4, + MODE1_PIDS_COUNT +} USERDIAG_tenMode1PIDS; + + + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define USERDIAG_nUARTFrequency 9600u +#define USERDIAG_nCAN2Frequency 500000u +#define USERDIAG_nRPCUDSREQSourcePort 0xc398 +#define USERDIAG_nRPCUDSREQDestPort 0x9c14 +#define USERDIAG_nRPCUDSRESPSourcePort 0x9c05 +#define USERDIAG_nRPCUDSRESPDestPort 0x9c15 +#define USERDIAG_nEnableUART +#define USERDIAG_nEnableCAN +#define USERDIAG_nEnableUSB +#define USERDIAG_nEnableENEToff + +#ifdef BUILD_MK60 +#define DIAG_nRESCAN EH_VIO_CAN2 +#endif + +#ifdef BUILD_MK64 +#define DIAG_nRESCAN EH_VIO_CAN +#endif + +#define USER_DIAG_APPEND_XOR() \ + u32Temp = ((0xff000000 & stCANMsg.u32DWH) >> 24) ^\ + ((0x00ff0000 & stCANMsg.u32DWH) >> 16) ^\ + ((0x0000ff00 & stCANMsg.u32DWH) >> 8) ^\ + ((0x000000ff & stCANMsg.u32DWH) >> 0) ^\ + ((0xff000000 & stCANMsg.u32DWL) >> 24) ^\ + ((0x00ff0000 & stCANMsg.u32DWL) >> 16) ^\ + ((0x0000ff00 & stCANMsg.u32DWL) >> 8);\ + stCANMsg.u32DWL += u32Temp; + +#define USER_DIAG_nCIDInfo \ +{ \ + { 0x8000, (puint8)&USERCAL_stRAMCAL.userCalADRefH, sizeof(GPM6_ttVolts), 4, DIAGAPI_enSecLevelInactive}, \ + { 0x8001, (puint8)&USERCAL_stRAMCAL.userCalVRef445, sizeof(GPM6_ttVolts), 4, DIAGAPI_enSecLevelInactive}, \ + { 0x8002, (puint8)&USERCAL_stRAMCAL.userCalVNernstTarget, sizeof(GPM6_ttVolts), 4, DIAGAPI_enSecLevelInactive}, \ + { 0x8003, (puint8)&USERCAL_stRAMCAL.userCalRNernstReady, sizeof(GPM6_ttVolts), 4, DIAGAPI_enSecLevelInactive}, \ + { 0x8004, (puint8)&USERCAL_stRAMCAL.au32UserCalPumpCurrentPFactor, 2 * sizeof(uint32), 4, DIAGAPI_enSecLevelInactive} \ +} + +#define USERDIAG_nMode1PIDOffsets \ +{\ + 0,\ + 4,\ + 8,\ + 10,\ + 12,\ + 13,\ + 14,\ + 15,\ + 16,\ + 17,\ + 18,\ + 19,\ + 20,\ + 22,\ + 23,\ + 24,\ + 25,\ + 27,\ + 28,\ + 29,\ + 30,\ + 32,\ + 34,\ + 36,\ + 38,\ + 40,\ + 42,\ + 44,\ + 46,\ + 47,\ + 48,\ + 49,\ + 51,\ + 55,\ + 57,\ + 59,\ + 61,\ + 65,\ + 69,\ + 73,\ + 77,\ + 81,\ + 85,\ + 89,\ + 93,\ + 94,\ + 95,\ + 96,\ + 97,\ + 98,\ + 100,\ + 102,\ + 103,\ + 107,\ + 111,\ + 115,\ + 119,\ + 123,\ + 127,\ + 131,\ + 135,\ + 137,\ + 139,\ + 141,\ + 143,\ + 147,\ + 151,\ + 153,\ + 155,\ + 157,\ + 158,\ + 159,\ + 160,\ + 161,\ + 162,\ + 163,\ + 164,\ + 165,\ + 167,\ + 169,\ + 173,\ + 177,\ + 178,\ + 179,\ + 181,\ + 183,\ + 185,\ + 187,\ + 189,\ + 191,\ + 193,\ + 194,\ + 195,\ + 196,\ + 198,\ + 200,\ + 201} + +#define USERDIAG_nUARTFrequency 9600u +#define USERDIAG_nCAN1Frequency 500000u +#define USERDIAG_nMode1BufferSize 256 + +#define USERDIAG_nCodes648 {54,54,78,78,78,78,139,139,139,139,232,232,232,232,54,54} +#define USERDIAG_nCodes1152 {28,28,81,81,81,81,132,132,132,132,193,193,193,193,28,28} + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _USERDIAG_C + #define EXTERN +#else + #define EXTERN extern +#endif + +EXTERN uint8 DIAG_u8EngagedGearReport; +//ASAM mode=readvalue name="Engaged Gear Report" type=uint8 offset=0 min=0 max=10 m=1 b=0 units="dl" format=1.0 help="Engaged Gear Report" + +EXTERN uint8 DIAG_u8PedalPositionReport; +//ASAM mode=readvalue name="Pedal Position Report" type=uint8 offset=0 min=0 max=120 m=0.4 b=0 units="dl" format=2.0 help="Pedal Position Report" + +EXTERN uint8 DIAG_u8GearSelectorReport; +//ASAM mode=readvalue name="Gear Selector Report" type=uint8 offset=0 min=0 max=10 m=1 b=0 units="dl" format=1.0 help="Gear Selector Report" + +EXTERN uint8 DIAG_u8PowerModeActive; +EXTERN uint16 DIAG_u16PowerModeActiveCount; +EXTERN uint16 DIAG_u16PowerModeCode; + +#define DIAG_nSPREADSMAX 5 +#define DIAG_nSPREADSRECORDSMAX 50 + +EXTERN SPREADAPI_tstSpreadResult DIAG_astSpreadResult[DIAG_nSPREADSMAX]; +//ASAM mode=readvalue name="_DIAG Spread Result Table 0" type=uint32 offset=0 min=0 max=1 m=1 b=0 units="dl" format=6.0 help="Internal Spread Result Table" +//ASAM mode=readvalue name="_DIAG Spread Result Table 1" type=uint32 offset=4 min=0 max=1 m=1 b=0 units="dl" format=6.0 help="Internal Spread Result Table" +//ASAM mode=readvalue name="_DIAG Spread Result Table 2" type=uint32 offset=8 min=0 max=1 m=1 b=0 units="dl" format=6.0 help="Internal Spread Result Table" +//ASAM mode=readvalue name="_DIAG Spread Result Table 3" type=uint32 offset=12 min=0 max=1 m=1 b=0 units="dl" format=6.0 help="Internal Spread Result Table" + +EXTERN uint8* DIAG_apu8SpreadTableAddresses[DIAG_nSPREADSMAX]; +//ASAM mode=writevalue name="_DIAG Spread Address Table 0" type=uint32 offset=0 min=0 max=1 m=1 b=0 units="dl" format=6.0 help="Internal Spread Address Table" +//ASAM mode=writevalue name="_DIAG Spread Address Table 1" type=uint32 offset=4 min=0 max=1 m=1 b=0 units="dl" format=6.0 help="Internal Spread Address Table" +//ASAM mode=writevalue name="_DIAG Spread Address Table 2" type=uint32 offset=8 min=0 max=1 m=1 b=0 units="dl" format=6.0 help="Internal Spread Address Table" +//ASAM mode=writevalue name="_DIAG Spread Address Table 3" type=uint32 offset=12 min=0 max=1 m=1 b=0 units="dl" format=6.0 help="Internal Spread Address Table" +EXTERN USERDIAG_tstSpreadIDXAddressPair DIAG_astIDXAddressPairs[DIAG_nSPREADSRECORDSMAX]; + + + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void USERDIAG_vStart(uint32* const pu32Arg); +void USERDIAG_vRun(uint32* const pu32Arg); +void USERDIAG_vTerminate(uint32* const pu32Arg); +void USERDIAG_vCallBack(uint32* const pu32Arg); +void USERDIAG_vAddIDXAddressPair(USERDIAG_tstSpreadIDXAddressPair* pstSpreadIDXAddressPair); + +/******************************************************************************* +* Interface : +* +* Implementation : +* +* Parameter +* Par1 : +* Par2 : +* +* +* Return Value : +*******************************************************************************/ +DIAGAPI_tenCBResult USERDIAG_boReadDataCallBack(uint16 u16CID, puint8 pu8Data, uint8 u8DataCount);/*CR1_1*/; + +/******************************************************************************* +* Interface : +* +* Implementation : +* +* Parameter +* Par1 : +* Par2 : +* +* +* Return Value : +*******************************************************************************/ +DIAGAPI_tenCBResult USERDIAG_boWriteDataCallBack(uint16 u16CID, puint8 pu8Data, uint8 u8DataCount);/*CR1_1*/ + +/******************************************************************************* +* Interface : +* +* Implementation : +* +* Parameter +* Par1 : +* Par2 : +* +* +* Return Value : +*******************************************************************************/ +DIAGAPI_tenCBResult USERDIAG_boRoutineControl(DIAGAPI_tenRoutineAction enRoutineAction, puint8 pu8Data, uint8 u8DataCount);/*CR1_1*/; + +#endif // USERDIAG_H + diff --git a/source/Client/EST.c b/source/Client/EST.c new file mode 100644 index 0000000..7d10184 --- /dev/null +++ b/source/Client/EST.c @@ -0,0 +1,651 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Electronic Spark Timing Header File */ +/* DESCRIPTION: This code module initialises the required */ +/* resources and functions for electronic spark timing */ +/* */ +/* FILE NAME: EST.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _EST_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "EST.h" +#include "CEMAPI.h" + + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +TEPMAPI_tstTimedKernelEvent EST_astTimedKernelEvents[2]; +SPREADAPI_ttSpreadIDX EST_tSpreadTimingxIDX; +SPREADAPI_ttSpreadIDX EST_tSpreadTimingyIDX; +SPREADAPI_ttSpreadIDX EST_tSpreadDwellIDX; +TABLEAPI_ttTableIDX EST_tMapTimingIDX; +TABLEAPI_ttTableIDX EST_tMapTimingStage1IDX; +TABLEAPI_ttTableIDX EST_tTableDwellIDX; +uint16 EST_u16TimingBase; +uint16 EST_u16TimingStaged; +uint16 EST_u16Timing; +uint16 EST_u16Dwell; + + +EST_tenIgnitionTimingStage EST_enIgnitionTimingStage; + + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ + + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void EST_vStart(puint32 const pu32Arg) +{ + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenEHIOType enEHIOType; + IOAPI_tenDriveStrength enDriveStrength; + TEPMAPI_tstTEPMChannelCB stTEPMChannelCB; + TEPMAPI_tstTEPMResourceCB stTEPMResourceCB; + TEPMAPI_tstTimedUserEvent stTimedEvent; + bool boCamSyncLate; + uint32 u32CamSyncSampleToothCount; + CEM_tstPatternSetupCB stPatternSetupCB; + + IOAPI_tenEdgePolarity enEdgePolarity = USERCAL_stRAMCAL.u8UserPrimaryEdgeSetup; + bool boFirstRising = 0 != USERCAL_stRAMCAL.u8UserFirstEdgeRisingPrimary; + uint32 u32TriggerType = USERCAL_stRAMCAL.u8TriggerType; + + /* Both peak and hold have a switch on and switch off event per cycle */ + TEPMAPI_ttEventCount tEventCount = 2; + EST_tIgnitionAdvanceMtheta = 0; + + EST_enIgnitionTimingStage = EST_nIgnitionPrimary; + EST_enIgnitionTimingRequest = EST_nIgnitionReqPrimary; + + /* Set dwell to 10 degrees - 360 degrees */ + EST_tStartFractionA = (0x10000 * 120) / EST_nDegreesPerCycle; + EST_tStartFractionB = (0x10000 * 120) / EST_nDegreesPerCycle; + EST_tStartFractionC = (0x10000 * 120) / EST_nDegreesPerCycle; + EST_tStartFractionD = (0x10000 * 120) / EST_nDegreesPerCycle; + EST_tDwellUs = 5000u; + + /* Request and initialise FTM for igniters */ + enEHIOResource = EH_VIO_FTM0; + enEHIOType = IOAPI_enTEPM; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + /* ONLY CONFIGURE THE FTM0 MODULE ONCE PER PROJECT! */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMResourceCB.enEHIOResource = EH_VIO_FTM0; + stTEPMResourceCB.enPreScalar = SENSORS_nFastFTMDivisor; + stTEPMResourceCB.enCountType = TEPMAPI_enCountUp; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMResourceCB); + } + + /* Request and initialise FTM2 for igniters */ + enEHIOResource = EH_VIO_FTM2; + enEHIOType = IOAPI_enTEPM; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + /* ONLY CONFIGURE THE TC2 MODULE ONCE PER PROJECT! */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMResourceCB.enEHIOResource = EH_VIO_FTM2; + stTEPMResourceCB.enPreScalar = SENSORS_nFastFTMDivisor; + stTEPMResourceCB.enCountType = TEPMAPI_enCountUp; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMResourceCB); + } + + /* Request and initialise EST_nESTOutput A ***************************/ + if ((0xffff > USERCAL_stRAMCAL.au32IgnitionSequence[0]) && (EH_IO_Invalid > USERCAL_stRAMCAL.aESTIOResource[0])) + { + enEHIOResource = USERCAL_stRAMCAL.aESTIOResource[0]; //EST_nESTOutputA; + enEHIOType = IOAPI_enCaptureCompare; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, + (void*)NULL, (void*)NULL); + + /* Initialise the TEPM channel EST_nESTOutput the dwell timer*/ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMChannelCB.enAction = TEPMAPI_enSetLow; + stTEPMChannelCB.boInterruptEnable = TRUE; + stTEPMChannelCB.enPreScalar = 0; + stTEPMChannelCB.u32Sequence = USERCAL_stRAMCAL.au32IgnitionSequence[0]; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMChannelCB); + } + + /* Switch igniter on at a fraction of global time */ + EST_astTimedKernelEvents[0].enAction = TEPMAPI_enSetHigh; + EST_astTimedKernelEvents[0].enMethod = TEPMAPI_enGlobalLinkedFraction; + EST_astTimedKernelEvents[0].ptEventTime = &EST_tStartFractionA; + EST_astTimedKernelEvents[0].enEHIOBitMirrorResource = USERCAL_stRAMCAL.aESTIOMuxResource[0]; + + /* Switch igniter off at timer ms */ + EST_astTimedKernelEvents[1].enAction = TEPMAPI_enSetLow; + EST_astTimedKernelEvents[1].enMethod = TEPMAPI_enHardLinkedTimeStep; + EST_astTimedKernelEvents[1].ptEventTime = &EST_tDwellUs; + EST_astTimedKernelEvents[1].enEHIOBitMirrorResource = USERCAL_stRAMCAL.aESTIOMuxResource[0]; + + USER_vSVC(SYSAPI_enConfigureKernelTEPMOutput, (void*)&enEHIOResource, + (void*)&EST_astTimedKernelEvents[0], (void*)&tEventCount); + } + + /* Request and initialise EST_nESTOutput B ***************************/ + if ((0xffff > USERCAL_stRAMCAL.au32IgnitionSequence[1]) && (EH_IO_Invalid > USERCAL_stRAMCAL.aESTIOResource[1])) + { + enEHIOResource = USERCAL_stRAMCAL.aESTIOResource[1]; //EST_nESTOutputB; + enEHIOType = IOAPI_enCaptureCompare; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, + (void*)NULL, (void*)NULL); + + /* Initialise the TEPM channel EST_nESTOutput the dwell timer*/ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMChannelCB.enAction = TEPMAPI_enSetLow; + stTEPMChannelCB.boInterruptEnable = TRUE; + stTEPMChannelCB.enPreScalar = 0; + stTEPMChannelCB.u32Sequence = USERCAL_stRAMCAL.au32IgnitionSequence[1]; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMChannelCB); + } + + /* Switch igniter on at a fraction of global time */ + EST_astTimedKernelEvents[0].enAction = TEPMAPI_enSetHigh; + EST_astTimedKernelEvents[0].enMethod = TEPMAPI_enGlobalLinkedFraction; + EST_astTimedKernelEvents[0].ptEventTime = &EST_tStartFractionB; + EST_astTimedKernelEvents[0].enEHIOBitMirrorResource = USERCAL_stRAMCAL.aESTIOMuxResource[1]; + + /* Switch igniter off at timer ms */ + EST_astTimedKernelEvents[1].enAction = TEPMAPI_enSetLow; + EST_astTimedKernelEvents[1].enMethod = TEPMAPI_enHardLinkedTimeStep; + EST_astTimedKernelEvents[1].ptEventTime = &EST_tDwellUs; + EST_astTimedKernelEvents[1].enEHIOBitMirrorResource = USERCAL_stRAMCAL.aESTIOMuxResource[1]; + + USER_vSVC(SYSAPI_enConfigureKernelTEPMOutput, (void*)&enEHIOResource, + (void*)&EST_astTimedKernelEvents[0], (void*)&tEventCount); + } + + /* Request and initialise EST_nESTOutput C ***************************/ + if ((0xffff > USERCAL_stRAMCAL.au32IgnitionSequence[2]) && (EH_IO_Invalid > USERCAL_stRAMCAL.aESTIOResource[2])) + { + enEHIOResource = USERCAL_stRAMCAL.aESTIOResource[2]; //EST_nESTOutputC; + enEHIOType = IOAPI_enCaptureCompare; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, + (void*)NULL, (void*)NULL); + + /* Initialise the TEPM channel EST_nESTOutput the dwell timer*/ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMChannelCB.enAction = TEPMAPI_enSetLow; + stTEPMChannelCB.boInterruptEnable = TRUE; + stTEPMChannelCB.enPreScalar = 0; + stTEPMChannelCB.u32Sequence = USERCAL_stRAMCAL.au32IgnitionSequence[2]; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMChannelCB); + } + + /* Switch igniter on at a fraction of global time */ + EST_astTimedKernelEvents[0].enAction = TEPMAPI_enSetHigh; + EST_astTimedKernelEvents[0].enMethod = TEPMAPI_enGlobalLinkedFraction; + EST_astTimedKernelEvents[0].ptEventTime = &EST_tStartFractionC; + EST_astTimedKernelEvents[0].enEHIOBitMirrorResource = USERCAL_stRAMCAL.aESTIOMuxResource[2]; + + /* Switch igniter off at timer ms */ + EST_astTimedKernelEvents[1].enAction = TEPMAPI_enSetLow; + EST_astTimedKernelEvents[1].enMethod = TEPMAPI_enHardLinkedTimeStep; + EST_astTimedKernelEvents[1].ptEventTime = &EST_tDwellUs; + EST_astTimedKernelEvents[1].enEHIOBitMirrorResource = USERCAL_stRAMCAL.aESTIOMuxResource[2]; + + USER_vSVC(SYSAPI_enConfigureKernelTEPMOutput, (void*)&enEHIOResource, + (void*)&EST_astTimedKernelEvents[0], (void*)&tEventCount); + } + + + /* Request and initialise EST_nESTOutput D ***************************/ + if ((0xffff > USERCAL_stRAMCAL.au32IgnitionSequence[3]) && (EH_IO_Invalid > USERCAL_stRAMCAL.aESTIOResource[3])) + { + enEHIOResource = USERCAL_stRAMCAL.aESTIOResource[3]; //EST_nESTOutputD; + enEHIOType = IOAPI_enCaptureCompare; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, + (void*)NULL, (void*)NULL); + + /* Initialise the TEPM channel EST_nESTOutput the dwell timer*/ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMChannelCB.enAction = TEPMAPI_enSetLow; + stTEPMChannelCB.boInterruptEnable = TRUE; + stTEPMChannelCB.enPreScalar = 0; + stTEPMChannelCB.u32Sequence = USERCAL_stRAMCAL.au32IgnitionSequence[3]; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMChannelCB); + } + + /* Switch igniter on at a fraction of global time */ + EST_astTimedKernelEvents[0].enAction = TEPMAPI_enSetHigh; + EST_astTimedKernelEvents[0].enMethod = TEPMAPI_enGlobalLinkedFraction; + EST_astTimedKernelEvents[0].ptEventTime = &EST_tStartFractionD; + EST_astTimedKernelEvents[0].enEHIOBitMirrorResource = USERCAL_stRAMCAL.aESTIOMuxResource[3]; + + /* Switch igniter off at timer ms */ + EST_astTimedKernelEvents[1].enAction = TEPMAPI_enSetLow; + EST_astTimedKernelEvents[1].enMethod = TEPMAPI_enHardLinkedTimeStep; + EST_astTimedKernelEvents[1].ptEventTime = &EST_tDwellUs; + EST_astTimedKernelEvents[1].enEHIOBitMirrorResource = USERCAL_stRAMCAL.aESTIOMuxResource[3]; + + USER_vSVC(SYSAPI_enConfigureKernelTEPMOutput, (void*)&enEHIOResource, + (void*)&EST_astTimedKernelEvents[0], (void*)&tEventCount); + } + + /* Request and initialise required Kernel managed spread for Timingx */ + EST_tSpreadTimingxIDX = SETUP_tSetupSpread((void*)&CAM_u32RPMFiltered, (void*)&USERCAL_stRAMCAL.aUserTimingxSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for Timingy */ + EST_tSpreadTimingyIDX = SETUP_tSetupSpread((void*)&MAP_tKiloPaFiltered, (void*)&USERCAL_stRAMCAL.aUserTimingySpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for Timing*/ + EST_tMapTimingIDX = SETUP_tSetupMap((void*)&USERCAL_stRAMCAL.aUserTimingMap, (void*)&EST_u16TimingBase, TYPE_enUInt16, 17, 17, EST_tSpreadTimingxIDX, EST_tSpreadTimingyIDX, NULL); + + /* Request and initialise required Kernel managed table for Timing*/ + EST_tMapTimingStage1IDX = SETUP_tSetupMap((void*)&USERCAL_stRAMCAL.aUserTimingMapStage1, (void*)&EST_u16TimingStaged, TYPE_enUInt16, 17, 17, EST_tSpreadTimingxIDX, EST_tSpreadTimingyIDX, NULL); + + /* Request and initialise required Kernel managed spread for Dwell */ + EST_tSpreadDwellIDX = SETUP_tSetupSpread((void*)&BVM_tBattVolts, (void*)&USERCAL_stRAMCAL.aUserDwellSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for Dwell*/ + EST_tTableDwellIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserDwellTable, (void*)&EST_u16Dwell, TYPE_enUInt16, 17, EST_tSpreadDwellIDX, NULL); + + stPatternSetupCB.enEdgePolarity = enEdgePolarity; + stPatternSetupCB.u32TriggerType = u32TriggerType; + stPatternSetupCB.boFirstEdgeRising = boFirstRising; + + USER_vSVC(SYSAPI_enSetupCrankTriggerEdgePattern, (void*)&USERCAL_stRAMCAL.aUserPrimaryTriggerTable[0], (void*)&stPatternSetupCB, NULL); + + USER_vSVC(SYSAPI_enSetupSyncPointsPattern, (void*)&USERCAL_stRAMCAL.aUserSyncPointsTable[0], (void*)&USERCAL_stRAMCAL.u32SyncPhaseRepeats, NULL); + + /* Enable the Motor driver enables */ + enEHIOResource = EST_nMotor1EnablePin; + enEHIOType = IOAPI_enDIOOutput; + enDriveStrength = IOAPI_enStrong; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + + enEHIOResource = EST_nMotor2EnablePin; + enEHIOType = IOAPI_enDIOOutput; + enDriveStrength = IOAPI_enStrong; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + + SETUP_vSetDigitalIOHigh(EST_nMotor1EnablePin); + SETUP_vSetDigitalIOHigh(EST_nMotor2EnablePin); + + /* Setup simple cam sync resource */ + if (EH_IO_Invalid != USERCAL_stRAMCAL.enSimpleCamSyncSource) + { + enEHIOResource = USERCAL_stRAMCAL.enSimpleCamSyncSource; + enEHIOType = IOAPI_enDIOInput; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + + /* Setup the simple CAM sync */ + boCamSyncLate = USERCAL_stRAMCAL.boCamSyncHighLate; + u32CamSyncSampleToothCount = USERCAL_stRAMCAL.u32CamSyncSampleToothCount; + + SETUP_vSetupSimpleCamSync(enEHIOResource, boCamSyncLate, u32CamSyncSampleToothCount); + } + + + /* Request and initialise VVT1 Input ***************************/ + if (EH_IO_Invalid > USERCAL_stRAMCAL.aVVTInputResource[0]) + { + enEHIOResource = USERCAL_stRAMCAL.aVVTInputResource[0]; + enEHIOType = IOAPI_enCaptureCompare; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, + (void*)NULL, (void*)NULL); + + /* Initialise the VVT1 Input */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMChannelCB.enAction = TEPMAPI_enCapAny; + stTEPMChannelCB.boInterruptEnable = TRUE; + stTEPMChannelCB.boRecursive = FALSE; + stTEPMChannelCB.u32Sequence = 0x10000000 + USERCAL_stRAMCAL.aVVTInputType[0]; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMChannelCB); + } + + stTimedEvent.enMethod = TEPMAPI_enLinkVVT1Input; + stTimedEvent.pfEventCB = NULL; + + USER_vSVC(SYSAPI_enConfigureUserTEPMInput, (void*)&enEHIOResource, + (void*)&stTimedEvent, (void*)NULL); + } + + + + /* Set up EST active output */ + if (EH_IO_Invalid != USERCAL_stRAMCAL.enESTBypass) + { + enEHIOResource = USERCAL_stRAMCAL.enESTBypass; + enEHIOType = IOAPI_enDIOOutput; + enDriveStrength = IOAPI_enStrong; + + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + } + + + + /* Set up EST mirror outputs */ + if (EH_IO_Invalid != USERCAL_stRAMCAL.aESTIOMuxResource[0]) + { + enEHIOResource = USERCAL_stRAMCAL.aESTIOMuxResource[0]; + enEHIOType = IOAPI_enDIOOutput; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + } + + if (EH_IO_Invalid != USERCAL_stRAMCAL.aESTIOMuxResource[1]) + { + enEHIOResource = USERCAL_stRAMCAL.aESTIOMuxResource[1]; + enEHIOType = IOAPI_enDIOOutput; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + } + + if (EH_IO_Invalid != USERCAL_stRAMCAL.aESTIOMuxResource[2]) + { + enEHIOResource = USERCAL_stRAMCAL.aESTIOMuxResource[2]; + enEHIOType = IOAPI_enDIOOutput; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + } + + if (EH_IO_Invalid != USERCAL_stRAMCAL.aESTIOMuxResource[3]) + { + enEHIOResource = USERCAL_stRAMCAL.aESTIOMuxResource[3]; + enEHIOType = IOAPI_enDIOOutput; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + } +} + +void EST_vRun(puint32 const pu32Arg) +{ + uint32 u32DwellDegrees; + uint32 u32DelayDegrees; + uint32 u32DwellUsMax; + uint32 u32DwellUs; + uint32 u32Temp; + sint32 s32ESTTrims[2]; + static uint32 u32CrankDwell; + static uint32 u32BypassCount; + uint32 u32Dwell; + IOAPI_tenTriState enTriState; + IOAPI_tenEHIOResource enEHIOResource; + bool boESTAltMapRequestActive; + + boESTAltMapRequestActive = SENSORS_boGetAuxActive(SENSORS_enAUX_LAUNCH_LOW); + boESTAltMapRequestActive |= SENSORS_boGetAuxActive(SENSORS_enAUX_LAUNCH_HIGH); + + + /* Calculate timing based on timing map request */ + if ((EST_nIgnitionReqPrimary == EST_enIgnitionTimingRequest) && + (FALSE == boESTAltMapRequestActive)) + { + //TODO + /* Calculate the current spread for Timingx */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&EST_tSpreadTimingxIDX, + NULL, NULL); + + /* Calculate the current spread for Timingy */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&EST_tSpreadTimingyIDX, + NULL, NULL); + + /* Lookup the current timing value for Timing */ + USER_vSVC(SYSAPI_enCalculateMap, (void*)&EST_tMapTimingIDX, + NULL, NULL); + + if (EST_u16Timing > EST_u16TimingBase) + { + if ((EST_u16Timing - EST_u16TimingBase) >= USERCAL_stRAMCAL.u16ESTNegRateMax) + { + if (EST_u16Timing >= USERCAL_stRAMCAL.u16ESTNegRateMax) + { + EST_u16Timing -= USERCAL_stRAMCAL.u16ESTNegRateMax; + } + else + { + EST_u16Timing = 0; + } + } + else + { + EST_u16Timing = EST_u16TimingBase; + } + } + else if (EST_u16Timing < EST_u16TimingBase) + { + if ((EST_u16TimingBase - EST_u16Timing) >= USERCAL_stRAMCAL.u16ESTPosRateMax) + { + EST_u16Timing += USERCAL_stRAMCAL.u16ESTNegRateMax; + } + else + { + EST_u16Timing = EST_u16TimingBase; + } + } + } + else if ((EST_nIgnitionReqDSGStage1 == EST_enIgnitionTimingRequest) || + (EST_nIgnitionReqDSGStage2 == EST_enIgnitionTimingRequest) || + (EST_nIgnitionReqDSGCutsStage3 == EST_enIgnitionTimingRequest) || + (TRUE == boESTAltMapRequestActive)) + { + /* Calculate the current spread for Timingx */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&EST_tSpreadTimingxIDX, + NULL, NULL); + + /* Calculate the current spread for Timingy */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&EST_tSpreadTimingyIDX, + NULL, NULL); + + /* Lookup the current timing value for Timing */ + USER_vSVC(SYSAPI_enCalculateMap, (void*)&EST_tMapTimingStage1IDX, + NULL, NULL); + + if (TRUE == boESTAltMapRequestActive) + { + EST_u16Timing = EST_u16TimingStaged; + } + else + { + EST_u16Timing = ((TORQUE_u32ESTTorqueModifier * EST_u16TimingBase) + + ((0x100 - TORQUE_u32ESTTorqueModifier) * EST_u16TimingStaged)) / 0x100; + } + } + + /* Calculate the current spread for dwell */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&EST_tSpreadDwellIDX, + NULL, NULL); + + /* Lookup the current dwell value for dwell */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&EST_tTableDwellIDX, + NULL, NULL); + + CPU_xEnterCritical(); + + u32DwellUsMax = (60000000 / CAM_u32RPMRaw) - EST_nDwellOffMinUs; + + if (300 > CAM_u32RPMFiltered) + { + u32CrankDwell = USERCAL_stRAMCAL.aUserDwellTable[0]; + } + else + { + u32CrankDwell = 50 < u32CrankDwell ? u32CrankDwell - 50 : 0; + } + + u32Dwell = MAX(u32CrankDwell, EST_u16Dwell); + + if (TRUE == USERCAL_stRAMCAL.boOBDISCADV) + { + if (0 < IAC_s32ISCESTTrim[0]) + { + EST_tIgnitionAdvanceMtheta = IAC_s32ISCESTTrim[0] + USERCAL_stRAMCAL.u16TimingMainOffset; + } + else + { + EST_tIgnitionAdvanceMtheta = 100 * EST_u16Timing + USERCAL_stRAMCAL.u16TimingMainOffset; + } + } + else + { + s32ESTTrims[0] = CLO2_s32ISCESTTrim[0] + IAC_s32ISCESTTrim[0]; + s32ESTTrims[1] = CLO2_s32ISCESTTrim[1] + IAC_s32ISCESTTrim[1]; + + if (0 <= s32ESTTrims[1]) + { + EST_tIgnitionAdvanceMtheta = 100 * EST_u16Timing + USERCAL_stRAMCAL.u16TimingMainOffset + (uint16)s32ESTTrims[1]; + } + else + { + EST_tIgnitionAdvanceMtheta = 100 * EST_u16Timing + USERCAL_stRAMCAL.u16TimingMainOffset; + + if (0 < (s32ESTTrims[1] + (sint32)EST_tIgnitionAdvanceMtheta)) + { + EST_tIgnitionAdvanceMtheta = (uint16)(s32ESTTrims[1] + (sint32)EST_tIgnitionAdvanceMtheta); + } + else + { + EST_tIgnitionAdvanceMtheta = 0; + } + } + } + + if (USERCAL_stRAMCAL.u16TimingMainOffset <= EST_tIgnitionAdvanceMtheta) + { + EST_tIgnitionAdvanceMthetaBTDC = EST_tIgnitionAdvanceMtheta - USERCAL_stRAMCAL.u16TimingMainOffset; + } + else + { + EST_tIgnitionAdvanceMthetaBTDC = 0; + } + + CPU_xExitCritical(); + + u32DwellUs = MIN(u32DwellUsMax, (uint32)u32Dwell); + + u32Temp = 600000 / CAM_u32RPMRaw; + + if (0 == USERCAL_stRAMCAL.u8WastedSparkEnable) + { + u32DwellDegrees = (u32DwellUs * EST_nDegreesPerCycle) / u32Temp; + u32DelayDegrees = 20 * EST_nDegreesPerCycle - u32DwellDegrees / 10 - (EST_tIgnitionAdvanceMtheta / 100); + } + else + { + u32DwellDegrees = (u32DwellUs * EST_nDegreesPerCycle) / u32Temp; + u32DelayDegrees = 10 * EST_nDegreesPerCycle - u32DwellDegrees / 10 - (EST_tIgnitionAdvanceMtheta / 100); + } + + /* Calculate EST start and end angles */ + switch (USERCAL_stRAMCAL.u8CylCount) + { + case 4: + { + if (0 == USERCAL_stRAMCAL.u8WastedSparkEnable) + { + EST_tStartFractionA = (6554 * u32DelayDegrees) / (2 * EST_nDegreesPerCycle); + EST_tStartFractionB = ((6554 * u32DelayDegrees) / (2 * EST_nDegreesPerCycle)); + EST_tStartFractionC = ((6554 * u32DelayDegrees) / (2 * EST_nDegreesPerCycle)); + EST_tStartFractionD = ((6554 * u32DelayDegrees) / (2 * EST_nDegreesPerCycle)); + } + else + { + EST_tStartFractionA = (6554 * u32DelayDegrees) / EST_nDegreesPerCycle; + EST_tStartFractionB = ((6554 * u32DelayDegrees) / EST_nDegreesPerCycle); + EST_tStartFractionC = (6554 * u32DelayDegrees) / EST_nDegreesPerCycle; + EST_tStartFractionD = ((6554 * u32DelayDegrees) / EST_nDegreesPerCycle); + } + + break; + } + case 8: + { + CPU_xEnterCritical(); + if (1850 < u32DelayDegrees) + { + //EST_tStartFractionA = (6554 * (u32DelayDegrees - 1800)) / EST_nDegreesPerCycle; + //EST_tStartFractionB = (6554 * (u32DelayDegrees - 1800)) / EST_nDegreesPerCycle; + //EST_tStartFractionC = (6554 * (u32DelayDegrees - 1800)) / EST_nDegreesPerCycle; + //EST_tStartFractionD = (6554 * (u32DelayDegrees - 1800)) / EST_nDegreesPerCycle; + EST_tStartFractionA = (6554 * (u32DelayDegrees)) / EST_nDegreesPerCycle; + EST_tStartFractionB = (6554 * (u32DelayDegrees)) / EST_nDegreesPerCycle; + EST_tStartFractionC = (6554 * (u32DelayDegrees)) / EST_nDegreesPerCycle; + EST_tStartFractionD = (6554 * (u32DelayDegrees)) / EST_nDegreesPerCycle; + } + else + { + EST_tStartFractionA = (6554 * 50) / EST_nDegreesPerCycle; + EST_tStartFractionB = (6554 * 50) / EST_nDegreesPerCycle; + EST_tStartFractionC = (6554 * 50) / EST_nDegreesPerCycle; + EST_tStartFractionD = (6554 * 50) / EST_nDegreesPerCycle; + } + CPU_xExitCritical(); + + break; + } + default: + { + EST_tStartFractionA = (6554 * u32DelayDegrees) / EST_nDegreesPerCycle; + EST_tStartFractionB = ((6554 * u32DelayDegrees) / EST_nDegreesPerCycle); + EST_tStartFractionC = ((6554 * u32DelayDegrees) / EST_nDegreesPerCycle); + EST_tStartFractionD = ((6554 * u32DelayDegrees) / EST_nDegreesPerCycle); + } + } + + EST_tDwellUs = EST_xUsToSlowTicks(u32DwellUs); + + /* Set the EST active output */ + if (EH_IO_Invalid != USERCAL_stRAMCAL.enESTBypass) + { + u32BypassCount = (500 < CAM_u32RPMRaw) && (~0 != u32BypassCount) ? u32BypassCount + 1 : u32BypassCount; + u32BypassCount = 0 == CAM_u32RPMRaw ? 0 : u32BypassCount; + + if (500 < u32BypassCount) + { + enEHIOResource = USERCAL_stRAMCAL.enESTBypass; + enTriState = IOAPI_enLow; + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, + (void*)&enTriState, (void*)NULL); + } + else + { + enEHIOResource = USERCAL_stRAMCAL.enESTBypass; + enTriState = IOAPI_enHigh; + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, + (void*)&enTriState, (void*)NULL); + } + } +} + +void EST_vTerminate(puint32 const pu32Arg) +{ + +} + + +void EST_vCallBack(puint32 const pu32Arg) +{ + +} + +#endif //BUILD_USER diff --git a/source/Client/EST.h b/source/Client/EST.h new file mode 100644 index 0000000..cb3d590 --- /dev/null +++ b/source/Client/EST.h @@ -0,0 +1,92 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Electronic Spark Timing Header File */ +/* DESCRIPTION: This code module initialises the required */ +/* resources and functions for electronic spark timing */ +/* */ +/* FILE NAME: EST.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef EST_H +#define EST_H + +#include +#include "IOAPI.h" +#include "TEPMAPI.h" +#include "USER.h" +#include "cpuabstract.h" + + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _EST_C + #define EXTERN +#else + #define EXTERN extern +#endif + +typedef enum +{ + EST_nIgnitionPrimary, + EST_nIgnitionStage1, + EST_nIgnitionStage2, + EST_nIgnitionStage3, +} EST_tenIgnitionTimingStage; + +typedef enum +{ + EST_nIgnitionReqPrimary, + EST_nIgnitionReqDSGStage1, + EST_nIgnitionReqDSGStage2, + EST_nIgnitionReqDSGCutsStage3, + EST_nIgnitionReqStage3, +} EST_tenIgnitionTimingRequest; + +#ifdef BUILD_SPARKDOG_PF +#define EST_nMotor1EnablePin EH_IO_GP4 +#define EST_nMotor2EnablePin EH_IO_GP4 +#endif //BUILD_SPARKDOG_PF + +#ifdef BUILD_SPARKDOG_TEENSY_ADAPT +#define EST_nMotor1EnablePin EH_IO_GP3 +#define EST_nMotor2EnablePin EH_IO_GP2 +#endif + +#define EST_nSlowFTMDivisor TEPMAPI_enDiv128 +#define EST_nDwellOffMinUs 1500u +#define EST_nDegreesPerCycle 360u +#define EST_xUsToSlowTicks(x) (((SENSORS_nSlowFTMFreq / 100u) * (x)) / 10000u) + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ + +EXTERN TEPMAPI_ttEventTime EST_tStartFractionD; +EXTERN TEPMAPI_ttEventTime EST_tStartFractionC; +EXTERN TEPMAPI_ttEventTime EST_tStartFractionB; +EXTERN TEPMAPI_ttEventTime EST_tStartFractionA; +//ASAM mode=readvalue name="EST Start Fraction" type=uint16 offset=0 min=0 max=1 m=0.00001526 b=0 units="dl" format=6.0 help="EST Dwell Start Fraction" +EXTERN TEPMAPI_ttEventTime EST_tDwellUs; +//ASAM mode=readvalue name="EST Dwell Fraction" type=uint16 offset=0 min=0 max=1 m=0.00001526 b=0 units="dl" format=6.0 help="EST Dwell Fraction" +EXTERN GPM6_ttMTheta EST_tIgnitionAdvanceMtheta; +EXTERN GPM6_ttMTheta EST_tIgnitionAdvanceMthetaBTDC; +//ASAM mode=readvalue name="EST Ignition Advance" type=uint32 offset=0 min=0 max=50 m=0.001 b=0 units="degrees" format=5.3 help="EST Ignition Advance" + +EXTERN EST_tenIgnitionTimingRequest EST_enIgnitionTimingRequest; +//ASAM mode=readvalue name="EST Timing Request Mode" type=uint16 offset=0 min=0 max=10 units="ENUMERATION PRIMARY=0 STAGE1=1 STAGE2=2 STAGE3=3 STAGE4=4" format=1.0 help="EST Dwell Start Fraction" + + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void EST_vStart(uint32 * const pu32Arg); +void EST_vRun(uint32* const pu32Arg); +void EST_vTerminate(uint32* const pu32Arg); +void EST_vCallBack(puint32 const pu32Arg); + + +#endif // EST_H + diff --git a/source/Client/FILM.c b/source/Client/FILM.c new file mode 100644 index 0000000..09ec56a --- /dev/null +++ b/source/Client/FILM.c @@ -0,0 +1,109 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Fuel Film Model */ +/* DESCRIPTION: This code module calculates the fuel film load */ +/* for manifold wetting compensation */ +/* */ +/* FILE NAME: FILM.c */ +/* REVISION HISTORY: 28-04-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _FILM_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "MAP.h" + + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +GPM6_ttNg FILM_tFilmLoadUg; +GPM6_ttNg FILM_tFilmLoadUgOld; +sint32 FILM_s32FilmLoadUgDelta; +uint32 FILM_u32FilmCallCount; + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void FILM_vStart(puint32 const pu32Arg) +{ + FILM_tFilmLoadUg = 0; + FILM_tFilmLoadUgOld = 0; + FILM_u32FilmCallCount = 0; + FILM_s32FilmLoadUgDeltaApplied = 0; +} + +void FILM_vRun(puint32 const pu32Arg) +{ + sint32 s32Temp; + uint32 u32Temp; + + FILM_u32FilmCallCount++; + + if (0 < CAM_u32RPMRaw) + { + /* Accumulate film with TPS based wall impact coefficient */ + u32Temp = (TPS_tThetaFiltered + 5000) / 950u; + u32Temp *= FUEL_tPredictedFuelFlowUg; + u32Temp /= 10000u; + u32Temp += FILM_tFilmLoadUg; + } + else + { + u32Temp = FILM_tFilmLoadUg; + } + + + /* Temporary film evaporation code */ + s32Temp = CTS_tTempCFiltered + (110000 - MAP_tKiloPaFiltered); + s32Temp /= 5000; + s32Temp = 1000 - s32Temp; + u32Temp /= 100; + u32Temp *= ((uint32)s32Temp); + u32Temp /= 100; + + FILM_tFilmLoadUg = MIN(u32Temp, 15000000); + + if (0 == (FILM_u32FilmCallCount % 0x2)) + { + FILM_s32FilmLoadUgDelta = (sint32)FILM_tFilmLoadUg - (sint32)FILM_tFilmLoadUgOld; + FILM_tFilmLoadUgOld = FILM_tFilmLoadUg; + } + + /* Clip the accumulate / evaporate derivative */ + if (0 <= FILM_s32FilmLoadUgDelta) + { + s32Temp = (500 > FILM_s32FilmLoadUgDelta) ? + 0 : 20 * FILM_s32FilmLoadUgDelta; + FILM_s32FilmLoadUgDeltaApplied = (80000 < s32Temp) ? + 80000 : s32Temp; + } + else + { + s32Temp = (-500 < FILM_s32FilmLoadUgDelta) ? + 0 : 20 * FILM_s32FilmLoadUgDelta; + FILM_s32FilmLoadUgDeltaApplied = (-80000 > s32Temp) ? + -80000 : s32Temp; + } +} + +void FILM_vTerminate(puint32 const pu32Arg) +{ + +} + + +void FILM_vCallBack(puint32 const pu32Arg) +{ + +} + + +#endif //BUILD_USER diff --git a/source/Client/FILM.h b/source/Client/FILM.h new file mode 100644 index 0000000..03d9ff0 --- /dev/null +++ b/source/Client/FILM.h @@ -0,0 +1,43 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Fuel Film Model Header File */ +/* DESCRIPTION: This code module calculates the fuel film load */ +/* for manifold wetting compensation */ +/* */ +/* FILE NAME: FILM.h */ +/* REVISION HISTORY: 28-04-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef FILM_H +#define FILM_H + +#include +#include "IOAPI.h" +#include "USER.h" + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ + + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _FILM_C + #define EXTERN +#else + #define EXTERN extern +#endif + + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +EXTERN sint32 FILM_s32FilmLoadUgDeltaApplied; + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void FILM_vStart(uint32 * const pu32Arg); +void FILM_vRun(uint32* const pu32Arg); +void FILM_vTerminate(uint32* const pu32Arg); +void FILM_vCallBack(puint32 const pu32Arg); + +#endif // MAP_H diff --git a/source/Client/FME.c b/source/Client/FME.c new file mode 100644 index 0000000..f349d5c --- /dev/null +++ b/source/Client/FME.c @@ -0,0 +1,148 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: FME */ +/* DESCRIPTION: This code assist with failure mode effects */ +/* processing */ +/* */ +/* FILE NAME: FME.c */ +/* REVISION HISTORY: 24-06-2020 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _FME_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "FME.h" + + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +const FME_tstDiagControlData FME_astDiagControlData[FME_enDiagCount] = FME_nControlData; +FME_tstDiagRunningData FME_astDiagRunningData[FME_enDiagCount]; +//ASAM mode=readvalue name="PPS Rationality Fault" parent="FME_astDiagRunningData" type=uint16 offset=8 min=0 max=2 units="ENUMERATION NO_FAULT=0 FAULT_ACTIVE=1 FAULT_CLEARED=2" format=3.0 help="FAULT" +//ASAM mode=readvalue name="Throttle Rationality Fault" parent="FME_astDiagRunningData" type=uint16 offset=20 min=0 max=2 units="ENUMERATION NO_FAULT=0 FAULT_ACTIVE=1 FAULT_CLEARED=2" format=3.0 help="FAULT" +//ASAM mode=readvalue name="TPSM Fault" parent="FME_astDiagRunningData" type=uint16 offset=32 min=0 max=2 units="ENUMERATION NO_FAULT=0 FAULT_ACTIVE=1 FAULT_CLEARED=2" format=3.0 help="FAULT" +//ASAM mode=readvalue name="PPSM Fault" parent="FME_astDiagRunningData" type=uint16 offset=44 min=0 max=2 units="ENUMERATION NO_FAULT=0 FAULT_ACTIVE=1 FAULT_CLEARED=2" format=3.0 help="FAULT" +//ASAM mode=readvalue name="PPSS Fault" parent="FME_astDiagRunningData" type=uint16 offset=56 min=0 max=2 units="ENUMERATION NO_FAULT=0 FAULT_ACTIVE=1 FAULT_CLEARED=2" format=3.0 help="FAULT" + + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ +static void FME_vConditionFault(FME_tenDiags, bool); + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void FME_enUpdateDiagState(FME_tenDiags enDiags, uint32 u32Data1, uint32 u32Data2) +{ + switch (FME_astDiagControlData[enDiags].enDiagtype) + { + case FME_enRelationship: + { + if (FME_enPPSPair == enDiags) + { + uint32 u32Temp = (500 * u32Data1) / u32Data2; + + FME_astDiagRunningData[enDiags].u32FilterData = + u32Temp / 8 + 7 * (FME_astDiagRunningData[enDiags].u32FilterData / 8); + + if ((800 > FME_astDiagRunningData[enDiags].u32FilterData) || + (1200 < FME_astDiagRunningData[enDiags].u32FilterData)) + { + FME_vConditionFault(enDiags, TRUE); + } + else + { + FME_vConditionFault(enDiags, FALSE); + } + } + if (FME_enPedalTransfer == enDiags) + { + if (u32Data1 < u32Data2) + { + FME_vConditionFault(enDiags, TRUE); + } + else + { + FME_vConditionFault(enDiags, FALSE); + } + } + break; + } + case FME_enSingle: + { + FME_astDiagRunningData[enDiags].u32FilterData = + u32Data1 / 4 + 3 * (FME_astDiagRunningData[enDiags].u32FilterData / 4); + + if ((FME_astDiagControlData[enDiags].u32FilterDataMin > FME_astDiagRunningData[enDiags].u32FilterData) || + (FME_astDiagControlData[enDiags].u32FilterDataMax < FME_astDiagRunningData[enDiags].u32FilterData)) + { + FME_vConditionFault(enDiags, TRUE); + } + else + { + FME_vConditionFault(enDiags, FALSE); + } + break; + } + default: + { + break; + } + } +} + +inline FME_tenFaultState FME_enGetDiagState(FME_tenDiags enDiags) +{ + return FME_astDiagRunningData[enDiags].enFaultState; +} + +static void FME_vConditionFault(FME_tenDiags enDiags, bool boFaultActive) +{ + if (TRUE == boFaultActive) + { + FME_astDiagRunningData[enDiags].u32FaultCounts = + FME_astDiagControlData[enDiags].u32FaultCountLimit > FME_astDiagRunningData[enDiags].u32FaultCounts ? + FME_astDiagRunningData[enDiags].u32FaultCounts + 1 : + FME_astDiagRunningData[enDiags].u32FaultCounts; + } + else + { + FME_astDiagRunningData[enDiags].u32FaultCounts = + 0 < FME_astDiagRunningData[enDiags].u32FaultCounts ? + FME_astDiagRunningData[enDiags].u32FaultCounts - 1 : + FME_astDiagRunningData[enDiags].u32FaultCounts; + } + + if ((FME_enNoFault == FME_astDiagRunningData[enDiags].enFaultState) && + (FME_astDiagControlData[enDiags].u32FaultCountLimit == FME_astDiagRunningData[enDiags].u32FaultCounts)) + { + FME_astDiagRunningData[enDiags].enFaultState = FME_enFaultActive; + } + else if ((FME_enFaultCleared == FME_astDiagRunningData[enDiags].enFaultState) && + (FME_astDiagControlData[enDiags].u32FaultCountLimit == FME_astDiagRunningData[enDiags].u32FaultCounts)) + { + FME_astDiagRunningData[enDiags].enFaultState = FME_enFaultActive; + } + else if ((FME_enFaultActive == FME_astDiagRunningData[enDiags].enFaultState) && + (0 == FME_astDiagRunningData[enDiags].u32FaultCounts)) + { + FME_astDiagRunningData[enDiags].enFaultState = FME_enFaultCleared; + } +} + +void FME_vDiagClearHistory(void) +{ + uint32 u32FaultIDX; + + for (u32FaultIDX = 0; u32FaultIDX < FME_enDiagCount; u32FaultIDX++) + { + FME_astDiagRunningData[u32FaultIDX].enFaultState = FME_enNoFault; + } +} + +#endif //BUILD_USER diff --git a/source/Client/FME.h b/source/Client/FME.h new file mode 100644 index 0000000..16ffec1 --- /dev/null +++ b/source/Client/FME.h @@ -0,0 +1,83 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: FME Header */ +/* DESCRIPTION: This code assist with failure mode effects */ +/* processing */ +/* */ +/* FILE NAME: FME.c */ +/* REVISION HISTORY: 24-06-2020 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef FME_H +#define FME_H + +#include +#include "IOAPI.h" +#include "USER.h" +#include "SYS.h" + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +typedef enum +{ + FME_enPPSPair, + FME_enPedalTransfer, + FME_enTPSMSingle, + FME_enPPSMSingle, + FME_enPPSSSingle, + FME_enDiagCount +} FME_tenDiags; + +typedef enum +{ + FME_enRelationship, + FME_enSingle, + FME_enDiagTypesCount +} FME_tenDiagTypes; + +typedef enum +{ + FME_enNoFault, + FME_enFaultActive, + FME_enFaultCleared +} FME_tenFaultState; + +typedef struct +{ + FME_tenDiagTypes enDiagtype; + uint32 u32FilterDataMin; + uint32 u32FilterDataMax; + uint32 u32FaultCountLimit; +} FME_tstDiagControlData; + +typedef struct +{ + uint32 u32FilterData; + uint32 u32FaultCounts; + FME_tenFaultState enFaultState; +} FME_tstDiagRunningData; + +#define FME_nControlData \ +{ \ + {FME_enRelationship, 800, 3000, 200},\ + {FME_enRelationship, 800, 3000, 500},\ + {FME_enSingle, 250, 2900, 30},\ + {FME_enSingle, 250, 2900, 30},\ + {FME_enSingle, 190, 1450, 30},\ +}\ + +#define FME_nBLIP_THROTTLE_DELTA_MAX 1000 +#define FME_nOVERRIDE_DELTA_MAX 500 + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ + + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void FME_enUpdateDiagState(FME_tenDiags enDiags, uint32 u32Data1, uint32 u32Data2); +FME_tenFaultState FME_enGetDiagState(FME_tenDiags enDiags); +void FME_vDiagClearHistory(void); + +#endif // FME_H + diff --git a/source/Client/FUEL.c b/source/Client/FUEL.c new file mode 100644 index 0000000..d590fb1 --- /dev/null +++ b/source/Client/FUEL.c @@ -0,0 +1,1246 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Fuelling */ +/* DESCRIPTION: This code module initialises the required */ +/* resources and functions for fuelling calculations */ +/* measurement */ +/* FILE NAME: FUEL.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _FUEL_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "FUEL.h" + +#ifdef BUILD_FME +#include "FME.h" +#endif + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +TEPMAPI_tstTimedKernelEvent FUEL_astTimedHoldKernelEvents[2]; +TEPMAPI_tstTimedKernelEvent FUEL_astTimedFuelPumpEvents[100]; +SPREADAPI_ttSpreadIDX FUEL_tSpreadAfmTFIDX; +SPREADAPI_ttSpreadIDX FUEL_tSpreadTAFRxIDX; +SPREADAPI_ttSpreadIDX FUEL_tSpreadTAFRyIDX; +SPREADAPI_ttSpreadIDX FUEL_tSpreadFuelFlowIDX; +SPREADAPI_ttSpreadIDX FUEL_tSpreadTFuelPressurexIDX; +SPREADAPI_ttSpreadIDX FUEL_tSpreadTFuelPressureyIDX; +SPREADAPI_ttSpreadIDX FUEL_tSpreadCrankingAirflowIDX; +SPREADAPI_ttSpreadIDX FUEL_tSpreadInjResponseIDX; +SPREADAPI_ttSpreadIDX FUEL_tSpreadInjShortOpeningIDX; +SPREADAPI_ttSpreadIDX FUEL_tSpreadFuelCutsIDX; +TABLEAPI_ttTableIDX FUEL_tTableCrankingAirflowIDX; +TABLEAPI_ttTableIDX FUEL_tTableAfmTFIDX; +TABLEAPI_ttTableIDX FUEL_tTableInjResponseIDX; +TABLEAPI_ttTableIDX FUEL_tTableInjShortOpeningIDX; +TABLEAPI_ttTableIDX FUEL_tTableFuelFlowIDX; +TABLEAPI_ttTableIDX FUEL_tTableFuelCutsIDX; +MAPSAPI_ttMapIDX FUEL_tMapTAFRIDX; +MAPSAPI_ttMapIDX FUEL_tMapTFuelPressureIDX; +uint16 FUEL_u16InjResponse; +uint16 FUEL_u16TFuelPressure; +uint16 FUEL_u16CrankingAirflow; +uint32 FUEL_u32SensorStateBank2; +bool FUEL_boCalculatePending; +bool FUEL_bo720Injection; +uint32 u32SequenceIDX; +uint32 FUEL_u32ADCRaw; +uint32 FUEL_u32ADCFiltered; +bool FUEL_boNewSample; +uint16 FUEL_u16FuelFlowRate; +uint32 FUEL_u32FuelChannelsMask; +uint32 FUEL_u32FuelChannelsCount; + + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ +static void FUEL_vTEPMCallBack(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime); +static void FUEL_vCyclicCalculate(void); +static void FUEL_vADCCallBack(IOAPI_tenEHIOResource, uint32); +static void FUEL_vCalcFuelChannels(void); + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void FUEL_vStart(puint32 const pu32Arg) +{ + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenEHIOType enEHIOType; + TEPMAPI_tstTEPMChannelCB stTEPMChannelCB; + IOAPI_tenDriveStrength enDriveStrength; + uint32 u32EventCount; + ADCAPI_tstADCCB stADCCB; + + FUEL_u32ADCRaw = 0; + FUEL_boNewSample = false; + FUEL_u32FuelChannelsMask = 0; + + if (EH_IO_Invalid != USERCAL_stRAMCAL.u16FRSADResource) + { + enEHIOResource = USERCAL_stRAMCAL.u16FRSADResource; + enEHIOType = IOAPI_enADSE; + stADCCB.enSamplesAv = ADCAPI_en32Samples; + stADCCB.pfResultCB = &FUEL_vADCCallBack; + stADCCB.enTrigger = ADCAPI_enTrigger4; + + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stADCCB); + + if (SYSAPI_enOK != pstSVCDataStruct->enSVCResult) + { + *pu32Arg |= (uint32)SYSAPI_enResourceRequestFailed;/*CR1_13*/ + } + } + else + { + *pu32Arg |= (uint32)SYSAPI_enResourceInitFailed;/*CR1_13*/ + } + } + + + /* Setup fuel pump relay */ + if (EH_IO_Invalid != USERCAL_stRAMCAL.enFuelPumpRelay) + { + enEHIOResource = USERCAL_stRAMCAL.enFuelPumpRelay; + enEHIOType = IOAPI_enDIOOutput; + enDriveStrength = IOAPI_enWeak; + + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + SETUP_vSetDigitalIOHigh(enEHIOResource); + } + + + /* Both peak and hold have a switch on and switch off event per cycle */ + TEPMAPI_ttEventCount tEventCount = 2; + + /* Initialise the GDI fuel pump control parameters */ + FUEL_tStartFPSolenoidDelay = 100; + FUEL_tStartFPSolenoidPeak = 15000; + FUEL_tStartFPSolenoidDutyHigh = 180;//160; + FUEL_tStartFPSolenoidDutyLow = 100;//140; + FUEL_tFPAccumulate = 9000; + FUEL_u16TFuelPressure = 12000; + + /* Set injection time to Xms */ + FUEL_tTimeHoldUs[0] = 1000; + FUEL_tTimeHoldUs[1] = 1000; + FUEL_tTimeHoldUs[2] = 1000; + FUEL_tTimeHoldUs[3] = 1000; + FUEL_tTimeHoldUs[4] = 1000; + FUEL_tTimeHoldUs[5] = 1000; + FUEL_tTimeHoldUs[6] = 1000; + FUEL_tTimeHoldUs[7] = 1000; + + FUEL_tTimeHold[0] = FUEL_xUsToSlowTicks(FUEL_tTimeHoldUs[0]); + FUEL_tTimeHold[1] = FUEL_xUsToSlowTicks(FUEL_tTimeHoldUs[1]); + FUEL_tTimeHold[2] = FUEL_xUsToSlowTicks(FUEL_tTimeHoldUs[2]); + FUEL_tTimeHold[3] = FUEL_xUsToSlowTicks(FUEL_tTimeHoldUs[3]); + FUEL_tTimeHold[4] = FUEL_xUsToSlowTicks(FUEL_tTimeHoldUs[4]); + FUEL_tTimeHold[5] = FUEL_xUsToSlowTicks(FUEL_tTimeHoldUs[5]); + FUEL_tTimeHold[6] = FUEL_xUsToSlowTicks(FUEL_tTimeHoldUs[6]); + FUEL_tTimeHold[7] = FUEL_xUsToSlowTicks(FUEL_tTimeHoldUs[7]); + + /* Set injection phase to 360 degrees */ + FUEL_tStartHoldFraction[0] = (0x10000 * 2) / 720; + FUEL_tStartHoldFraction[1] = (0x10000 * 2) / 720; + FUEL_tStartHoldFraction[2] = (0x10000 * 2) / 720; + FUEL_tStartHoldFraction[3] = (0x10000 * 2) / 720; + FUEL_tStartHoldFraction[4] = (0x10000 * 2) / 720; + FUEL_tStartHoldFraction[5] = (0x10000 * 5) / 720; + FUEL_tStartHoldFraction[6] = (0x10000 * 5) / 720; + FUEL_tStartHoldFraction[7] = (0x10000 * 5) / 720; + + /* Request and initialise Fuel Injector group A */ + if ((0xffff > USERCAL_stRAMCAL.au32InjectionSequence[0]) && (EH_IO_Invalid > USERCAL_stRAMCAL.aFuelIOResource[0])) + { + enEHIOResource = USERCAL_stRAMCAL.aFuelIOResource[0]; //FUEL_nInj1Output; + enEHIOType = IOAPI_enCaptureCompare; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + /* Initialise the TEPM channel Fuel Injector group A */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMChannelCB.enAction = TEPMAPI_enSetLow; + stTEPMChannelCB.boInterruptEnable = TRUE; + stTEPMChannelCB.boAsyncRequestEnable = TRUE; + stTEPMChannelCB.u32Sequence = USERCAL_stRAMCAL.au32InjectionSequence[0]; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMChannelCB); + } + + /* Switch injector on at a fraction of global time */ + FUEL_astTimedHoldKernelEvents[0].enAction = TEPMAPI_enSetHigh; + FUEL_astTimedHoldKernelEvents[0].enMethod = TEPMAPI_enGlobalLinkedFraction; + FUEL_astTimedHoldKernelEvents[0].ptEventTime = &FUEL_tStartHoldFraction[0]; + FUEL_astTimedHoldKernelEvents[0].enEHIOBitMirrorResource = EH_IO_Invalid; + + /* Switch injector off at timer ms */ + FUEL_astTimedHoldKernelEvents[1].enAction = TEPMAPI_enSetLow; + FUEL_astTimedHoldKernelEvents[1].enMethod = TEPMAPI_enHardLinkedTimeStep; + FUEL_astTimedHoldKernelEvents[1].ptEventTime = &FUEL_tTimeHold[0]; + FUEL_astTimedHoldKernelEvents[1].pfEventCB = FUEL_vTEPMCallBack; + FUEL_astTimedHoldKernelEvents[1].enEHIOBitMirrorResource = EH_IO_Invalid; + + USER_vSVC(SYSAPI_enConfigureKernelTEPMOutput, (void*)&enEHIOResource, + (void*)&FUEL_astTimedHoldKernelEvents[0], (void*)&tEventCount); + + if ((EH_IO_TMR1 <= USERCAL_stRAMCAL.aFuelIOResource[0]) && + (EH_IO_TMR16 >= USERCAL_stRAMCAL.aFuelIOResource[0])) + { + FUEL_u32FuelChannelsMask |= + (1 << (USERCAL_stRAMCAL.aFuelIOResource[0] - EH_IO_TMR1)); + } + } + + /* Request and initialise Fuel Injector group B */ + if ((0xffff > USERCAL_stRAMCAL.au32InjectionSequence[1]) && (EH_IO_Invalid > USERCAL_stRAMCAL.aFuelIOResource[1])) + { + enEHIOResource = USERCAL_stRAMCAL.aFuelIOResource[1]; //FUEL_nInj2Output; + enEHIOType = IOAPI_enCaptureCompare; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + /* Initialise the TEPM channel Fuel Injector group B */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMChannelCB.enAction = TEPMAPI_enSetLow; + stTEPMChannelCB.boInterruptEnable = TRUE; + stTEPMChannelCB.boAsyncRequestEnable = TRUE; + stTEPMChannelCB.u32Sequence = USERCAL_stRAMCAL.au32InjectionSequence[1]; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMChannelCB); + } + + /* Switch injector on at a fraction of global time */ + FUEL_astTimedHoldKernelEvents[0].enAction = TEPMAPI_enSetHigh; + FUEL_astTimedHoldKernelEvents[0].enMethod = TEPMAPI_enGlobalLinkedFraction; + FUEL_astTimedHoldKernelEvents[0].ptEventTime = &FUEL_tStartHoldFraction[1]; + FUEL_astTimedHoldKernelEvents[0].enEHIOBitMirrorResource = EH_IO_Invalid; + + /* Switch injector off at timer ms */ + FUEL_astTimedHoldKernelEvents[1].enAction = TEPMAPI_enSetLow; + FUEL_astTimedHoldKernelEvents[1].enMethod = TEPMAPI_enHardLinkedTimeStep; + FUEL_astTimedHoldKernelEvents[1].ptEventTime = &FUEL_tTimeHold[1]; + FUEL_astTimedHoldKernelEvents[1].pfEventCB = FUEL_vTEPMCallBack; + FUEL_astTimedHoldKernelEvents[1].enEHIOBitMirrorResource = EH_IO_Invalid; + + USER_vSVC(SYSAPI_enConfigureKernelTEPMOutput, (void*)&enEHIOResource, + (void*)&FUEL_astTimedHoldKernelEvents[0], (void*)&tEventCount); + + if ((EH_IO_TMR1 <= USERCAL_stRAMCAL.aFuelIOResource[1]) && + (EH_IO_TMR16 >= USERCAL_stRAMCAL.aFuelIOResource[1])) + { + FUEL_u32FuelChannelsMask |= + (1 << (USERCAL_stRAMCAL.aFuelIOResource[1] - EH_IO_TMR1)); + } + } + + /* Request and initialise Fuel Injector group C */ + if ((0xffff > USERCAL_stRAMCAL.au32InjectionSequence[2]) && (EH_IO_Invalid > USERCAL_stRAMCAL.aFuelIOResource[2])) + { + enEHIOResource = USERCAL_stRAMCAL.aFuelIOResource[2]; //FUEL_nInj3Output; + enEHIOType = IOAPI_enCaptureCompare; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + /* Initialise the TEPM channel Fuel Injector group C */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMChannelCB.enAction = TEPMAPI_enSetLow; + stTEPMChannelCB.boInterruptEnable = TRUE; + stTEPMChannelCB.boAsyncRequestEnable = TRUE; + stTEPMChannelCB.u32Sequence = USERCAL_stRAMCAL.au32InjectionSequence[2]; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMChannelCB); + } + + /* Switch injector on at a fraction of global time */ + FUEL_astTimedHoldKernelEvents[0].enAction = TEPMAPI_enSetHigh; + FUEL_astTimedHoldKernelEvents[0].enMethod = TEPMAPI_enGlobalLinkedFraction; + FUEL_astTimedHoldKernelEvents[0].ptEventTime = &FUEL_tStartHoldFraction[2]; + FUEL_astTimedHoldKernelEvents[0].enEHIOBitMirrorResource = EH_IO_Invalid; + + /* Switch injector off at timer ms */ + FUEL_astTimedHoldKernelEvents[1].enAction = TEPMAPI_enSetLow; + FUEL_astTimedHoldKernelEvents[1].enMethod = TEPMAPI_enHardLinkedTimeStep; + FUEL_astTimedHoldKernelEvents[1].ptEventTime = &FUEL_tTimeHold[2]; + FUEL_astTimedHoldKernelEvents[1].pfEventCB = FUEL_vTEPMCallBack; + FUEL_astTimedHoldKernelEvents[1].enEHIOBitMirrorResource = EH_IO_Invalid; + + USER_vSVC(SYSAPI_enConfigureKernelTEPMOutput, (void*)&enEHIOResource, + (void*)&FUEL_astTimedHoldKernelEvents[0], (void*)&tEventCount); + + if ((EH_IO_TMR1 <= USERCAL_stRAMCAL.aFuelIOResource[2]) && + (EH_IO_TMR16 >= USERCAL_stRAMCAL.aFuelIOResource[2])) + { + FUEL_u32FuelChannelsMask |= + (1 << (USERCAL_stRAMCAL.aFuelIOResource[2] - EH_IO_TMR1)); + } + } + + /* Initialise the TEPM channel Fuel Injector group D */ + if ((0xffff > USERCAL_stRAMCAL.au32InjectionSequence[3]) && (EH_IO_Invalid > USERCAL_stRAMCAL.aFuelIOResource[3])) + { + enEHIOResource = USERCAL_stRAMCAL.aFuelIOResource[3]; //FUEL_nInj4Output; + enEHIOType = IOAPI_enCaptureCompare; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + /* Initialise the TEPM channel Fuel Injector group D */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMChannelCB.enAction = TEPMAPI_enSetLow; + stTEPMChannelCB.boInterruptEnable = TRUE; + stTEPMChannelCB.boAsyncRequestEnable = TRUE; + stTEPMChannelCB.u32Sequence = USERCAL_stRAMCAL.au32InjectionSequence[3]; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMChannelCB); + } + + /* Switch injector on at a fraction of global time */ + FUEL_astTimedHoldKernelEvents[0].enAction = TEPMAPI_enSetHigh; + FUEL_astTimedHoldKernelEvents[0].enMethod = TEPMAPI_enGlobalLinkedFraction; + FUEL_astTimedHoldKernelEvents[0].ptEventTime = &FUEL_tStartHoldFraction[3]; + FUEL_astTimedHoldKernelEvents[0].enEHIOBitMirrorResource = EH_IO_Invalid; + + /* Switch injector off at timer ms */ + FUEL_astTimedHoldKernelEvents[1].enAction = TEPMAPI_enSetLow; + FUEL_astTimedHoldKernelEvents[1].enMethod = TEPMAPI_enHardLinkedTimeStep; + FUEL_astTimedHoldKernelEvents[1].ptEventTime = &FUEL_tTimeHold[3]; + FUEL_astTimedHoldKernelEvents[1].pfEventCB = FUEL_vTEPMCallBack; + FUEL_astTimedHoldKernelEvents[1].enEHIOBitMirrorResource = EH_IO_Invalid; + + USER_vSVC(SYSAPI_enConfigureKernelTEPMOutput, (void*)&enEHIOResource, + (void*)&FUEL_astTimedHoldKernelEvents[0], (void*)&tEventCount); + + if ((EH_IO_TMR1 <= USERCAL_stRAMCAL.aFuelIOResource[3]) && + (EH_IO_TMR16 >= USERCAL_stRAMCAL.aFuelIOResource[3])) + { + FUEL_u32FuelChannelsMask |= + (1 << (USERCAL_stRAMCAL.aFuelIOResource[3] - EH_IO_TMR1)); + } + } + + /* Initialise the Fuel Pressure Solenoid free-wheel enable*/ + enEHIOResource = EH_IO_GP5; + enEHIOType = IOAPI_enDIOOutput; + enDriveStrength = IOAPI_enStrong; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + + /* Initialise the TEPM channel Fuel Pressure Solenoid */ + if (EH_IO_Invalid > USERCAL_stRAMCAL.u16FuelPressureSolenoidResource) + { + enEHIOResource = USERCAL_stRAMCAL.u16FuelPressureSolenoidResource; + enEHIOType = IOAPI_enCaptureCompare; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + /* Initialise the TEPM channel Fuel Pressure Solenoid */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMChannelCB.enAction = TEPMAPI_enSetLow; + stTEPMChannelCB.boInterruptEnable = TRUE; + stTEPMChannelCB.boAsyncRequestEnable = TRUE; + stTEPMChannelCB.u32Sequence = 0x0000080; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMChannelCB); + } + + /* Switch injector on at a fraction of global time */ + FUEL_astTimedFuelPumpEvents[0].enAction = TEPMAPI_enSetHigh; + FUEL_astTimedFuelPumpEvents[0].enMethod = TEPMAPI_enGlobalLinkedTimeStep;//TEPMAPI_enGlobalLinkedFraction; + FUEL_astTimedFuelPumpEvents[0].ptEventTime = &FUEL_tStartFPSolenoidDelay; + FUEL_astTimedFuelPumpEvents[0].enEHIOBitMirrorResource = EH_IO_GP5; + + FUEL_astTimedFuelPumpEvents[1].enAction = TEPMAPI_enSetLow; + FUEL_astTimedFuelPumpEvents[1].enMethod = TEPMAPI_enHardLinkedTimeStep; + FUEL_astTimedFuelPumpEvents[1].ptEventTime = &FUEL_tStartFPSolenoidPeak; + FUEL_astTimedFuelPumpEvents[1].pfEventCB = FUEL_vTEPMCallBack; + FUEL_astTimedFuelPumpEvents[1].enEHIOBitMirrorResource = EH_IO_GP5; + FUEL_astTimedFuelPumpEvents[1].ptAccumulate = &FUEL_tFPAccumulate; + + for (u32EventCount = 1; u32EventCount <= 48; u32EventCount++) + { + FUEL_astTimedFuelPumpEvents[2 * u32EventCount].enAction = TEPMAPI_enSetHigh; + FUEL_astTimedFuelPumpEvents[2 * u32EventCount].enMethod = TEPMAPI_enHardLinkedTimeStep; + FUEL_astTimedFuelPumpEvents[2 * u32EventCount].ptEventTime = &FUEL_tStartFPSolenoidDutyLow; + FUEL_astTimedFuelPumpEvents[2 * u32EventCount].pfEventCB = FUEL_vTEPMCallBack; + FUEL_astTimedFuelPumpEvents[2 * u32EventCount].enEHIOBitMirrorResource = EH_IO_GP5; + FUEL_astTimedFuelPumpEvents[2 * u32EventCount].ptAccumulate = &FUEL_tFPAccumulate; + + FUEL_astTimedFuelPumpEvents[2 * u32EventCount + 1].enAction = TEPMAPI_enSetLow; + FUEL_astTimedFuelPumpEvents[2 * u32EventCount + 1].enMethod = TEPMAPI_enHardLinkedTimeStep; + FUEL_astTimedFuelPumpEvents[2 * u32EventCount + 1].ptEventTime = &FUEL_tStartFPSolenoidDutyHigh; + FUEL_astTimedFuelPumpEvents[2 * u32EventCount + 1].pfEventCB = FUEL_vTEPMCallBack; + FUEL_astTimedFuelPumpEvents[2 * u32EventCount + 1].enEHIOBitMirrorResource = EH_IO_GP5; + FUEL_astTimedFuelPumpEvents[2 * u32EventCount + 1].ptAccumulate = &FUEL_tFPAccumulate; + } + + tEventCount = 98; + + USER_vSVC(SYSAPI_enConfigureKernelTEPMOutput, (void*)&enEHIOResource, + (void*)&FUEL_astTimedFuelPumpEvents[0], (void*)&tEventCount); + } + + /* Request and initialise required Kernel managed spread for AfmTF */ + FUEL_tSpreadAfmTFIDX = SETUP_tSetupSpread((void*)&FUEL_nXAFMAxisRef, (void*)&USERCAL_stRAMCAL.aUserCURVEAfmTFSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for AfmTF */ + FUEL_tTableAfmTFIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserCURVEAfmTFTable, (void*)&AFM_tAirFlowAFMRawUg, TYPE_enUInt32, 17, FUEL_tSpreadAfmTFIDX, NULL); + + /* Request and initialise required Kernel managed spread for Fuel Flow */ + FUEL_tSpreadFuelFlowIDX = SETUP_tSetupSpread((void*)&FUEL_tKiloPaFiltered, (void*)&USERCAL_stRAMCAL.aUserFuelFlowRateSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for Fuel Flow */ + FUEL_tTableFuelFlowIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserFuelFlowRateTable, (void*)&FUEL_u16FuelFlowRate, TYPE_enUInt16, 17, FUEL_tSpreadFuelFlowIDX, NULL); + + /* Request and initialise required Kernel managed spread for TAFRx */ + FUEL_tSpreadTAFRxIDX = SETUP_tSetupSpread((void*)&CAM_u32RPMFiltered, (void*)&USERCAL_stRAMCAL.aUserTAFRxSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for TAFRy */ + FUEL_tSpreadTAFRyIDX = SETUP_tSetupSpread((void*)&MAP_tKiloPaFiltered, (void*)&USERCAL_stRAMCAL.aUserTAFRySpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed map for TAFR */ + FUEL_tMapTAFRIDX = SETUP_tSetupMap((void*)&USERCAL_stRAMCAL.aUserMAPTAFR, (void*)&FUEL_u16TAFR, TYPE_enUInt16, 17, 17, FUEL_tSpreadTAFRxIDX, FUEL_tSpreadTAFRyIDX, NULL); + + /* Request and initialise required Kernel managed spread for injector response */ + FUEL_tSpreadInjResponseIDX = SETUP_tSetupSpread((void*)&BVM_tBattVolts, (void*)&USERCAL_stRAMCAL.aUserInjResponseSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for injector response */ + FUEL_tTableInjResponseIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserInjResponseTable, (void*)&FUEL_u16InjResponse, TYPE_enUInt16, 17, FUEL_tSpreadInjResponseIDX, NULL); + + /* Request and initialise required Kernel managed spread for cranking airflow */ + FUEL_tSpreadCrankingAirflowIDX = SETUP_tSetupSpread((void*)&CAM_u32RPMRaw, (void*)&USERCAL_stRAMCAL.aUserCrankingAirflowSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for cranking airflow */ + FUEL_tTableCrankingAirflowIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserCrankingAirflowTable, (void*)&FUEL_u16CrankingAirflow, TYPE_enUInt16, 17, FUEL_tSpreadCrankingAirflowIDX, NULL); + + /* Request and initialise required Kernel managed spread for injector short opening */ + FUEL_tSpreadInjShortOpeningIDX = SETUP_tSetupSpread((void*)&FUEL_tTimePredictedUsInput, (void*)&USERCAL_stRAMCAL.aUserInjShortOpeningSpread, TYPE_enUInt32, 11, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for injector short opening */ + FUEL_tTableInjShortOpeningIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserInjShortOpeningTable, (void*)&FUEL_tTimePredictedShortOpeningUs, TYPE_enUInt32, 11, FUEL_tSpreadInjShortOpeningIDX, NULL); + + /* Request and initialise required Kernel managed spread for launch and flat shift fuel cuts */ + FUEL_tSpreadFuelCutsIDX = SETUP_tSetupSpread((void*)&CAM_u32RPMRaw, (void*)&USERCAL_stRAMCAL.aUserFuelCutsSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for launch and flat shift fuel cuts */ + FUEL_tTableFuelCutsIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserFuelCutsTable, (void*)&FUEL_u16FuelCutsPercent, TYPE_enUInt16, 17, FUEL_tSpreadFuelCutsIDX, NULL); + + + FUEL_bo720Injection = FALSE; + + for (u32SequenceIDX = 0; u32SequenceIDX < FUEL_nFuelSequenceCount; u32SequenceIDX++) + { + if (((USERCAL_stRAMCAL.au32InjectionSequence[u32SequenceIDX] & 0xff) == 0xff) || + ((USERCAL_stRAMCAL.au32InjectionSequence[u32SequenceIDX] & 0xff00) == 0xff00)) + { + FUEL_bo720Injection = TRUE; + } + } + + CLO2_vInit(); + FUEL_vCalcFuelChannels(); +} + +void FUEL_vRun(puint32 const pu32Arg) +{ + static uint32 u32FuelRunCount = 0; + static sint32 s32FuelPressureErrorSum; + static uint32 u32SampleCount = 0; + uint16 u16WDTVal; + IOAPI_tenTriState enTriState; + IOAPI_tenEHIOResource enEHIOResource; + RELAY_tenBit enBit; + uint32 u32Temp; + sint32 s32Temp; + static bool boFuelCutsActivePrev = FALSE; + bool boFuelCutsActive; + static bool boAirflowFMEEnable; + uint32 u32FuelCutPercent = 40; + + CLO2_vFilterSensors(); + + if (0 == u32FuelRunCount % FUEL_nInjRespCalcRate) + { + /* Calculate the current spread for injector response */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&FUEL_tSpreadInjResponseIDX, + NULL, NULL); + + /* Lookup the current value for injector response */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&FUEL_tTableInjResponseIDX, + NULL, NULL); + + /* Calculate the current spread for TAFRx */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&FUEL_tSpreadTAFRxIDX, + NULL, NULL); + + /* Calculate the current spread for TAFRy */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&FUEL_tSpreadTAFRyIDX, + NULL, NULL); + + /* Lookup the current value for TAFR */ + USER_vSVC(SYSAPI_enCalculateMap, (void*)&FUEL_tMapTAFRIDX, + NULL, NULL); + + /* Reset the WDT */ + USER_vSVC(SYSAPI_enResetWatchdog, &u16WDTVal, NULL, NULL); + } + + if ((TRUE == FUEL_boCalculatePending) + || (FALSE == FUEL_boFuelPrimed)) + + { + FUEL_vCyclicCalculate(); + + if (EH_IO_Invalid > USERCAL_stRAMCAL.u16FuelPressureSolenoidResource) + { + if (USERCAL_stRAMCAL.u32GDIMAPMin > MAP_tKiloPaFiltered) + { + FUEL_u16TFuelPressure = USERCAL_stRAMCAL.u16GDIPressureMin; + } + else if (USERCAL_stRAMCAL.u32GDIMAPMax < MAP_tKiloPaFiltered) + { + FUEL_u16TFuelPressure = USERCAL_stRAMCAL.u16GDIPressureMax; + } + else + { + FUEL_u16TFuelPressure = USERCAL_stRAMCAL.u16GDIPressureMin + + (((MAP_tKiloPaFiltered - USERCAL_stRAMCAL.u32GDIMAPMin) * (USERCAL_stRAMCAL.u16GDIPressureMax - USERCAL_stRAMCAL.u16GDIPressureMin)) / + (USERCAL_stRAMCAL.u32GDIMAPMax - USERCAL_stRAMCAL.u32GDIMAPMin)); + } + + + s32Temp = FUEL_tKiloPaFiltered - FUEL_u16TFuelPressure; + + if (0 > s32Temp) + { + /* accumulate the feedback error */ + s32FuelPressureErrorSum += ((s32Temp * 500) / (sint32)CAM_u32RPMRaw); + s32FuelPressureErrorSum = 20000 < s32FuelPressureErrorSum ? 20000 : s32FuelPressureErrorSum; + s32FuelPressureErrorSum = -20000 > s32FuelPressureErrorSum ? -20000 : s32FuelPressureErrorSum; + + /* pressure too low */ + s32Temp *= USERCAL_stRAMCAL.u16FuelPressurePGain; + s32Temp += (s32FuelPressureErrorSum * USERCAL_stRAMCAL.u16FuelPressureIGain / 4); + s32Temp += 10000000; + } + else if (2000 < s32Temp) + { + /* pressure more than 2000 kPa too high */ + s32Temp -= 2000; + + /* accumulate the feedback error */ + s32FuelPressureErrorSum += ((s32Temp * 500) / (sint32)CAM_u32RPMRaw); + s32FuelPressureErrorSum = 20000 < s32FuelPressureErrorSum ? 20000 : s32FuelPressureErrorSum; + s32FuelPressureErrorSum = -20000 > s32FuelPressureErrorSum ? -20000 : s32FuelPressureErrorSum; + + s32Temp *= USERCAL_stRAMCAL.u16FuelPressurePGain; + s32Temp += (s32FuelPressureErrorSum * USERCAL_stRAMCAL.u16FuelPressureIGain / 4); + s32Temp /= 2; + s32Temp += 10000000; + } + else + { + s32Temp = 10000000; + s32Temp += (s32FuelPressureErrorSum * USERCAL_stRAMCAL.u16FuelPressureIGain / 4); + } + + /* add feedforward guesstimate */ + s32Temp -= (USERCAL_stRAMCAL.u16GDIValveFF * ((CAM_u32RPMRaw * MAP_tKiloPaFiltered) / 1000000)); + s32Temp += 10000 * USERCAL_stRAMCAL.u16FuelPressureControlOffset; + + s32Temp = (1000 * (sint32)USERCAL_stRAMCAL.u16GDIValveMin) < s32Temp ? s32Temp : (1000 * (sint32)USERCAL_stRAMCAL.u16GDIValveMin); + s32Temp = (1000 * (sint32)USERCAL_stRAMCAL.u16GDIValveMax) > s32Temp ? s32Temp : (1000 * (sint32)USERCAL_stRAMCAL.u16GDIValveMax); + + FUEL_tFPAccumulate = s32Temp / CAM_u32RPMRaw; + FUEL_tFPAccumulate -= (CAM_u32RPMRaw / 16); + FUEL_tStartFPSolenoidDelay = (7000000 - 500 * CAM_u32RPMRaw) / CAM_u32RPMRaw; + } + } + + if ((TRUE == CTS_boCTSReady) + && (FALSE == FUEL_boFuelPrimed)) + { + if ((0 == CAM_u32RPMRaw) && (TRUE == USERCAL_stRAMCAL.u8FuelPrimeEnable)) + { + /* Prime the injectors */ + USER_vSVC(SYSAPI_enTEPMAsyncRequest, NULL, NULL, NULL); + FUEL_boFuelPrimed = TRUE; + } + else + { + FUEL_boFuelPrimed = TRUE; + } + } + else if ((2000 == u32FuelRunCount) + && (FALSE == FUEL_boFuelPrimed)) + { + /* Finish prime */ + FUEL_boFuelPrimed = TRUE; + } + + u32FuelRunCount++; + + if (EH_IO_Invalid != USERCAL_stRAMCAL.enFuelPumpRelay) + { + if (TRUE == FUEL_boFuelPumpOn) + { + enEHIOResource = USERCAL_stRAMCAL.enFuelPumpRelay; + enTriState = IOAPI_enHigh; + + if (EH_IO_IIC1_SDA > enEHIOResource) + { + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, + (void*)&enTriState, (void*)NULL); + } + else + { + enBit = 1 << (enEHIOResource - EH_IO_IIC1_SDA); + RELAYS_vOutputBit(enBit, IOAPI_enHigh == enTriState); + } + } + else + { + enEHIOResource = USERCAL_stRAMCAL.enFuelPumpRelay; + enTriState = IOAPI_enLow; + + if (EH_IO_IIC1_SDA > enEHIOResource) + { + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, + (void*)&enTriState, (void*)NULL); + } + else + { + enBit = 1 << (enEHIOResource - EH_IO_IIC1_SDA); + RELAYS_vOutputBit(enBit, IOAPI_enHigh == enTriState); + } + } + } + + if (FUEL_boNewSample == TRUE) + { + FUEL_u32ADSamples[u32SampleCount] = FUEL_u32ADCRaw; + u32SampleCount = u32SampleCount % FUEL_nSampleCount; + u32SampleCount++; + + if (0 == u32SampleCount) + { + FUEL_u32ADCFiltered = USERMATH_u32DiscardAndAverage32(FUEL_u32ADSamples, FUEL_nSampleCount, 2);/*CR1_1*/ + FUEL_u32ADCFiltered *= 0x100; + } + + u32Temp = ((FUEL_u32ADCFiltered / 100U) * USERCAL_stRAMCAL.s32FuelPressureSensorGain) / 10000u; + + if (0 <= USERCAL_stRAMCAL.s32FuelPressureSensorOffset) + { + FUEL_tKiloPaFiltered = u32Temp + USERCAL_stRAMCAL.s32FuelPressureSensorOffset; + } + else + { + if (u32Temp >= -USERCAL_stRAMCAL.s32FuelPressureSensorOffset) + { + FUEL_tKiloPaFiltered = u32Temp + USERCAL_stRAMCAL.s32FuelPressureSensorOffset; + } + else + { + FUEL_tKiloPaFiltered = 0; + } + } + + FUEL_boNewSample = FALSE; + } + + boFuelCutsActive = SENSORS_boGetAuxActive(SENSORS_enAUX_LAUNCH_LOW); + boFuelCutsActive |= SENSORS_boGetAuxActive(SENSORS_enAUX_LAUNCH_HIGH); + boFuelCutsActive |= (0x100 != TORQUE_u32FuelTorqueModifier); + + if (TRUE == boFuelCutsActive) + { + if (EST_nIgnitionReqPrimary == EST_enIgnitionTimingRequest) + { + /* Calculate the current spread for fuel cuts */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&FUEL_tSpreadFuelCutsIDX, + NULL, NULL); + + /* Lookup the current value for fuel cuts */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&FUEL_tTableFuelCutsIDX, + NULL, NULL); + + u32FuelCutPercent = (uint32)FUEL_u16FuelCutsPercent; + } + else + { + if (EST_nIgnitionReqDSGCutsStage3 == EST_enIgnitionTimingRequest) + { + if (2000 < CAM_u32RPMFiltered) + { + if (100000 < MAP_tKiloPaFiltered) + { + u32FuelCutPercent = (MAP_tKiloPaFiltered - 100000) / 1000; + u32FuelCutPercent = + USERCAL_stRAMCAL.u16TorqueReductionMaxFuelCut > u32FuelCutPercent ? + u32FuelCutPercent : USERCAL_stRAMCAL.u16TorqueReductionMaxFuelCut; + } + else + { + u32FuelCutPercent = 0; + } + } + else + { + u32FuelCutPercent = 0; + } + } + else + { + /* No fuel cut pre-shift */ + u32FuelCutPercent = 0; + } + } + + /* Set the fuel cuts */ + USER_vSVC(SYSAPI_enSetFuelCuts, &u32FuelCutPercent, &FUEL_u32FuelChannelsMask, &FUEL_u32FuelChannelsCount); + } + else + { + u32FuelCutPercent = 0; + + if (boFuelCutsActivePrev != boFuelCutsActive) + { + USER_vSVC(SYSAPI_enSetFuelCuts, &u32FuelCutPercent, &FUEL_u32FuelChannelsMask, &FUEL_u32FuelChannelsCount); + } + } + + boFuelCutsActivePrev = boFuelCutsActive; + + /* FME fuel cuts */ +#ifdef BUILD_FME + if (0 != USERCAL_stRAMCAL.u8DBSlaveConfig) + { + boAirflowFMEEnable = AFM_tAirFlowAFMUg < USERCAL_stRAMCAL.u32AirflowFMELimitLow ? + FALSE : boAirflowFMEEnable; + + boAirflowFMEEnable = AFM_tAirFlowAFMUg > USERCAL_stRAMCAL.u32AirflowFMELimitHigh ? + TRUE : boAirflowFMEEnable; + + /* Override safety airflow limit set too high > 15g/s */ + if (15000000u < USERCAL_stRAMCAL.u32AirflowFMELimitHigh) boAirflowFMEEnable = TRUE; + + u32Temp = (u32FuelRunCount >> 4) & 0x7; + + boFuelCutsActive = FALSE; + + if (TRUE == boAirflowFMEEnable) + { + boFuelCutsActive |= (FME_enFaultActive == FME_enGetDiagState(FME_enPPSPair)); + boFuelCutsActive |= (FME_enFaultActive == FME_enGetDiagState(FME_enPedalTransfer)); + boFuelCutsActive |= (FME_enFaultActive == FME_enGetDiagState(FME_enTPSMSingle)); + boFuelCutsActive |= (FME_enFaultActive == FME_enGetDiagState(FME_enPPSMSingle)); + boFuelCutsActive |= (FME_enFaultActive == FME_enGetDiagState(FME_enPPSSSingle)); + } + + if (TRUE == boFuelCutsActive) + { + FUEL_aboFMECutFlag[u32Temp] = TRUE; + } + else + { + FUEL_aboFMECutFlag[u32Temp] = FALSE; + } + } +#endif //BUILD_FME + +} + +void FUEL_vCalculateFuellingValues() +{ + FUEL_boCalculatePending = TRUE; +} + +static void FUEL_vCyclicCalculate(void) +{ + static bool boAFMTransientControl; + static bool boFuelAFRCutoff; + static uint32 u32OverrunCutCount; + uint32 u32SeqIDX; + uint8 u8SeqFuelBit; + uint32 u32FuelCycleTimeUs; + uint32 u32Temp = 0; + static bool boSequentialMode; + static bool boHighDuty; + static uint32 u32SequentialModeCount; + uint32 u32MaxFuel; + uint32 u32ReturnlessPressureKpa; + uint16 u16FuelFlowRate; + + if ((FALSE == FUEL_boFuelPrimed) && + (400 > CAM_u32RPMRaw) && + (TRUE == USERCAL_stRAMCAL.u8FuelPrimeEnable)) + { + FUEL_tTimePredictedUs[0] = CTS_u32Primer; + FUEL_tTimePredictedUs[1] = CTS_u32Primer; + } + else + { + uint32 u32Temp1; + uint32 u32Temp2; + sint32 s32Temp; + + /* Calculate the current spread for AfmTF */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&FUEL_tSpreadAfmTFIDX, + NULL, NULL); + + /* Lookup the current AfmTF value for AfmTF */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&FUEL_tTableAfmTFIDX, + NULL, NULL); + + + /* Max delta ramp airflow */ + if (AFM_tAirFlowAFMRawUg >= AFM_tAirFlowAFMUg) + { + u32Temp = USERCAL_stRAMCAL.u16AFMMaxCycleDeltaUgPos * 1000; + + if (u32Temp < (AFM_tAirFlowAFMRawUg - AFM_tAirFlowAFMUg)) + { + AFM_tAirFlowAFMUg += u32Temp; + } + else + { + AFM_tAirFlowAFMUg = AFM_tAirFlowAFMRawUg; + } + } + else + { + u32Temp = USERCAL_stRAMCAL.u16AFMMaxCycleDeltaUgNeg * 1000; + + if (u32Temp < (AFM_tAirFlowAFMUg - AFM_tAirFlowAFMRawUg)) + { + if (AFM_tAirFlowAFMUg > u32Temp) + { + AFM_tAirFlowAFMUg -= u32Temp; + } + else + { + AFM_tAirFlowAFMUg = 0; + } + } + else + { + AFM_tAirFlowAFMUg = AFM_tAirFlowAFMRawUg; + } + } + + + if (0 != USERCAL_stRAMCAL.u8VariableFuelPressureEnable) + { + /* Calculate the current spread for Fuel Flow */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&FUEL_tSpreadFuelFlowIDX, + NULL, NULL); + + /* Lookup the current fuel flow rate */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&FUEL_tTableFuelFlowIDX, + NULL, NULL); + } + + boAFMTransientControl = USERCAL_stRAMCAL.u32AFMTransientControlRPMLimit > CAM_u32RPMRaw ? TRUE : boAFMTransientControl; + boAFMTransientControl = (USERCAL_stRAMCAL.u32AFMTransientControlRPMLimit + 100) < CAM_u32RPMRaw ? FALSE : boAFMTransientControl; + + if ((USERCAL_stRAMCAL.u16RPMRunThreshold < CAM_u32RPMRaw) || (USERCAL_stRAMCAL.u8CrankingAirflowEnable == FALSE)) + { + if ((TRUE == USERCAL_stRAMCAL.u8EnableBackupAirflowTransients) && + (TRUE == boAFMTransientControl)) + { + if (AFM_tAirFlowAFMUg > AFM_tAirFlowBackupUg) + { + u32Temp1 = (AFM_tAirFlowBackupUg * 9) / 8; + FUEL_tPredictedAirFlowUg = u32Temp > AFM_tAirFlowAFMUg ? AFM_tAirFlowAFMUg : u32Temp; + } + else + { + u32Temp1 = (AFM_tAirFlowBackupUg * 7) / 8; + FUEL_tPredictedAirFlowUg = u32Temp > AFM_tAirFlowAFMUg ? u32Temp : AFM_tAirFlowAFMUg; + } + } + else + { + if (USERCAL_stRAMCAL.u32SpeedDensityAFMTPSLim > TPS_tThetaFiltered) + /* At small throttle angles */ + { + if (TRUE == USERCAL_stRAMCAL.u8EnableAFMPrimaryInputClosed) + { + FUEL_tPredictedAirFlowUg = AFM_tAirFlowAFMUg; + } + else if ((FALSE == USERCAL_stRAMCAL.u8EnableAFMPrimaryInputClosed) && + (TRUE == USERCAL_stRAMCAL.u8EnableAFMPrimaryInputOpen)) + { + u32Temp1 = TPS_tThetaFiltered * (AFM_tAirFlowAFMUg / USERCAL_stRAMCAL.u32SpeedDensityAFMTPSLim); + u32Temp2 = (USERCAL_stRAMCAL.u32SpeedDensityAFMTPSLim - TPS_tThetaFiltered) * (AFM_tAirFlowVEUg / USERCAL_stRAMCAL.u32SpeedDensityAFMTPSLim); + + FUEL_tPredictedAirFlowUg = u32Temp1 + u32Temp2; + } + else + { + FUEL_tPredictedAirFlowUg = AFM_tAirFlowVEUg; + } + } + else + { + if (TRUE == USERCAL_stRAMCAL.u8EnableAFMPrimaryInputOpen) + { + FUEL_tPredictedAirFlowUg = AFM_tAirFlowAFMUg; + } + else + { + FUEL_tPredictedAirFlowUg = AFM_tAirFlowVEUg; + } + } + } + } + else + { + /* Calculate the current spread for cranking airflow */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&FUEL_tSpreadCrankingAirflowIDX, + NULL, NULL); + + /* Lookup the current value for cranking airflow */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&FUEL_tTableCrankingAirflowIDX, + NULL, NULL); + FUEL_tPredictedAirFlowUg = 1000 * FUEL_u16CrankingAirflow; + } + + if (TRUE == FUEL_boFuelPrimed) + { + CLO2_vRun(); + IAC_vCallBack(NULL); + } + + + /* Add manifold capacitance transitory airflow */ + if (500000 < MAP_s32ManDeltaChargeMassPerSUg) + { + FUEL_tPredictedAirFlowUg += (uint32)MAP_s32ManDeltaChargeMassPerSUg; + } + else if ((-500000 > MAP_s32ManDeltaChargeMassPerSUg) && (FUEL_tPredictedAirFlowUg > -MAP_s32ManDeltaChargeMassPerSUg)) + { + FUEL_tPredictedAirFlowUg += (uint32)MAP_s32ManDeltaChargeMassPerSUg; + } + + FUEL_tPredictedFuelFlowUg = (10u * FUEL_tPredictedAirFlowUg) / FUEL_u16TAFR; + + /* Add CTS and ATS correction */ + FUEL_tPredictedFuelFlowUg = ((FUEL_tPredictedFuelFlowUg / 10UL) * (CTS_u32FuelMultiplier + ATS_u32FuelMultiplier - 1000)) / 100UL; + + /* Add TPS moving enrichment */ + FUEL_tPredictedFuelFlowUg = ((FUEL_tPredictedFuelFlowUg / 10UL) * (TPS_u32MovingTPSEnrichment)) / 100UL; + + /* Add TPS tip in enrichment */ + FUEL_tPredictedFuelFlowUg = ((FUEL_tPredictedFuelFlowUg / 10UL) * (TPS_u32TipInEnrichment)) / 100UL; + + + s32Temp = (sint32)FUEL_tPredictedFuelFlowUg + FILM_s32FilmLoadUgDeltaApplied; + + if (0 <= s32Temp) + { + FUEL_tPredictedFuelFlowUg = (uint32)s32Temp; + } + else + { + FUEL_tPredictedFuelFlowUg = 0; + } + + /* Add STT trim */ + FUEL_tPredictedFuelFlowPerInjectionNg[0] = (12 / USERCAL_stRAMCAL.u8InjDivide) * (100 * FUEL_tPredictedFuelFlowUg / CAM_u32RPMRaw);//was filtered!! + FUEL_tPredictedFuelFlowPerInjectionNg[0] *= CLO2_u32STT[0]; + FUEL_tPredictedFuelFlowPerInjectionNg[1] = (12 / USERCAL_stRAMCAL.u8InjDivide) * (100 * FUEL_tPredictedFuelFlowUg / CAM_u32RPMRaw);//was filtered!! + FUEL_tPredictedFuelFlowPerInjectionNg[1] *= CLO2_u32STT[1]; + + /* Add fuel pressure trim */ + if ((USERCAL_stRAMCAL.u8ReturnlessEnable == TRUE) && (FALSE == USERCAL_stRAMCAL.u8VariableFuelPressureEnable)) + { + u32ReturnlessPressureKpa = 1000 * USERCAL_stRAMCAL.u16ReturnlessPressureKPa; + u32Temp = MAP_tKiloPaFiltered + u32ReturnlessPressureKpa; + u32Temp /= (101 + (u32ReturnlessPressureKpa / 1000)); + u32Temp = 1000 > u32Temp ? u32Temp : 999; + u32Temp = USERMATH_u32GetSquareRoot(u32Temp); + + FUEL_tPredictedFuelFlowPerInjectionNg[0] /= 1000; + FUEL_tPredictedFuelFlowPerInjectionNg[0] *= u32Temp; + FUEL_tPredictedFuelFlowPerInjectionNg[1] /= 1000; + FUEL_tPredictedFuelFlowPerInjectionNg[1] *= u32Temp; + } + + if (FALSE == USERCAL_stRAMCAL.u8VariableFuelPressureEnable) + { + u16FuelFlowRate = (uint32)USERCAL_stRAMCAL.u16InjFlowRate; + } + else + { + u16FuelFlowRate = FUEL_u16FuelFlowRate; + } + + u32Temp = (uint32)USERCAL_stRAMCAL.u8CylCount * u16FuelFlowRate; + FUEL_tTimePredictedUs[0] = FUEL_tPredictedFuelFlowPerInjectionNg[0] / u32Temp; + FUEL_tTimePredictedUs[1] = FUEL_tPredictedFuelFlowPerInjectionNg[1] / u32Temp; + + /* Trim short pulse */ + if (USERCAL_stRAMCAL.u16MinLinearFuelPulse > FUEL_tTimePredictedUs[0]) + { + FUEL_tTimePredictedUsInput = FUEL_tTimePredictedUs[0]; + (void)BOOSTED_boIndexAndCalculateTable(FUEL_tSpreadInjShortOpeningIDX, FUEL_tTableInjShortOpeningIDX); + + /* Pragmatic workaround - predicted event < 1.6 ms */ + if (USERCAL_stRAMCAL.aUserInjShortOpeningTable[10] > FUEL_tTimePredictedUs[0]) + { + u32Temp = USERCAL_stRAMCAL.aUserInjShortOpeningTable[10] - FUEL_tTimePredictedShortOpeningUs; + u32Temp *= (BVM_tBattVolts - 4000); + u32Temp /= 11000; + FUEL_tTimePredictedShortOpeningUs = USERCAL_stRAMCAL.aUserInjShortOpeningTable[10] - u32Temp; + } + + FUEL_tTimePredictedUs[0] = FUEL_tTimePredictedShortOpeningUs; + } + + if (USERCAL_stRAMCAL.u16MinLinearFuelPulse > FUEL_tTimePredictedUs[1]) + { + FUEL_tTimePredictedUsInput = FUEL_tTimePredictedUs[1]; + (void)BOOSTED_boIndexAndCalculateTable(FUEL_tSpreadInjShortOpeningIDX, FUEL_tTableInjShortOpeningIDX); + + /* Pragmatic workaround - predicted event < 1.6 ms */ + if (USERCAL_stRAMCAL.aUserInjShortOpeningTable[10] > FUEL_tTimePredictedUs[1]) + { + u32Temp = USERCAL_stRAMCAL.aUserInjShortOpeningTable[10] - FUEL_tTimePredictedShortOpeningUs; + u32Temp *= (BVM_tBattVolts - 4000); + u32Temp /= 11000; + FUEL_tTimePredictedShortOpeningUs = USERCAL_stRAMCAL.aUserInjShortOpeningTable[10] - u32Temp; + } + + FUEL_tTimePredictedUs[1] = FUEL_tTimePredictedShortOpeningUs; + } + + boFuelAFRCutoff = (FUEL_u16TAFR < USERCAL_stRAMCAL.u16AFRReinstate) ? FALSE : boFuelAFRCutoff; + boFuelAFRCutoff = (FUEL_u16TAFR > USERCAL_stRAMCAL.u16AFRCutoff) ? TRUE : boFuelAFRCutoff; + } + + FUEL_tTimePredictedUs[0] = TRUE == boFuelAFRCutoff ? 0 : FUEL_tTimePredictedUs[0]; + FUEL_tTimePredictedUs[1] = TRUE == boFuelAFRCutoff ? 0 : FUEL_tTimePredictedUs[1]; + + /* Apply DSG torque reduce trim */ + if ((EST_nIgnitionReqDSGStage1 == EST_enIgnitionTimingRequest) || + (EST_nIgnitionReqDSGStage2 == EST_enIgnitionTimingRequest) || + (EST_nIgnitionReqDSGCutsStage3 == EST_enIgnitionTimingRequest)) + { + FUEL_tTimePredictedUs[0] = TORQUE_u32FuelTorqueModifier * FUEL_tTimePredictedUs[0] / 0x100; + FUEL_tTimePredictedUs[1] = TORQUE_u32FuelTorqueModifier * FUEL_tTimePredictedUs[1] / 0x100; + } + + /* Increment fuel consumed for BC */ + FUEL_u32FuelConsumed += FUEL_tTimePredictedUs[0]; + + /* Manage overrun fuel cut */ +#ifdef BUILD_BSP_VSS_CAN + if ((TRUE == MAP_boHighVacuum) && + (TRUE == TPS_boThrottleClosed) && + (TRUE == IAC_boOverrunCutRPMEnable) && + (0 != SENSORS_u16CANVSS) && + (0xffff != SENSORS_u16CANVSS)) +#else + if ((TRUE == MAP_boHighVacuum) && + (TRUE == TPS_boThrottleClosed) && + (TRUE == IAC_boOverrunCutRPMEnable)) +#endif + { + u32OverrunCutCount = 40 > u32OverrunCutCount ? u32OverrunCutCount + 1 : u32OverrunCutCount; + + for (u32SeqIDX = 0; u32SeqIDX < 8; u32SeqIDX++) + { + FUEL_aboSeqOverrunCutFlag[u32SeqIDX] = u32OverrunCutCount > (10 + (u32SeqIDX << 3)) ? TRUE : FALSE; + } + } + else if (TRUE == IAC_boOverrunCutRPMEnable) + { + u32OverrunCutCount = 3 < u32OverrunCutCount ? u32OverrunCutCount - 4 : 0; + + for (u32SeqIDX = 0; u32SeqIDX < 8; u32SeqIDX++) + { + FUEL_aboSeqOverrunCutFlag[u32SeqIDX] = u32OverrunCutCount > (10 + (u32SeqIDX << 3)) ? TRUE : FALSE; + } + } + else + { + u32OverrunCutCount = 0; + + for (u32SeqIDX = 0; u32SeqIDX < 8; u32SeqIDX++) + { + FUEL_aboSeqOverrunCutFlag[u32SeqIDX] = FALSE; + } + } + + u8SeqFuelBit = 1; + + /* Apply overrun and over-speed fuel cuts */ + for (u32SeqIDX = 0; u32SeqIDX < 8; u32SeqIDX++) + { + if ((TRUE == FUEL_aboSeqRevCutFlag[u32SeqIDX]) || +#ifdef BUILD_FME + (TRUE == FUEL_aboFMECutFlag[u32SeqIDX]) || +#endif //BUILD_FME + (TRUE == FUEL_aboSeqOverrunCutFlag[u32SeqIDX])) + { + FUEL_tTimeHoldUs[u32SeqIDX] = 600; + FUEL_tTimeHold[u32SeqIDX] = 400; + } + else + { + CPU_xEnterCritical(); + if (0 == (u8SeqFuelBit & USERCAL_stRAMCAL.u8SeqFuelAssign)) + { + FUEL_tTimeHoldUs[u32SeqIDX] = FUEL_tTimePredictedUs[0] + (uint32)FUEL_u16InjResponse; + FUEL_tTimeHoldUs[u32SeqIDX] = (uint32)((sint32)FUEL_tTimeHoldUs[u32SeqIDX] + USERCAL_stRAMCAL.s16SequenceFuelOffset[u32SeqIDX]); + FUEL_tTimeHold[u32SeqIDX] = FUEL_xUsToSlowTicks(FUEL_tTimeHoldUs[u32SeqIDX]); + } + else + { + FUEL_tTimeHoldUs[u32SeqIDX] = FUEL_tTimePredictedUs[1] + (uint32)FUEL_u16InjResponse; + FUEL_tTimeHoldUs[u32SeqIDX] = (uint32)((sint32)FUEL_tTimeHoldUs[u32SeqIDX] + USERCAL_stRAMCAL.s16SequenceFuelOffset[u32SeqIDX]); + FUEL_tTimeHold[u32SeqIDX] = FUEL_xUsToSlowTicks(FUEL_tTimeHoldUs[u32SeqIDX]); + } + CPU_xExitCritical(); + } + + u8SeqFuelBit *= 2; + } + + FUEL_boCalculatePending = FALSE; + + u32MaxFuel = MAX(FUEL_tTimeHoldUs[0], FUEL_tTimeHoldUs[1]); + u32MaxFuel = MAX(u32MaxFuel, FUEL_tTimeHoldUs[2]); + u32MaxFuel = MAX(u32MaxFuel, FUEL_tTimeHoldUs[3]); + + u32FuelCycleTimeUs = 120000000 / (CAM_u32RPMRaw * USERCAL_stRAMCAL.u8InjDivide); + u32Temp = (0x10000 * u32MaxFuel) / u32FuelCycleTimeUs; + + + /* Condition the high duty flag */ + boHighDuty = 40000 < u32Temp ? TRUE : boHighDuty; + boHighDuty = 30000 > u32Temp ? FALSE : boHighDuty; + + + /* Clear sequential counter */ + if (250 > CAM_u32RPMFiltered) + { + u32SequentialModeCount = 0; + } + + /* Check sequential mode */ + if ((350 > CAM_u32RPMFiltered) || (true == boHighDuty) || (FALSE == FUEL_bo720Injection)) + { + u32SequentialModeCount = 0 < u32SequentialModeCount ? u32SequentialModeCount - 1 : 0; + } + else + { + u32SequentialModeCount = FUEL_nSeqModeCountLimit > u32SequentialModeCount ? u32SequentialModeCount + 1 : FUEL_nSeqModeCountLimit; + } + + + /* Condition the sequential flag */ + boSequentialMode = FUEL_nSeqModeCountLimit <= u32SequentialModeCount ? TRUE : boSequentialMode; + boSequentialMode = 0 == u32SequentialModeCount ? FALSE : boSequentialMode; + + + if (TRUE == boSequentialMode) + { + if (49500 > u32Temp) + { + /* Assign the end of event angles */ + FUEL_tStartHoldFraction[0] = 50000 - u32Temp; + FUEL_tStartHoldFraction[1] = 50000 - u32Temp; + FUEL_tStartHoldFraction[2] = 50000 - u32Temp; + FUEL_tStartHoldFraction[3] = 50000 - u32Temp; + } + else + { + /* Assign the end of event angles */ + FUEL_tStartHoldFraction[0] = 500; + FUEL_tStartHoldFraction[1] = 500; + FUEL_tStartHoldFraction[2] = 500; + FUEL_tStartHoldFraction[3] = 500; + } + } + else + { + /* Assign the start of event angles */ + //FUEL_tStartHoldFraction[0] = 1500; + //FUEL_tStartHoldFraction[1] = 1500; + //FUEL_tStartHoldFraction[2] = 1500; + //FUEL_tStartHoldFraction[3] = 1500; + if (2000 > CAM_u32RPMRaw) + { + FUEL_tStartHoldFraction[0] = 2000 + ((2000 - CAM_u32RPMRaw) << 3); + FUEL_tStartHoldFraction[1] = 2000 + ((2000 - CAM_u32RPMRaw) << 3); + FUEL_tStartHoldFraction[2] = 2000 + ((2000 - CAM_u32RPMRaw) << 3); + FUEL_tStartHoldFraction[3] = 2000 + ((2000 - CAM_u32RPMRaw) << 3); + } + else + { + FUEL_tStartHoldFraction[0] = 2000; + FUEL_tStartHoldFraction[1] = 2000; + FUEL_tStartHoldFraction[2] = 2000; + FUEL_tStartHoldFraction[3] = 2000; + } + } +} + + +void FUEL_vTerminate(puint32 const pu32Arg) +{ + +} + + +void FUEL_vCallBack(puint32 const pu32Arg) +{ + +} + +static void FUEL_vTEPMCallBack(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime) +{ + //FUEL_boFuelPrimed = TRUE; +} + +static void FUEL_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult) +{ + FUEL_u32ADCRaw = MIN(u32ADCResult, SENSORS_nSENSORADMAX); + FUEL_boNewSample = TRUE; +} + +static void FUEL_vCalcFuelChannels(void) +{ + uint32 u32IDX; + uint32 u32Mask = 1; + FUEL_u32FuelChannelsCount = 0; + + for (u32IDX = 0; u32IDX < 32; u32IDX++) + { + if (0 != (u32Mask & FUEL_u32FuelChannelsMask)) + { + FUEL_u32FuelChannelsCount++; + } + + u32Mask *= 2; + } +} + +#endif //BUILD_USER diff --git a/source/Client/FUEL.h b/source/Client/FUEL.h new file mode 100644 index 0000000..77f0ee8 --- /dev/null +++ b/source/Client/FUEL.h @@ -0,0 +1,91 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Fuelling Header File */ +/* DESCRIPTION: This code module initialises the required */ +/* resources and functions for fuelling calculations */ +/* measurement */ +/* FILE NAME: FUEL.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef FUEL_H +#define FUEL_H + +#include +#include "cpuabstract.h" +#include "declarations.h" +#include "CLO2.h" +#include "IOAPI.h" +#include "SPREADSAPI.h" +#include "TABLESAPI.h" +#include "sensors.h" +#include "TEPM.h" +#include "USER.h" + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define FUEL_xUsToSlowTicks(x) (((SENSORS_nSlowFTMFreq / 100u) * (x)) / 10000u) +#define FUEL_nEngineCap (1400) +#define FUEL_nInjRespCalcRate (4) +#define FUEL_nInj4Output EH_IO_ADD8 +#define FUEL_nInj3Output EH_IO_TMR10 +#define FUEL_nInj2Output EH_IO_TMR11 +#define FUEL_nInj1Output EH_IO_EXTINT +#define FUEL_nShortPulseRangeUs 2000 +#define FUEL_nXAFMAxisRef AFM_tSensorHertz +#define FUEL_nFuelSequenceCount 4 +#define FUEL_nSeqModeCountLimit 10 +#define FUEL_nSampleCount 5 + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _FUEL_C + #define EXTERN +#else + #define EXTERN extern +#endif + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +EXTERN TEPMAPI_ttEventTime FUEL_tStartHoldFraction[8]; +EXTERN TEPMAPI_ttEventTime FUEL_tStartFPSolenoidDelay; +EXTERN TEPMAPI_ttEventTime FUEL_tStartFPSolenoidPeak; +EXTERN TEPMAPI_ttEventTime FUEL_tStartFPSolenoidDutyHigh; +EXTERN TEPMAPI_ttEventTime FUEL_tStartFPSolenoidDutyLow; +EXTERN TEPMAPI_ttEventTime FUEL_tFPAccumulate; +EXTERN TEPMAPI_ttEventTime FUEL_tTimeHold[8]; +EXTERN GPM6_ttPulseUs FUEL_tTimeHoldUs[8]; +//ASAM mode=readvalue name="Fuel Injector Hold ms" type=uint32 offset=0 min=0 max=40 m=0.001 b=0 units="ms" format=5.3 help="Fuel Injector Total ms" +EXTERN GPM6_ttCc FUEL_tMaxAirFlow; +EXTERN GPM6_ttMcc FUEL_tPredictedAirFlowMcc; +EXTERN GPM6_ttUg FUEL_tPredictedAirFlowUg; +EXTERN GPM6_ttG FUEL_tPredictedFuelFlowUg; +EXTERN GPM6_ttG FUEL_tPredictedFuelFlowPerInjectionNg[2]; +//ASAM mode=readvalue name="Fuel Injector Predicted ms" type=uint32 offset=0 min=0 max=40 m=0.001 b=0 units="ms" format=5.3 help="Fuel Injector Predicted ms" +EXTERN volatile GPM6_ttPulseUs FUEL_tTimePredictedUs[2]; +EXTERN volatile GPM6_ttPulseUs FUEL_tTimePredictedUsInput; +EXTERN volatile GPM6_ttPulseUs FUEL_tTimePredictedShortOpeningUs; +EXTERN bool FUEL_boFuelPrimed; +EXTERN bool FUEL_u32PrimeCBCount; +EXTERN uint16 FUEL_u16TAFR; +EXTERN bool FUEL_aboSeqRevCutFlag[8]; +EXTERN bool FUEL_aboSeqOverrunCutFlag[8]; +EXTERN bool FUEL_aboFMECutFlag[8]; +EXTERN uint32 FUEL_u32FuelConsumed; +EXTERN uint32 FUEL_u32ADSamples[FUEL_nSampleCount]; +EXTERN GPM6_ttPa FUEL_tKiloPaFiltered; +//ASAM mode=readvalue name="Fuel Rail kPa" type=uint32 offset=0 min=0 max=35000 m=1 b=0 units="kPa" format=5.3 help="Fuel Rail Pressure" +EXTERN bool FUEL_boFuelPumpOn; +//ASAM mode=readvalue name="Fuel Pump On" type=uint8 offset=0 min=0 max=1 m=1 b=0 units="bool" format=5.3 help="Fuel Pump On" +EXTERN uint16 FUEL_u16FuelCutsPercent; + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void FUEL_vStart(uint32 * const pu32Arg); +void FUEL_vRun(uint32* const pu32Arg); +void FUEL_vTerminate(uint32* const pu32Arg); +void FUEL_vCallBack(puint32 const pu32Arg); +void FUEL_vCalculateFuellingValues(void); + +#endif // FUEL_H diff --git a/source/Client/GENDATA.c b/source/Client/GENDATA.c new file mode 100644 index 0000000..87386e2 --- /dev/null +++ b/source/Client/GENDATA.c @@ -0,0 +1,358 @@ +/******************************************************************************/ +/* Copyright (c) 2019 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Generic Data Code File */ +/* DESCRIPTION: This code module contains generic data transforms */ +/* */ +/* FILE NAME: gendata.c */ +/* REVISION HISTORY: 28-06-2019 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#define _GENDATA_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER +#include "GENDATA.h" +#include "AFM.h" +#include "MAP.h" + + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ + + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ + +SPREADAPI_ttSpreadIDX GENDATA_tSpreadPWM2DxIDX[GENDATA_nPWM2DTableCount]; +SPREADAPI_ttSpreadIDX GENDATA_tSpreadPWM3DxIDX[GENDATA_nPWM3DTableCount]; +SPREADAPI_ttSpreadIDX GENDATA_tSpreadPWM3DyIDX[GENDATA_nPWM3DTableCount]; + +TABLEAPI_ttTableIDX GENDATA_tTablePWMIDX[GENDATA_nPWM2DTableCount]; +MAPSAPI_ttMapIDX GENDATA_tMapPWMIDX[GENDATA_nPWM3DTableCount]; + +TEPMAPI_tstTimedKernelEvent GENDATA_astTimedKernelEvents[1]; + + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void GENDATA_vStart(puint32 const pu32Arg) +{ + uint32 u32OutputIDX; + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenEHIOType enEHIOType; + IOAPI_tenDriveStrength enDriveStrength = IOAPI_enWeak; + TEPMAPI_tstTEPMChannelCB stTEPMChannelCB; + TEPMAPI_ttEventCount tEventCount = 1; + + /* Request and initialise required Kernel managed spread for PWM table 1 x */ + GENDATA_tSpreadPWM2DxIDX[0] = SETUP_tSetupSpread((void*)&GENDATA_s32SOURCE[0], (void*)&USERCAL_stRAMCAL.aUserPWM2D_1SpreadX, TYPE_enInt32, GENDATA_nPWM2DTableDimX, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for PWM table 2 x */ + GENDATA_tSpreadPWM2DxIDX[1] = SETUP_tSetupSpread((void*)&GENDATA_s32SOURCE[1], (void*)&USERCAL_stRAMCAL.aUserPWM2D_2SpreadX, TYPE_enInt32, GENDATA_nPWM2DTableDimX, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for PWM table 3 x */ + GENDATA_tSpreadPWM2DxIDX[2] = SETUP_tSetupSpread((void*)&GENDATA_s32SOURCE[2], (void*)&USERCAL_stRAMCAL.aUserPWM2D_3SpreadX, TYPE_enInt32, GENDATA_nPWM2DTableDimX, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for PWM table 4 x */ + GENDATA_tSpreadPWM2DxIDX[3] = SETUP_tSetupSpread((void*)&GENDATA_s32SOURCE[3], (void*)&USERCAL_stRAMCAL.aUserPWM2D_4SpreadX, TYPE_enInt32, GENDATA_nPWM2DTableDimX, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for PWM table 5 x */ + GENDATA_tSpreadPWM2DxIDX[4] = SETUP_tSetupSpread((void*)&GENDATA_s32SOURCE[4], (void*)&USERCAL_stRAMCAL.aUserPWM2D_5SpreadX, TYPE_enInt32, GENDATA_nPWM2DTableDimX, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for PWM table 6 x */ + GENDATA_tSpreadPWM2DxIDX[5] = SETUP_tSetupSpread((void*)&GENDATA_s32SOURCE[5], (void*)&USERCAL_stRAMCAL.aUserPWM2D_6SpreadX, TYPE_enInt32, GENDATA_nPWM2DTableDimX, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for PWM table 7 x */ + GENDATA_tSpreadPWM2DxIDX[6] = SETUP_tSetupSpread((void*)&GENDATA_s32SOURCE[6], (void*)&USERCAL_stRAMCAL.aUserPWM2D_7SpreadX, TYPE_enInt32, GENDATA_nPWM2DTableDimX, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for PWM table 8 x */ + GENDATA_tSpreadPWM2DxIDX[7] = SETUP_tSetupSpread((void*)&GENDATA_s32SOURCE[7], (void*)&USERCAL_stRAMCAL.aUserPWM2D_8SpreadX, TYPE_enInt32, GENDATA_nPWM2DTableDimX, SPREADAPI_enSpread4ms, NULL); + + + /* 2D PWM maps data */ + /* Request and initialise required Kernel managed map for 2D PWM 1 */ + GENDATA_tTablePWMIDX[0] = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserPWM2D_1Data, (void*)&GENDATA_u16PWMOutput[0], TYPE_enUInt16, GENDATA_nPWM2DTableDimX, GENDATA_tSpreadPWM2DxIDX[0], NULL); + + /* Request and initialise required Kernel managed map for 2D PWM 2 */ + GENDATA_tTablePWMIDX[1] = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserPWM2D_2Data, (void*)&GENDATA_u16PWMOutput[1], TYPE_enUInt16, GENDATA_nPWM2DTableDimX, GENDATA_tSpreadPWM2DxIDX[1], NULL); + + /* Request and initialise required Kernel managed map for 2D PWM 3 */ + GENDATA_tTablePWMIDX[2] = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserPWM2D_3Data, (void*)&GENDATA_u16PWMOutput[2], TYPE_enUInt16, GENDATA_nPWM2DTableDimX, GENDATA_tSpreadPWM2DxIDX[2], NULL); + + /* Request and initialise required Kernel managed map for 2D PWM 4 */ + GENDATA_tTablePWMIDX[3] = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserPWM2D_4Data, (void*)&GENDATA_u16PWMOutput[3], TYPE_enUInt16, GENDATA_nPWM2DTableDimX, GENDATA_tSpreadPWM2DxIDX[3], NULL); + + /* Request and initialise required Kernel managed map for 2D PWM 5 */ + GENDATA_tTablePWMIDX[4] = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserPWM2D_5Data, (void*)&GENDATA_u16PWMOutput[4], TYPE_enUInt16, GENDATA_nPWM2DTableDimX, GENDATA_tSpreadPWM2DxIDX[4], NULL); + + /* Request and initialise required Kernel managed map for 2D PWM 6 */ + GENDATA_tTablePWMIDX[5] = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserPWM2D_6Data, (void*)&GENDATA_u16PWMOutput[5], TYPE_enUInt16, GENDATA_nPWM2DTableDimX, GENDATA_tSpreadPWM2DxIDX[5], NULL); + + /* Request and initialise required Kernel managed map for 2D PWM 7 */ + GENDATA_tTablePWMIDX[6] = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserPWM2D_7Data, (void*)&GENDATA_u16PWMOutput[6], TYPE_enUInt16, GENDATA_nPWM2DTableDimX, GENDATA_tSpreadPWM2DxIDX[6], NULL); + + /* Request and initialise required Kernel managed map for 2D PWM 8 */ + GENDATA_tTablePWMIDX[7] = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserPWM2D_8Data, (void*)&GENDATA_u16PWMOutput[7], TYPE_enUInt16, GENDATA_nPWM2DTableDimX, GENDATA_tSpreadPWM2DxIDX[7], NULL); + + + /* 3D PWM maps X axes */ + /* Request and initialise required Kernel managed spread for PWM map 1 x */ + GENDATA_tSpreadPWM3DxIDX[0] = SETUP_tSetupSpread((void*)&GENDATA_s32SOURCE[8], (void*)&USERCAL_stRAMCAL.aUserPWM3D_1SpreadX, TYPE_enInt32, GENDATA_nPWM3DTableDimX, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for PWM map 2 x */ + GENDATA_tSpreadPWM3DxIDX[1] = SETUP_tSetupSpread((void*)&GENDATA_s32SOURCE[9], (void*)&USERCAL_stRAMCAL.aUserPWM3D_2SpreadX, TYPE_enInt32, GENDATA_nPWM3DTableDimX, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for PWM map 3 x */ + GENDATA_tSpreadPWM3DxIDX[2] = SETUP_tSetupSpread((void*)&GENDATA_s32SOURCE[10], (void*)&USERCAL_stRAMCAL.aUserPWM3D_3SpreadX, TYPE_enInt32, GENDATA_nPWM3DTableDimX, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for PWM map 4 x */ + GENDATA_tSpreadPWM3DxIDX[3] = SETUP_tSetupSpread((void*)&GENDATA_s32SOURCE[11], (void*)&USERCAL_stRAMCAL.aUserPWM3D_4SpreadX, TYPE_enInt32, GENDATA_nPWM3DTableDimX, SPREADAPI_enSpread4ms, NULL); + + + + /* 3D PWM maps Y axes */ + /* Request and initialise required Kernel managed spread for PWM map 1 x */ + GENDATA_tSpreadPWM3DyIDX[0] = SETUP_tSetupSpread((void*)&GENDATA_s32SOURCE[12], (void*)&USERCAL_stRAMCAL.aUserPWM3D_1SpreadY, TYPE_enInt32, GENDATA_nPWM3DTableDimY, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for PWM map 2 x */ + GENDATA_tSpreadPWM3DyIDX[1] = SETUP_tSetupSpread((void*)&GENDATA_s32SOURCE[13], (void*)&USERCAL_stRAMCAL.aUserPWM3D_2SpreadY, TYPE_enInt32, GENDATA_nPWM3DTableDimY, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for PWM map 3 x */ + GENDATA_tSpreadPWM3DyIDX[2] = SETUP_tSetupSpread((void*)&GENDATA_s32SOURCE[14], (void*)&USERCAL_stRAMCAL.aUserPWM3D_3SpreadY, TYPE_enInt32, GENDATA_nPWM3DTableDimY, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for PWM map 4 x */ + GENDATA_tSpreadPWM3DyIDX[3] = SETUP_tSetupSpread((void*)&GENDATA_s32SOURCE[15], (void*)&USERCAL_stRAMCAL.aUserPWM3D_4SpreadY, TYPE_enInt32, GENDATA_nPWM3DTableDimY, SPREADAPI_enSpread4ms, NULL); + + + + /* 3D PWM maps data */ + /* Request and initialise required Kernel managed map for 3D PWM 1 */ + GENDATA_tMapPWMIDX[0] = SETUP_tSetupMap((void*)&USERCAL_stRAMCAL.aUserPWM3D_1Data, (void*)&GENDATA_u16PWMOutput[8], TYPE_enUInt16, 17, 17, GENDATA_tSpreadPWM3DxIDX[0], GENDATA_tSpreadPWM3DyIDX[0], NULL); + + /* Request and initialise required Kernel managed map for 3D PWM 2 */ + GENDATA_tMapPWMIDX[1] = SETUP_tSetupMap((void*)&USERCAL_stRAMCAL.aUserPWM3D_2Data, (void*)&GENDATA_u16PWMOutput[9], TYPE_enUInt16, 17, 17, GENDATA_tSpreadPWM3DxIDX[1], GENDATA_tSpreadPWM3DyIDX[1], NULL); + + /* Request and initialise required Kernel managed map for 3D PWM 3 */ + GENDATA_tMapPWMIDX[2] = SETUP_tSetupMap((void*)&USERCAL_stRAMCAL.aUserPWM3D_3Data, (void*)&GENDATA_u16PWMOutput[10], TYPE_enUInt16, 17, 17, GENDATA_tSpreadPWM3DxIDX[2], GENDATA_tSpreadPWM3DyIDX[2], NULL); + + /* Request and initialise required Kernel managed map for 3D PWM 4 */ + GENDATA_tMapPWMIDX[3] = SETUP_tSetupMap((void*)&USERCAL_stRAMCAL.aUserPWM3D_4Data, (void*)&GENDATA_u16PWMOutput[11], TYPE_enUInt16, 17, 17, GENDATA_tSpreadPWM3DxIDX[3], GENDATA_tSpreadPWM3DyIDX[3], NULL); + + + for (u32OutputIDX = 0; u32OutputIDX < 8; u32OutputIDX++) + { + /* Request and initialise 2D PWM ***************************/ + if (EH_IO_Invalid > USERCAL_stRAMCAL.aPWM2DIOOutputResource[u32OutputIDX]) + { + enEHIOResource = USERCAL_stRAMCAL.aPWM2DIOOutputResource[u32OutputIDX]; + enEHIOType = IOAPI_enPWM; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, + (void*)NULL, (void*)NULL); + + /* Initialise the TEPM channel PWM */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMChannelCB.enAction = TEPMAPI_enSetLow; + stTEPMChannelCB.boInterruptEnable = TRUE; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMChannelCB); + } + + /* Switch out off at timer ms */ + GENDATA_astTimedKernelEvents[0].enAction = TEPMAPI_enSetLow; + GENDATA_astTimedKernelEvents[0].enMethod = TEPMAPI_enHardLinkedTimeStep; + GENDATA_astTimedKernelEvents[0].ptEventTime = &GENDATA_u32PWMOutput[u32OutputIDX]; + GENDATA_astTimedKernelEvents[0].tAccumulate = USERCAL_stRAMCAL.aUserPWM2DPeriod[u32OutputIDX]; + + USER_vSVC(SYSAPI_enConfigureKernelTEPMOutput, (void*)&enEHIOResource, + (void*)&GENDATA_astTimedKernelEvents[0], (void*)&tEventCount); + } + } + + for (u32OutputIDX = 0; u32OutputIDX < 4; u32OutputIDX++) + { + /* Request and initialise 2D PWM ***************************/ + if (EH_IO_Invalid > USERCAL_stRAMCAL.aPWM3DIOOutputResource[u32OutputIDX]) + { + enEHIOResource = USERCAL_stRAMCAL.aPWM3DIOOutputResource[u32OutputIDX]; + enEHIOType = IOAPI_enPWM; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, + (void*)NULL, (void*)NULL); + + /* Initialise the TEPM channel PWM */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMChannelCB.enAction = TEPMAPI_enSetLow; + stTEPMChannelCB.boInterruptEnable = TRUE; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMChannelCB); + } + + /* Switch out off at timer ms */ + GENDATA_astTimedKernelEvents[0].enAction = TEPMAPI_enSetLow; + GENDATA_astTimedKernelEvents[0].enMethod = TEPMAPI_enHardLinkedTimeStep; + GENDATA_astTimedKernelEvents[0].ptEventTime = &GENDATA_u32PWMOutput[u32OutputIDX + 8]; + GENDATA_astTimedKernelEvents[0].tAccumulate = USERCAL_stRAMCAL.aUserPWM3DPeriod[u32OutputIDX + 8]; + + USER_vSVC(SYSAPI_enConfigureKernelTEPMOutput, (void*)&enEHIOResource, + (void*)&GENDATA_astTimedKernelEvents[0], (void*)&tEventCount); + } + } + + enEHIOType = IOAPI_enDIOOutput; + enDriveStrength = IOAPI_enStrong; + + if (EH_IO_Invalid > USERCAL_stRAMCAL.aPWM3DSlowIOOutputResource[0]) + { + enEHIOResource = USERCAL_stRAMCAL.aPWM3DSlowIOOutputResource[0]; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + } + + if (EH_IO_Invalid > USERCAL_stRAMCAL.aPWM3DSlowIOOutputResource[1]) + { + enEHIOResource = USERCAL_stRAMCAL.aPWM3DSlowIOOutputResource[1]; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + } + + if (EH_IO_Invalid > USERCAL_stRAMCAL.aPWM3DSlowIOOutputResource[2]) + { + enEHIOResource = USERCAL_stRAMCAL.aPWM3DSlowIOOutputResource[2]; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + } + + if (EH_IO_Invalid > USERCAL_stRAMCAL.aPWM3DSlowIOOutputResource[3]) + { + enEHIOResource = USERCAL_stRAMCAL.aPWM3DSlowIOOutputResource[3]; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + } +} + +void GENDATA_vRun(puint32 const pu32Arg) +{ + static uint32 u32SampleCount = 0; + static uint32 au32PWMSlowCount[4]; + static bool aboPWMOn[4]; + uint16 u16GenIDXX; + uint16 u16GenIDXY; + uint32 u32Temp; + IOAPI_tenTriState enTriState; + IOAPI_tenEHIOResource enEHIOResource; + + /* Buffer GENDATA_enBoostValve */ + GENDATA_s32VARS[GENDATA_enBoostValve] = MAP_u16PressureValveDuty; + + /* Buffer GENDATA_enThrottleAngle */ + GENDATA_s32VARS[GENDATA_enThrottleAngle] = TPS_tThetaFiltered; + + /* Buffer GENDATA_enCTS */ + GENDATA_s32VARS[GENDATA_enCTS] = CTS_tTempCFiltered; + + /* Buffer GENDATA_enEngineSpeed */ + GENDATA_s32VARS[GENDATA_enEngineSpeed] = CAM_u32RPMFiltered; + + + u16GenIDXX = USERCAL_stRAMCAL.aPWM2DAxesSourceXIDX[u32SampleCount]; + GENDATA_s32SOURCE[u32SampleCount] = GENDATA_s32VARS[u16GenIDXX]; + + if (~0 != u16GenIDXX) + { + /* Calculate the current generic spread */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&GENDATA_tSpreadPWM2DxIDX[u32SampleCount], + NULL, NULL); + + /* Lookup the current generic table */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&GENDATA_tTablePWMIDX[u32SampleCount], + NULL, NULL); + + GENDATA_u32PWMOutput[u32SampleCount] = GENDATA_u16PWMOutput[u32SampleCount]; + } + + u16GenIDXX = USERCAL_stRAMCAL.aPWM2DAxesSourceXIDX[u32SampleCount]; + GENDATA_s32SOURCE[u32SampleCount] = GENDATA_s32VARS[u16GenIDXX]; + + if (0xff != u16GenIDXX) + { + /* Calculate the current generic spread */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&GENDATA_tSpreadPWM2DxIDX[u32SampleCount], + NULL, NULL); + + /* Lookup the current generic table */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&GENDATA_tTablePWMIDX[u32SampleCount], + NULL, NULL); + + GENDATA_u32PWMOutput[u32SampleCount] = GENDATA_u16PWMOutput[u32SampleCount]; + } + + + u16GenIDXX = USERCAL_stRAMCAL.aPWM3DAxesSourceXIDX[u32SampleCount % 4]; + u16GenIDXY = USERCAL_stRAMCAL.aPWM3DAxesSourceYIDX[u32SampleCount % 4]; + + GENDATA_s32SOURCE[8 + (u32SampleCount % 4)] = GENDATA_s32VARS[u16GenIDXX]; + GENDATA_s32SOURCE[12 + (u32SampleCount % 4)] = GENDATA_s32VARS[u16GenIDXY]; + + if ((0xff != u16GenIDXX) && (0xff != u16GenIDXX)) + { + /* Calculate the current generic spread X */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&GENDATA_tSpreadPWM3DxIDX[u32SampleCount % 4], + NULL, NULL); + + /* Calculate the current generic spread Y */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&GENDATA_tSpreadPWM3DyIDX[u32SampleCount % 4], + NULL, NULL); + + /* Lookup the current generic map */ + USER_vSVC(SYSAPI_enCalculateMap, (void*)&GENDATA_tMapPWMIDX[u32SampleCount % 4], + NULL, NULL); + + + GENDATA_u32PWMOutput[8 + (u32SampleCount % 4)] = GENDATA_u16PWMOutput[8 + (u32SampleCount % 4)]; + } + + u32SampleCount = 7 > u32SampleCount ? u32SampleCount + 1 : 0; + + for (u16GenIDXX = 0; u16GenIDXX < 4; u16GenIDXX++) + { + if (EH_IO_Invalid > USERCAL_stRAMCAL.aPWM3DSlowIOOutputResource[u16GenIDXX]) + { + if ((USERCAL_stRAMCAL.aPWM3DSlowPeriod[u16GenIDXX] - 1) > au32PWMSlowCount[u16GenIDXX]) + { + au32PWMSlowCount[u16GenIDXX]++; + u32Temp = (GENDATA_u32PWMOutput[8 + u16GenIDXX] * USERCAL_stRAMCAL.aPWM3DSlowPeriod[u16GenIDXX]) / 0x10000; + + if ((u32Temp <= au32PWMSlowCount[u16GenIDXX]) && (TRUE == aboPWMOn[u16GenIDXX])) + { + enEHIOResource = USERCAL_stRAMCAL.aPWM3DSlowIOOutputResource[u16GenIDXX]; + enTriState = IOAPI_enLow; + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, + (void*)&enTriState, (void*)NULL); + aboPWMOn[u16GenIDXX] = FALSE; + } + } + else + { + aboPWMOn[u16GenIDXX] = TRUE; + au32PWMSlowCount[u16GenIDXX] = 0; + enEHIOResource = USERCAL_stRAMCAL.aPWM3DSlowIOOutputResource[u16GenIDXX]; + enTriState = IOAPI_enHigh; + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, + (void*)&enTriState, (void*)NULL); + } + } + } +} + +void GENDATA_vTerminate(puint32 const pu32Arg) +{ + +} + + + +#endif //BUILD_USER diff --git a/source/Client/GENDATA.h b/source/Client/GENDATA.h new file mode 100644 index 0000000..df3593a --- /dev/null +++ b/source/Client/GENDATA.h @@ -0,0 +1,83 @@ +/******************************************************************************/ +/* Copyright (c) 2019 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Generic Data Header File */ +/* DESCRIPTION: This code module contains generic data transforms */ +/* */ +/* FILE NAME: gendata.c */ +/* REVISION HISTORY: 28-06-2019 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef GENDATA_H +#define GENDATA_H + +#include "MAPSAPI.h" +#include "TABLESAPI.h" + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _GENDATA_C + #define EXTERN +#else + #define EXTERN extern +#endif + +#define GENDATA_nPWM2DTableCount 8 +#define GENDATA_nPWM3DTableCount 4 +#define GENDATA_nPWM2DTableDimX 17 +#define GENDATA_nPWM3DTableDimX 17 +#define GENDATA_nPWM3DTableDimY 17 +#define GENDATA_nVarsCount 50 + +typedef enum +{ + GENDATA_enEngineSpeed, + GENDATA_enThrottleAngle, + GENDATA_enMAPKpa, + GENDATA_enCTS, + GENDATA_enATS, + GENDATA_enBoostValve +} GENDATA_tenGenericDataIDX; + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +EXTERN sint32 GENDATA_s32VARS[16]; +//ASAM mode=readvalue name="Generic Data 1|LINK|Engine Speed Raw" type=uint16 offset=0 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic RPM" +//ASAM mode=readvalue name="Generic Data 2|LINK|Throttle Angle" type=uint16 offset=2 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic TPS" +//ASAM mode=readvalue name="Generic Data 3|LINK|MAP kPa" type=uint16 offset=4 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic MAP" +//ASAM mode=readvalue name="Generic Data 4|LINK|Coolant Temperature" type=uint16 offset=6 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic CTS" +//ASAM mode=readvalue name="Generic Data 5|LINK|Air Temperature" type=uint16 offset=8 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic ATS" +//ASAM mode=readvalue name="Generic Data 6|LINK|Boost Valve Duty" type=uint16 offset=10 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic Boost Valve" + +EXTERN sint32 GENDATA_s32SOURCE[16]; +//ASAM mode=readvalue name="Generic Source IDX1" type=uint16 offset=0 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic Source IDX1" +//ASAM mode=readvalue name="Generic Source IDX2" type=uint16 offset=2 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic Source IDX2" +//ASAM mode=readvalue name="Generic Source IDX3" type=uint16 offset=4 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic Source IDX3" +//ASAM mode=readvalue name="Generic Source IDX4" type=uint16 offset=6 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic Source IDX4" +//ASAM mode=readvalue name="Generic Source IDX5" type=uint16 offset=8 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic Source IDX5" +//ASAM mode=readvalue name="Generic Source IDX6" type=uint16 offset=10 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic Source IDX6" +//ASAM mode=readvalue name="Generic Source IDX7" type=uint16 offset=12 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic Source IDX7" +//ASAM mode=readvalue name="Generic Source IDX8" type=uint16 offset=14 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic Source IDX8" +//ASAM mode=readvalue name="Generic Source IDX9" type=uint16 offset=16 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic Source IDX9" +//ASAM mode=readvalue name="Generic Source IDX10" type=uint16 offset=18 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic Source IDX10" +//ASAM mode=readvalue name="Generic Source IDX11" type=uint16 offset=20 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic Source IDX11" +//ASAM mode=readvalue name="Generic Source IDX12" type=uint16 offset=22 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic Source IDX12" +//ASAM mode=readvalue name="Generic Source IDX13" type=uint16 offset=24 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic Source IDX13" +//ASAM mode=readvalue name="Generic Source IDX14" type=uint16 offset=26 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic Source IDX14" +//ASAM mode=readvalue name="Generic Source IDX15" type=uint16 offset=28 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic Source IDX15" +//ASAM mode=readvalue name="Generic Source IDX16" type=uint16 offset=30 min=0 max=32767 m=1 b=-32768 units="dl" format=5.3 help="Generic Source IDX16" +EXTERN uint16 GENDATA_u16PWMOutput[12]; +EXTERN uint32 GENDATA_u32PWMOutput[12]; + + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void GENDATA_vStart(uint32 * const pu32Arg); +void GENDATA_vRun(uint32* const pu32Arg); +void GENDATA_vTerminate(uint32* const pu32Arg); + + +#endif // GENDATA_H diff --git a/source/Client/IAC.c b/source/Client/IAC.c new file mode 100644 index 0000000..4f6955b --- /dev/null +++ b/source/Client/IAC.c @@ -0,0 +1,727 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Idle Air Control */ +/* DESCRIPTION: This code module initialises the required */ +/* resources and functions for idle air control */ +/* */ +/* FILE NAME: IAC.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _IAC_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "IAC.h" + +#include "usercal.h" + + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +#ifdef BUILD_BSP_IAC_STEPPER +uint32 IAC_u32TargetStep; +uint32 IAC_u32TargetStepNormalised; +uint32 IAC_u32FeedbackStep; +// mode=readvalue name="IAC Step" type=uint32 offset=0 min=0 max=255 m=1 b=0 units="dl" format=5.3 help="IAC Current Stepper Position" +uint32 IAC_u32StepsLearnedMin; +// mode=readvalue name="IAC Step Learned Min" type=uint32 offset=0 min=0 max=255 m=1 b=0 units="dl" format=5.3 help="IAC Learned Min Position" +IAC_tenStepperState IAC_enStepperState; +uint32 IAC_u32StepCounter; +uint32 IAC_u32StepCounterLimit; +uint8 IAC_u8StepArray[4]; +#endif + +uint32 IAC_u32IdleEntryTimer; +uint32 IAC_u32RPMLongAverage; +SPREADAPI_ttSpreadIDX IAC_tSpreadISCTargetIDX; +TABLEAPI_ttTableIDX IAC_tTableISCTargetIDX; +uint16 IAC_u16ISCTarget; +uint16 IAC_u16ISCTargetRamp; +//ASAM mode=readvalue name="IAC Target RPM" type=uint16 offset=0 min=0 max=4095 m=1 b=0 units="RPM" format=4.0 help="IAC Current Target RPM" +uint16 IAC_u16ISCTargetRampOld; +bool IAC_boRun; + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ +#ifdef BUILD_BSP_IAC_STEPPER +static bool IAC_boUnderStepMins(void); +static uint32 IAC_u32GetOpenStepsTempNormalised(uint32 u32Temp); +#endif //BUILD_BSP_IAC_STEPPER + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void IAC_vStart(puint32 const pu32Arg) +{ +#ifdef BUILD_BSP_IAC_STEPPER + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenEHIOType enEHIOType; + IOAPI_tenDriveStrength enDriveStrength = IOAPI_enWeak; + + IAC_u32TargetStep = 0; + IAC_u32FeedbackStep = 0; + IAC_enStepperState = IAC_enResetHome; + IAC_u32StepCounter = 0; + IAC_u32StepCounterLimit = 0; + + enEHIOType = IOAPI_enDIOOutput; + enDriveStrength = IOAPI_enStrong; + + if (EH_IO_Invalid > USERCAL_stRAMCAL.aIACIOResource[0]) + { + enEHIOResource = USERCAL_stRAMCAL.aIACIOResource[0]; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + } + + if (EH_IO_Invalid > USERCAL_stRAMCAL.aIACIOResource[1]) + { + enEHIOResource = USERCAL_stRAMCAL.aIACIOResource[1]; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + } + + if (EH_IO_Invalid > USERCAL_stRAMCAL.aIACIOResource[2]) + { + enEHIOResource = USERCAL_stRAMCAL.aIACIOResource[2]; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + } + + if (EH_IO_Invalid > USERCAL_stRAMCAL.aIACIOResource[3]) + { + enEHIOResource = USERCAL_stRAMCAL.aIACIOResource[3]; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + } + + +#endif + + IAC_u32IdleEntryTimer = 0; + IAC_u32RPMLongAverage = 0; + IAC_enControlState = IAC_enOpenLoop; + + /* Request and initialise required Kernel managed spread for ISC target spread*/ + IAC_tSpreadISCTargetIDX = SETUP_tSetupSpread((void*)&CTS_tTempCFiltered, (void*)&USERCAL_stRAMCAL.aUserISCSpeedTargetSpread , TYPE_enInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for ISC target */ + IAC_tTableISCTargetIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserISCSpeedTargetTable, (void*)&IAC_u16ISCTarget, TYPE_enUInt16, 17, IAC_tSpreadISCTargetIDX, NULL); +} + +void IAC_vRun(puint32 const pu32Arg) +{ +#ifdef BUILD_BSP_IAC_STEPPER + IOAPI_tenTriState enTriState; + IOAPI_tenEHIOResource enEHIOResource; + uint32 u32OpenLoopTargetStep; + uint32 u32OpenLoopTargetStepNormalised; + uint32 u32TempClipped; + static uint32 u32StepsLearnedCount; +#endif + + uint32 u32Temp; + sint32 s32Temp; + static sint32 s32RPMErrOld; + sint32 s32ErrDelta; + sint32 s32ErrDeltaAbs; + uint32 u32IdleEntryRPM; + static uint32 u32ISCCount; + static uint16 u16TargetRamp = 200; + static uint16 u16AfterStartTargetRamp = 200; + static uint32 u32OBDAdvFiltered = 500 * (0x80 + 40); + static uint16 u16ISCMin = 0; + static uint16 u16ISCMax = 4096; + uint16 u16TempMin; + uint16 u16TempMax; + + if (TRUE == IAC_boRun) + { + /* Calculate the current spread for ISC target */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&IAC_tSpreadISCTargetIDX, + NULL, NULL); + + /* Lookup the current value for ISC target */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&IAC_tTableISCTargetIDX, + NULL, NULL); + + IAC_boOverrunCutRPMEnable = (IAC_u16ISCTarget + USERCAL_stRAMCAL.u16OverrunCutEnableRPM) > CAM_u32RPMRaw ? FALSE : IAC_boOverrunCutRPMEnable; + IAC_boOverrunCutRPMEnable = (IAC_u16ISCTarget + USERCAL_stRAMCAL.u16OverrunCutDisableRPM) < CAM_u32RPMRaw ? TRUE : IAC_boOverrunCutRPMEnable; + + u32IdleEntryRPM = IAC_u16ISCTarget + USERCAL_stRAMCAL.u16IdleEntryOffset; + IAC_u16ISCTargetRamp = IAC_u16ISCTarget + u16TargetRamp + u16AfterStartTargetRamp; + + if (USERCAL_stRAMCAL.u16RPMRunThreshold < CAM_u32RPMRaw) + { + (void)USERMATH_u16SinglePoleLowPassFilter16((uint16)CAM_u32RPMRaw, + 0x10, &IAC_u32RPMLongAverage); + } + else + { + IAC_u32RPMLongAverage = 0x100 * CAM_u32RPMRaw; + } + + + if ((u32IdleEntryRPM > CAM_u32RPMRaw) && + (TRUE == TPS_boThrottleClosed) && + (0 != CAM_u32RPMRaw)) + { + s32Temp = (sint32)(IAC_u32RPMLongAverage / 0x100) - (sint32)CAM_u32RPMRaw; + s32Temp = ABS(s32Temp); + + if (300 > s32Temp) + { + if (10 < IAC_u32IdleEntryTimer) + { + IAC_enControlState = IAC_enClosedLoop; + } + else + { + IAC_u32IdleEntryTimer++; + } + } + else + { + IAC_u32IdleEntryTimer = 0; + } + } + else + { + IAC_u32IdleEntryTimer = 0; + IAC_enControlState = IAC_enOpenLoop; + } + + if (0 > CTS_tTempCFiltered) + { + u16TempMin = USERCAL_stRAMCAL.u16ISCColdISCMin; + u16TempMax = USERCAL_stRAMCAL.u16ISCColdISCMax; + } + else if (50000 < CTS_tTempCFiltered) + { + u16TempMin = USERCAL_stRAMCAL.u16ISCHotISCMin; + u16TempMax = USERCAL_stRAMCAL.u16ISCHotISCMax; + } + else if ((USERCAL_stRAMCAL.u16ISCColdISCMin >= USERCAL_stRAMCAL.u16ISCHotISCMin) && + (USERCAL_stRAMCAL.u16ISCColdISCMax >= USERCAL_stRAMCAL.u16ISCHotISCMax)) + { + u16TempMin = USERCAL_stRAMCAL.u16ISCHotISCMin + + ((USERCAL_stRAMCAL.u16ISCColdISCMin - USERCAL_stRAMCAL.u16ISCHotISCMin) * (50 - (CTS_tTempCFiltered / 1000)) / + 50); + + u16TempMax = USERCAL_stRAMCAL.u16ISCHotISCMax + + ((USERCAL_stRAMCAL.u16ISCColdISCMax - USERCAL_stRAMCAL.u16ISCHotISCMax) * (50 - (CTS_tTempCFiltered / 1000)) / + 50); + } + + /* Ramp the min/max */ + if (400 > CAM_u32RPMFiltered) + { + u16ISCMin = 2048; + u16ISCMax = 4096; + } + else + { + if ((u16TempMin + 10) < u16ISCMin) + { + u16ISCMin -= 10; + } + else if (u16TempMin > (u16ISCMin + 10)) + { + u16ISCMin += 10; + } + + if ((u16TempMax + 10) < u16ISCMax) + { + u16ISCMax -= 10; + } + else if (u16TempMax > (u16ISCMax + 10)) + { + u16ISCMax += 10; + } + } + + + if (IAC_enClosedLoop == IAC_enControlState) + { + if (TRUE == USERCAL_stRAMCAL.boOBDISCADV) + { + if (TRUE == SENSORS_boOBDAdvNewSample) + { + s32Temp = 500 * SENSORS_u8OBDAdv; + u32OBDAdvFiltered = ((7 * u32OBDAdvFiltered) / 8) + s32Temp / 8; + + if ((128 * 500) < s32Temp) + { + IAC_s32ISCESTTrim[0] = s32Temp - 128 * 500; + IAC_s32ISCESTTrim[1] = s32Temp - 128 * 500; + } + else + { + IAC_s32ISCESTTrim[0] = 0; + IAC_s32ISCESTTrim[1] = 0; + } + + SENSORS_boOBDAdvNewSample = FALSE; + } + else + { + if (((sint32)u32OBDAdvFiltered - 128 * 500 + 2000) < IAC_s32ISCESTTrim[0]) + { + IAC_s32ISCESTTrim[0] -= 2000; + IAC_s32ISCESTTrim[1] -= 2000; + } + if (((sint32)u32OBDAdvFiltered - 128 * 500 - 2000) > IAC_s32ISCESTTrim[0]) + { + IAC_s32ISCESTTrim[0] += 2000; + IAC_s32ISCESTTrim[1] += 2000; + } + } + } + else + { + if ((IAC_u16ISCTargetRamp - USERCAL_stRAMCAL.u16StallSaverRPMThreshold) > (uint16)CAM_u32RPMRaw) + { + /* Stall saver */ + u16TargetRamp = USERCAL_stRAMCAL.u16ISCEntryRamp; + } + + /* Hold the rpm error in s32Temp */ + s32Temp = (sint32)IAC_u16ISCTargetRamp - (sint32)CAM_u32RPMRaw; + + if (IAC_u16ISCTargetRamp <= IAC_u16ISCTargetRampOld) + { + if ((IAC_u16ISCTargetRampOld - IAC_u16ISCTargetRamp) < 20) + { + s32ErrDelta = s32Temp - s32RPMErrOld; + } + else + { + s32ErrDelta = 0; + } + } + else + { + if ((IAC_u16ISCTargetRamp - IAC_u16ISCTargetRampOld) < 20) + { + s32ErrDelta = s32Temp - s32RPMErrOld; + } + else + { + s32ErrDelta = 0; + } + } + + s32ErrDeltaAbs = ABS(s32ErrDelta); + s32RPMErrOld = (sint32)IAC_u16ISCTargetRamp - (sint32)CAM_u32RPMRaw; + IAC_u16ISCTargetRampOld = IAC_u16ISCTargetRamp; + + if (0 <= s32Temp) + { + s32Temp = 40 < s32Temp ? s32Temp - 40 : 0; + } + else + { + s32Temp = -40 > s32Temp ? s32Temp + 40 : 0; + } + + if (20 > s32ErrDeltaAbs) + { + s32ErrDelta = 0; + } + else + { + if (0 > s32ErrDelta) + { + s32ErrDelta += 20; + s32ErrDelta *= 2; + } + else + { + s32ErrDelta -= 20; + s32ErrDelta *= 2; + } + } + + s32Temp /= 4; + s32Temp += s32ErrDelta; + + if ((0 == TPS_u16CANTPSDeltaNegCount) && (0 == TPS_u16CANTPSDeltaPosCount)) + { + if (0 <= s32Temp) + { + CPU_xEnterCritical(); + IAC_s32ISCESTTrim[0] = (sint32)USERCAL_stRAMCAL.u32ISCESTTrimPos > (USERCAL_stRAMCAL.u16ESTCLGain * s32Temp) ? (USERCAL_stRAMCAL.u16ESTCLGain * s32Temp) : USERCAL_stRAMCAL.u32ISCESTTrimPos; + IAC_s32ISCESTTrim[1] = (sint32)USERCAL_stRAMCAL.u32ISCESTTrimPos > (USERCAL_stRAMCAL.u16ESTCLGain * s32Temp) ? (USERCAL_stRAMCAL.u16ESTCLGain * s32Temp) : USERCAL_stRAMCAL.u32ISCESTTrimPos; + CPU_xExitCritical(); + } + else + { + CPU_xEnterCritical(); + IAC_s32ISCESTTrim[0] = (sint32)~USERCAL_stRAMCAL.u32ISCESTTrimNeg < (USERCAL_stRAMCAL.u16ESTCLGain * s32Temp) ? (USERCAL_stRAMCAL.u16ESTCLGain * s32Temp) : (sint32)~USERCAL_stRAMCAL.u32ISCESTTrimNeg; + IAC_s32ISCESTTrim[1] = (sint32)~USERCAL_stRAMCAL.u32ISCESTTrimNeg < (USERCAL_stRAMCAL.u16ESTCLGain * s32Temp) ? (USERCAL_stRAMCAL.u16ESTCLGain * s32Temp) : (sint32)~USERCAL_stRAMCAL.u32ISCESTTrimNeg; + CPU_xExitCritical(); + } + } + } + + +#ifndef BUILD_BSP_IAC_STEPPER + /* Closed loop airflow */ + s32Temp = (sint32)IAC_u16ISCTargetRamp - (sint32)CAM_u32RPMRaw; + s32Temp = ABS(s32Temp); + + if (60 < s32Temp) + { + if (IAC_u16ISCTargetRamp > CAM_u32RPMRaw) + { + IAC_u32ISCDuty += (IAC_u16ISCTargetRamp - CAM_u32RPMRaw - 60); + IAC_u32ISCDuty = 0x1000 < IAC_u32ISCDuty ? 0x1000 : IAC_u32ISCDuty; + } + else + { + u32Temp = CAM_u32RPMRaw - IAC_u16ISCTargetRamp - 60; + u32Temp = 50 < u32Temp ? 50 : u32Temp; + + if (IAC_u32ISCDuty > u32Temp) + { + + IAC_u32ISCDuty -= (u32Temp / 8); + } + } + + IAC_u32ISCDuty = u16ISCMin <= IAC_u32ISCDuty ? IAC_u32ISCDuty : u16ISCMin; + IAC_u32ISCDuty = u16ISCMax >= IAC_u32ISCDuty ? IAC_u32ISCDuty : u16ISCMax; + } + + IAC_u8SlaveTarget = 0x10 + (IAC_u32ISCDuty / 0x100); + +#endif //BUILD_BSP_IAC_STEPPER + + if ((IAC_u16ISCTargetRamp + 250) > (uint16)CAM_u32RPMRaw) + { + u16TargetRamp = 0 < u16TargetRamp ? u16TargetRamp - 1 : 0; + } + } + else + { + IAC_s32ISCESTTrim[0] = 0; + IAC_s32ISCESTTrim[1] = 0; + + /* Open loop duty */ + IAC_u32ISCDuty = (u16ISCMin + u16ISCMax) / 2; + IAC_u8SlaveTarget = 0x10 + (IAC_u32ISCDuty / 0x100); + u16TargetRamp = USERCAL_stRAMCAL.u16ISCEntryRamp; + } + + IAC_boRun = FALSE; + } + +#ifdef BUILD_BSP_IAC_STEPPER + if (TRUE == USERCAL_stRAMCAL.u8StepperIACEnable) + { + if (IAC_enResetHome == IAC_enStepperState) + { + if (0 == IAC_u32StepCounterLimit) + { + /* If we have just started the stepper reset sequence */ + IAC_u32StepCounter = 0; + IAC_u32TargetStepNormalised = 0; + IAC_u32TargetStep = 0; + IAC_u32StepCounterLimit = 4 * USERCAL_stRAMCAL.u32UserStepperHomeSteps; + IAC_u32StepsLearnedMin = ~0; + u32StepsLearnedCount = 0; + IAC_u8StepArray[0] = USERCAL_stRAMCAL.aUserStepperCloseTable[0]; + IAC_u8StepArray[1] = USERCAL_stRAMCAL.aUserStepperCloseTable[1]; + IAC_u8StepArray[2] = USERCAL_stRAMCAL.aUserStepperCloseTable[2]; + IAC_u8StepArray[3] = USERCAL_stRAMCAL.aUserStepperCloseTable[3]; + } + else if (IAC_u32StepCounterLimit == IAC_u32StepCounter) + { + /* If the stepper reset sequence is complete */ + IAC_u32StepCounter = 0; + + + if (0 <= CTS_tTempCFiltered) + { + u32Temp = 100000 > CTS_tTempCFiltered ? CTS_tTempCFiltered : 100000; + } + else + { + u32Temp = 0; + } + + IAC_u32TargetStepNormalised = IAC_u32GetOpenStepsTempNormalised(u32Temp); + IAC_u32TargetStep = (USERCAL_stRAMCAL.u16IACStepsOpenCold * IAC_u32TargetStepNormalised) / 256; + + IAC_u32FeedbackStep = 0; + IAC_u32StepCounterLimit = 4 * IAC_u32TargetStep; + IAC_u8StepArray[0] = USERCAL_stRAMCAL.aUserStepperOpenTable[0]; + IAC_u8StepArray[1] = USERCAL_stRAMCAL.aUserStepperOpenTable[1]; + IAC_u8StepArray[2] = USERCAL_stRAMCAL.aUserStepperOpenTable[2]; + IAC_u8StepArray[3] = USERCAL_stRAMCAL.aUserStepperOpenTable[3]; + IAC_enStepperState = IAC_enNormal; + } + } + else if (IAC_enNormal == IAC_enStepperState) + { + if (IAC_u32StepCounterLimit == IAC_u32StepCounter) + { + if (0 <= CTS_tTempCFiltered) + { + u32TempClipped = 100000 > CTS_tTempCFiltered ? CTS_tTempCFiltered : 100000; + } + else + { + u32TempClipped = 0; + } + + u32OpenLoopTargetStepNormalised = IAC_u32GetOpenStepsTempNormalised(u32TempClipped); + + if (IAC_enOpenLoop == IAC_enControlState) + { + IAC_u32TargetStepNormalised = u32OpenLoopTargetStepNormalised; + u32StepsLearnedCount = 0; + } + else + { + /* Closed loop */ + s32Temp = (sint32)IAC_u16ISCTarget - (sint32)CAM_u32RPMRaw; + s32Temp = ABS(s32Temp); + + if (60 < s32Temp) + { + u32ISCCount++; + u32StepsLearnedCount = 0; + + if (IAC_u16ISCTarget > CAM_u32RPMRaw) + { + if (0 == (u32ISCCount % 4)) + { + IAC_u32TargetStepNormalised = u32OpenLoopTargetStepNormalised > IAC_u32TargetStepNormalised ? + IAC_u32TargetStepNormalised + 1 : IAC_u32TargetStepNormalised; + } + } + else + { + if (USERCAL_stRAMCAL.u16IACStepsOpenHot > ((IAC_u32TargetStepNormalised * USERCAL_stRAMCAL.u16IACStepsOpenHot) / 256)) + { + if (250 < s32Temp) + { + if (false == IAC_boUnderStepMins()) + { + if (0 == (u32ISCCount % 8)) + { + IAC_u32TargetStepNormalised = (0 < IAC_u32TargetStepNormalised) ? + IAC_u32TargetStepNormalised - 1 : IAC_u32TargetStepNormalised; + } + } + else + { + /* Proceed very slowly to learn when under min learn */ + if (0 == (u32ISCCount % 16)) + { + IAC_u32TargetStepNormalised = (0 < IAC_u32TargetStepNormalised) ? + IAC_u32TargetStepNormalised - 1 : IAC_u32TargetStepNormalised; + } + } + } + else + { + if (false == IAC_boUnderStepMins()) + { + if (0 == (u32ISCCount % 16)) + { + IAC_u32TargetStepNormalised = (0 < IAC_u32TargetStepNormalised) ? + IAC_u32TargetStepNormalised - 1 : IAC_u32TargetStepNormalised; + } + } + else + { + /* Proceed very slowly to learn when under min learn */ + if (0 == (u32ISCCount % 64)) + { + IAC_u32TargetStepNormalised = (0 < IAC_u32TargetStepNormalised) ? + IAC_u32TargetStepNormalised - 1 : IAC_u32TargetStepNormalised; + } + } + } + } + else + { + if (0 == (u32ISCCount % 16)) + { + IAC_u32TargetStep = (0 < IAC_u32TargetStep) ? + IAC_u32TargetStep - 1 : IAC_u32TargetStep; + } + } + } + } + else + { + u32ISCCount = 0; + u32StepsLearnedCount++; + + if ((IAC_LEARN_COUNTS - 1) == (u32StepsLearnedCount % IAC_LEARN_COUNTS)) + { + if (~0 == IAC_u32StepsLearnedMin) + { + IAC_u32StepsLearnedMin = IAC_u32FeedbackStep; + } + else + { + if (IAC_u32FeedbackStep < IAC_u32StepsLearnedMin) + { + if ((IAC_u32StepsLearnedMin - IAC_u32FeedbackStep) > (USERCAL_stRAMCAL.u16IACStepsOpenHot / 2)) + { + IAC_u32StepsLearnedMin -= (USERCAL_stRAMCAL.u16IACStepsOpenHot / 2); + } + else + { + IAC_u32StepsLearnedMin = IAC_u32StepsLearnedMin - 1; + } + } + else if (IAC_u32FeedbackStep > IAC_u32StepsLearnedMin) + { + IAC_u32StepsLearnedMin = IAC_u32FeedbackStep; + } + } + } + } + } + + IAC_u32TargetStep = IAC_u32TargetStepNormalised * USERCAL_stRAMCAL.u16IACStepsOpenCold / 0x100; + s32Temp = (sint32)IAC_u32TargetStep - (sint32)IAC_u32FeedbackStep; + + if (1 < (ABS(s32Temp))) + { + if (IAC_u32TargetStep < IAC_u32FeedbackStep) + { + IAC_u8StepArray[0] = USERCAL_stRAMCAL.aUserStepperCloseTable[0]; + IAC_u8StepArray[1] = USERCAL_stRAMCAL.aUserStepperCloseTable[1]; + IAC_u8StepArray[2] = USERCAL_stRAMCAL.aUserStepperCloseTable[2]; + IAC_u8StepArray[3] = USERCAL_stRAMCAL.aUserStepperCloseTable[3]; + IAC_u32StepCounterLimit = 4; + IAC_u32StepCounter = 0; + } + else + { + IAC_u8StepArray[0] = USERCAL_stRAMCAL.aUserStepperOpenTable[0]; + IAC_u8StepArray[1] = USERCAL_stRAMCAL.aUserStepperOpenTable[1]; + IAC_u8StepArray[2] = USERCAL_stRAMCAL.aUserStepperOpenTable[2]; + IAC_u8StepArray[3] = USERCAL_stRAMCAL.aUserStepperOpenTable[3]; + IAC_u32StepCounterLimit = 4; + IAC_u32StepCounter = 0; + } + } + } + } + + if (IAC_u32StepCounterLimit > IAC_u32StepCounter) + { + if (EH_IO_Invalid > USERCAL_stRAMCAL.aIACIOResource[0]) + { + enEHIOResource = USERCAL_stRAMCAL.aIACIOResource[0]; + enTriState = (0 == (0x01 & IAC_u8StepArray[IAC_u32StepCounter & 0x03])) ? IOAPI_enLow : IOAPI_enHigh; + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, + (void*)&enTriState, (void*)NULL); + } + + if (EH_IO_Invalid > USERCAL_stRAMCAL.aIACIOResource[1]) + { + enEHIOResource = USERCAL_stRAMCAL.aIACIOResource[1]; + enTriState = (0 == (0x02 & IAC_u8StepArray[IAC_u32StepCounter & 0x03])) ? IOAPI_enLow : IOAPI_enHigh; + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, + (void*)&enTriState, (void*)NULL); + } + + if (EH_IO_Invalid > USERCAL_stRAMCAL.aIACIOResource[2]) + { + enEHIOResource = USERCAL_stRAMCAL.aIACIOResource[2]; + enTriState = (0 == (0x04 & IAC_u8StepArray[IAC_u32StepCounter & 0x03])) ? IOAPI_enLow : IOAPI_enHigh; + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, + (void*)&enTriState, (void*)NULL); + } + + if (EH_IO_Invalid > USERCAL_stRAMCAL.aIACIOResource[3]) + { + enEHIOResource = USERCAL_stRAMCAL.aIACIOResource[3]; + enTriState = (0 == (0x08 & IAC_u8StepArray[IAC_u32StepCounter & 0x03])) ? IOAPI_enLow : IOAPI_enHigh; + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, + (void*)&enTriState, (void*)NULL); + } + + + IAC_u32StepCounter++; + + if (0 == (0x03 & IAC_u32StepCounter)) + { + if (IAC_u32FeedbackStep > IAC_u32TargetStep) + { + IAC_u32FeedbackStep--; + } + else if (IAC_u32FeedbackStep < IAC_u32TargetStep) + { + IAC_u32FeedbackStep++; + } + } + } + } +#endif //BUILD_BSP_IAC_STEPPER + + + if (400 > CAM_u32RPMFiltered) + { + u16AfterStartTargetRamp = USERCAL_stRAMCAL.u16ISCPostStartRamp; + } + else + { + if (0 == (u32ISCCount % 8)) + { + if (0 < u16AfterStartTargetRamp) + { + u16AfterStartTargetRamp--; + } + } + } + + + u32ISCCount++; +} + +#ifdef BUILD_BSP_IAC_STEPPER +static uint32 IAC_u32GetOpenStepsTempNormalised(uint32 u32Temp) +{ + static volatile uint32 u32OpenStepsNormalised; + static volatile uint32 u32ColdNormalisedSteps = 255; + static volatile uint32 u32HotNormalisedSteps; + + //u32HotNormalisedSteps = ((uint32)USERCAL_stRAMCAL.u16IACStepsOpenCold * 0x100ul) / (uint32)USERCAL_stRAMCAL.u16IACStepsOpenHot; + u32HotNormalisedSteps = 50; + u32OpenStepsNormalised = (((100000ul - u32Temp) * u32ColdNormalisedSteps) + (u32Temp * u32HotNormalisedSteps)) / 100000ul; + + return u32OpenStepsNormalised; +} +#endif //BUILD_BSP_IAC_STEPPER + +#ifdef BUILD_BSP_IAC_STEPPER +static bool IAC_boUnderStepMins(void) +{ + bool boUnderMins = IAC_u32StepsLearnedMin >= IAC_u32TargetStep; + + return boUnderMins; +} +#endif //BUILD_BSP_IAC_STEPPER + +void IAC_vTerminate(puint32 const pu32Arg) +{ + +} + + +void IAC_vCallBack(puint32 const pu32Arg) +{ + IAC_boRun = TRUE; +} + +#endif //BUILD_USER diff --git a/source/Client/IAC.h b/source/Client/IAC.h new file mode 100644 index 0000000..8c6dee9 --- /dev/null +++ b/source/Client/IAC.h @@ -0,0 +1,66 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Idle Air Control Header File */ +/* DESCRIPTION: This code module initialises the required */ +/* resources and functions for idle air control */ +/* */ +/* FILE NAME: IAC.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef IAC_H +#define IAC_H + +#include +#include "CTS.h" +#include "TPS.h" +#include "IOAPI.h" +#include "SETUP.h" +#include "USER.h" + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ + +#ifdef EXTERN +#undef EXTERN +#endif +#ifdef _IAC_C +#define EXTERN +#else +#define EXTERN extern +#endif + +#define IAC_LEARN_COUNTS 400 + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ + +typedef enum +{ + IAC_enResetHome, + IAC_enNormal +} IAC_tenStepperState; + +typedef enum +{ + IAC_enOpenLoop, + IAC_enClosedLoop +} IAC_tenControlState; + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +EXTERN uint32 IAC_u32ISCDuty; +EXTERN IAC_tenControlState IAC_enControlState; +EXTERN bool IAC_boOverrunCutRPMEnable; +EXTERN sint32 IAC_s32ISCESTTrim[2]; +EXTERN uint8 IAC_u8SlaveTarget; + + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void IAC_vStart(uint32 * const pu32Arg); +void IAC_vRun(uint32* const pu32Arg); +void IAC_vTerminate(uint32* const pu32Arg); +void IAC_vCallBack(puint32 const pu32Arg); + +#endif // MAP_H + diff --git a/source/Client/LSU4X.c b/source/Client/LSU4X.c new file mode 100644 index 0000000..7eea0da --- /dev/null +++ b/source/Client/LSU4X.c @@ -0,0 +1,520 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. */ +/* All rights reserved. */ +/******************************************************************************/ +/* */ +/* PACKAGE TITLE: LSU4.X */ +/* DESCRIPTION: This code module initialises the required ADC, DAC */ +/* CTRL, spread, table, DIO and TEPM resources for */ +/* managing the nernst cell voltage and impedence */ +/* measurement for the LSU4.X sensor/s */ +/* FILE NAME: LSU4X.c */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _LSU4X_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "LSU4X.h" + +/* LOCAL MACRO DEFINITIONS ****************************************************/ +#define LSU4X_nADConfigCount (sizeof(LSU4X_rastADConfig) / sizeof(LSU4X_tstADConfig)) + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +DACAPI_ttOutputVoltage LSU4X_atDACVoltageQueue[LSU_DEVICE_COUNT][LSU4X_nDACQueueSize]; +GPM6_ttVolts LSU4X_atNernstSenseVoltsDC[LSU_DEVICE_COUNT]; +//ASAM mode=readvalue name="Nernst Sense 1 Volts" type=uint32 offset=0 min=0 max=5 m=0.001 b=0 units="V" format=4.3 help="Nernst Sense Volts Left" +GPM6_ttVolts LSU4X_atNernstSenseVoltsACHigh[LSU_DEVICE_COUNT];/*CR1_42*/ +GPM6_ttVolts LSU4X_atNernstSenseVoltsACLow[LSU_DEVICE_COUNT];/*CR1_42*/ +sint32 LSU4X_ai32PumpCurrentADC[LSU_DEVICE_COUNT]; +sint32 LSU4X_ai32PumpCurrentADC[LSU_DEVICE_COUNT]; +sint32 LSU4X_ai32PumpCurrentADCFiltered[LSU_DEVICE_COUNT]; +GPM6_ttMicroAmps LSU4X_atPumpCurrentMicroAmps[LSU_DEVICE_COUNT];/*CR1_42*/ +//ASAM mode=readvalue name="Pump Current 1" type=sint32 offset=0 min=-20000 max=20000 m=0.001 b=0 units="uA" format=4.3 help="Pump 1 Current (uA)" +GPM6_ttMicroAmps LSU4X_atPumpCurrentMicroAmpsNorm[LSU_DEVICE_COUNT];/*CR1_42*/ +CTRLAPI_ttPIDIDX LSU4X_atPIDLSU4XIDX[LSU_DEVICE_COUNT]; +SPREADAPI_ttSpreadIDX LSU4X_atSpreadLSU4XIDX[LSU_DEVICE_COUNT]; +TABLEAPI_ttTableIDX LSU4X_atTableLSU4XIDX[LSU_DEVICE_COUNT]; +sint32 LSU4X_ai32PIDTarget[LSU_DEVICE_COUNT]; +sint32 LSU4X_ai32PIDFeedback[LSU_DEVICE_COUNT]; +sint32 LSU4X_ai32PIDOutput[LSU_DEVICE_COUNT]; +uint32 LSU4X_au32SensorReadyCount[LSU_DEVICE_COUNT]; +uint8 LSU4X_au8ACCallBackWait[LSU_DEVICE_COUNT]; +IOAPI_tenTriState LSU4X_enTriState; + + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ +/******************************************************************************* +* Interface : LSU4X_vADCCallBack +* +* Implementation : Callback to receive the measured ADC value +* +* Parameter +* Par1 : enEHIOResource enum of the ADC resource +* Par2 : u32ADCResult the ADC conversion value +* +* Return Value : NIL +*******************************************************************************/ +static void LSU4X_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult);/*CR1_40*/ + +/******************************************************************************* +* Interface : LSU4X_vEnablePumpControl +* +* Implementation : Function to determine if the pump control should be enabled +* +* Parameter +* Par1 : NIL +* +* Return Value : NIL +*******************************************************************************/ +static void LSU4X_vEnablePumpControl(void); + + +/* LOCAL CONSTANT DEFINITIONS (STATIC) ****************************************/ +const LSU4X_tstADConfig LSU4X_rastADConfig[] = LSU4X_nADConfig;/*CR1_41*/ + + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void LSU4X_vStart(puint32 const pu32Arg) +{ + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenEHIOType enEHIOType; + IOAPI_tenDriveStrength enDriveStrength = IOAPI_enWeak; + CTRLAPI_tenCTRLType enCTRLType; + ADCAPI_tstADCCB stADCCB; + DACAPI_tstDACCB stDACCB; + CTRLAPI_tstPIDCB stPIDCB; + SPREADAPI_tstSpreadCB stSpreadCB; + TABLEAPI_tstTableCB stTableCB; + uint32 u32ADConfigIDX; + bool boInitFailed = FALSE; + +#ifdef BUILD_SPARKDOG_PF + /* not yet tested */ + return; +#endif + + LSU4X_au32DCSampleCount[0] = 0; + + /* Request and initialise AD converter resources */ + for (u32ADConfigIDX = 0; u32ADConfigIDX < LSU4X_nADConfigCount; u32ADConfigIDX++) + { + enEHIOResource = LSU4X_rastADConfig[u32ADConfigIDX].enEHIOResource; + enEHIOType = LSU4X_rastADConfig[u32ADConfigIDX].enEHIOType; + stADCCB.enSamplesAv = LSU4X_rastADConfig[u32ADConfigIDX].enSamplesAv; + stADCCB.enDiffGain = LSU4X_rastADConfig[u32ADConfigIDX].enDiffGain; + stADCCB.pfResultCB = LSU4X_rastADConfig[u32ADConfigIDX].pfResultCB; + stADCCB.enTrigger = LSU4X_rastADConfig[u32ADConfigIDX].enTrigger; + + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stADCCB); + + if (SYSAPI_enOK != pstSVCDataStruct->enSVCResult) boInitFailed = TRUE; + } + else + { + boInitFailed = TRUE; + break; + } + } + + /* Request and initialise DACs */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + enEHIOType = IOAPI_enDAC; + enEHIOResource = LSU4X_nDACResource; + + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stDACCB.enQueueDepth = (DACAPI_tenQueueDepth)(LSU4X_nDACQueueSize - 1); + stDACCB.boWaterMarkEventEnable = FALSE; + stDACCB.boPointerTopEventEnable = FALSE; + stDACCB.boPointerBottomEventEnable = FALSE; + stDACCB.enTriggerType = DACAPI_enSoftwareTrigger; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stDACCB); + } + } + + /* Request and initialise the LSUX PID controllers */ + stPIDCB.enPIDRate = CTRLAPI_enPID1ms; + stPIDCB.pi32Target = &LSU4X_ai32PIDTarget[0]; + stPIDCB.pi32Feedback = &LSU4X_ai32PIDFeedback[0]; + stPIDCB.pi32Output = &LSU4X_ai32PIDOutput[0]; + stPIDCB.u8PTerm = 0xff; + stPIDCB.u8ITerm = 0xff; + stPIDCB.u8DTerm = 0x20; + stPIDCB.boNoWindUp = TRUE; + stPIDCB.boReset = FALSE; + stPIDCB.boResetIntegrator = FALSE; + stPIDCB.boRun = TRUE; + stPIDCB.i32OutputMin = -1 * (0x80 * LSU4X_nDACRange) + 100; + stPIDCB.i32OutputMax = 0x80 * LSU4X_nDACRange - 100; + enCTRLType = CTRLAPI_enPID; + + USER_vSVC(SYSAPI_enInitialiseCTRLResource, (void*)&enCTRLType, (void*)&stPIDCB, NULL); + LSU4X_atPIDLSU4XIDX[0] = (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) ? + (CTRLAPI_ttPIDIDX)pstSVCDataStruct->tClientHandle : -1; + + + /* Request and initialise required Kernel managed spreads */ + stSpreadCB.pvSourceData = (void*)&LSU4X_atPumpCurrentMicroAmpsNorm[0]; + stSpreadCB.pvSpreadData = (void*)&USERCAL_stRAMCAL.aUserCalPumpSpread[0]; + stSpreadCB.enDataType = TYPE_enInt32; + stSpreadCB.s16SpreadSize = 17; + stSpreadCB.enSpreadRate = SPREADAPI_enSpread1ms; + stSpreadCB.pfResultCB = NULL; + + USER_vSVC(SYSAPI_enInitialiseSpreadResource, (void*)&stSpreadCB, NULL, NULL); + LSU4X_atSpreadLSU4XIDX[0] = (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) ? + (SPREADAPI_ttSpreadIDX)pstSVCDataStruct->tClientHandle : -1; + + boInitFailed = ((-1 == LSU4X_atSpreadLSU4XIDX[0]) || (-1 == LSU4X_atSpreadLSU4XIDX[1])) ? + TRUE : boInitFailed; + + + /* Request and initialise required Kernel managed tables */ + stTableCB.pvTableData = (void*)&USERCAL_stRAMCAL.aUserCalPumpLambda[0]; + stTableCB.pvOutputData = (void*)&LSU4X_atLambdaRaw[0]; + stTableCB.enDataType = TYPE_enInt16; + stTableCB.i16TableSize = 17; + stTableCB.tSpreadIDX = LSU4X_atSpreadLSU4XIDX[0]; + stTableCB.pfResultCB = NULL; + + USER_vSVC(SYSAPI_enInitialiseTableResource, (void*)&stTableCB, NULL, NULL); + LSU4X_atTableLSU4XIDX[0] = (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) ? + (TABLEAPI_ttTableIDX)pstSVCDataStruct->tClientHandle : -1; + + boInitFailed = (-1 == LSU4X_atTableLSU4XIDX[0]) ? + TRUE : boInitFailed; + + + /* Request and initialise the LSU sensor 1 and 2 AC control lines */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + enEHIOResource = LSU4X_nSWHResource; + enEHIOType = IOAPI_enDIOOutput; + enDriveStrength = IOAPI_enStrong; + + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&enDriveStrength); + + if (SYSAPI_enOK != pstSVCDataStruct->enSVCResult) boInitFailed = TRUE; + } + else + { + boInitFailed = TRUE; + } + } + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + enEHIOResource = LSU4X_nSWLResource; + enEHIOType = IOAPI_enDIOOutput; + enDriveStrength = IOAPI_enStrong; + + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&enDriveStrength); + + if (SYSAPI_enOK != pstSVCDataStruct->enSVCResult) boInitFailed = TRUE; + } + else + { + boInitFailed = TRUE; + } + } + + LSU4X_au32SensorReadyCount[0] = 0; + LSU4X_ai32PIDTarget[0] = USERCAL_stRAMCAL.userCalVNernstTarget; +} + +void LSU4X_vRun(uint32* const pu32Arg ) +{ + static uint32 u32RunCounter = 0;/*CR1_44*/ + sint32 s32Temp; + sint32 s32TempDelta; + IOAPI_tenEHIOResource enEHIOResource; + +#ifdef BUILD_SPARKDOG_PF + /* not yet tested */ + return; +#endif + + ADCAPI_tenTrigger enTrigger = ADCAPI_enTrigger1; + + LSU4X_atDACVoltageQueue[0][0] = (LSU4X_nDACRange / 2) + (LSU4X_ai32PIDOutput[0] / 0x100); + + + if (0 == (u32RunCounter++ % 0x2)) + { + USER_vSVC(SYSAPI_enTriggerADQueue, (void*)&enTrigger, NULL, NULL); + } + + if (0 == (u32RunCounter % LSU4X_nPWMCycCount)) + { + LSUH_vTurnHeaterOn(); + } + else if ((LSUH_au32HeaterDuty[0] / 25) <= (u32RunCounter % LSU4X_nPWMCycCount)) + { + if (true == LSUH_aboHeaterIsOn[0]) + { + LSUH_vTurnHeaterOff(); + } + } + + + if (0 == (u32RunCounter % 0x2)) + { + /* Set the AC control lines */ + enEHIOResource = LSU4X_nSWHResource; + LSU4X_enTriState = (0 == (u32RunCounter & 0x2)) ? IOAPI_enLow : IOAPI_enHigh; + + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, + (void*)&LSU4X_enTriState, (void*)NULL); + + enEHIOResource = LSU4X_nSWLResource; + LSU4X_enTriState = (0 == (u32RunCounter & 0x2)) ? IOAPI_enHigh : IOAPI_enLow; + + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, + (void*)&LSU4X_enTriState, (void*)NULL); + } + + if (LSU4X_enTriState == IOAPI_enHigh) + { + enEHIOResource = LSU4X_nDACResource; + LSU4X_atDACVoltageQueue[0][0] = (LSU4X_nDACRange / 2) + (LSU4X_ai32PIDOutput[0] / 0x100) - 65; + USER_vSVC(SYSAPI_enWriteDACQueue, (void*)&enEHIOResource, (void*)&LSU4X_atDACVoltageQueue[0][0], NULL); + } + else + { + enEHIOResource = LSU4X_nDACResource; + LSU4X_atDACVoltageQueue[0][0] = (LSU4X_nDACRange / 2) + (LSU4X_ai32PIDOutput[0] / 0x100) + 65; + USER_vSVC(SYSAPI_enWriteDACQueue, (void*)&enEHIOResource, (void*)&LSU4X_atDACVoltageQueue[0][0], NULL); + } + + + LSU4X_vEnablePumpControl(); + + /* Buffer the nernst cell PID controller feedback */ + LSU4X_ai32PIDFeedback[0] = LSU4X_atNernstSenseVoltsDC[0]; + + /* Calculate the pump currents */ + s32Temp = LSU4X_ai32PumpCurrentADCFiltered[0]; + + /* Add offset correction */ + if (USERCAL_stRAMCAL.ai32UserCalPumpCurrentOffset[0] <= s32Temp) + { + s32Temp -= USERCAL_stRAMCAL.ai32UserCalPumpCurrentOffset[0]; + + if ((sint32)USERCAL_stRAMCAL.au8UserCalPumpDeadband[0] < s32Temp) + { + s32Temp -= (uint32)USERCAL_stRAMCAL.au8UserCalPumpDeadband[0]; + } + else + { + s32Temp = 0; + } + } + else + { + s32Temp -= USERCAL_stRAMCAL.ai32UserCalPumpCurrentOffset[0]; + s32TempDelta = ~s32Temp; + s32TempDelta += 1; + + if ((sint32)USERCAL_stRAMCAL.au8UserCalPumpDeadband[0] < s32TempDelta) + { + s32Temp += (uint32)USERCAL_stRAMCAL.au8UserCalPumpDeadband[0]; + } + else + { + s32Temp = 0; + } + } + + /* Multiply for factor correction */ + if (0 <= s32Temp) + { + LSU4X_atPumpCurrentMicroAmps[0] = + s32Temp * (sint32)USERCAL_stRAMCAL.au32UserCalPumpCurrentPFactor[0]; + } + else + { + LSU4X_atPumpCurrentMicroAmps[0] = + s32Temp * (sint32)USERCAL_stRAMCAL.au32UserCalPumpCurrentMFactor[0]; + } + + /* Calculate normalised (sensor specific calibration) pump current */ + LSU4X_atPumpCurrentMicroAmpsNorm[0] = + (LSU4X_atPumpCurrentMicroAmps[0] * + USERCAL_stRAMCAL.au8UserCalPumpSensorTrim[0]) / 128; + + + /* Calculate the current spread */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&LSU4X_atSpreadLSU4XIDX[0], + NULL, NULL); + + /* Lookup the current Lambda */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&LSU4X_atTableLSU4XIDX[0], + NULL, NULL); +} + +void LSU4X_vTerminate(uint32* const pu32Arg ) +{ + +} + +void LSU4X_vCallBack(uint32* const pu32Arg ) +{ + +} + +void LSU4X_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult) +{ + static uint32 u32TempLow[LSU_DEVICE_COUNT]; + static uint32 u32TempHigh[LSU_DEVICE_COUNT]; + static uint32 u32DCDL; + uint32 u32TempDelta; + + + switch (enEHIOResource) + { + case EH_IO_IIC1_SCL: + { + LSU4X_atNernstSenseVoltsDC[0] = CONV_tADCToVolts(EH_IO_IIC1_SCL, u32ADCResult); + break; + } + case EH_I_ADD1: + { + LSU4X_au8ACCallBackWait[0]++; + + if (4 > LSU4X_au8ACCallBackWait[0]) + { + LSU4X_au32ACSampleCount[0] = 0; + } + else + { + if (0xfff < u32ADCResult) + { + u32ADCResult = 0x80000000 - ((0xffff - u32ADCResult) << 8); + } + else + { + u32ADCResult = 0x80000000 + (u32ADCResult << 8); + } + + if (IOAPI_enHigh == LSU4X_enTriState) + { + u32TempLow[0] = u32ADCResult; + } + else + { + u32TempHigh[0] = u32ADCResult; + } + + if (u32TempHigh[0] >= u32TempLow[0]) + { + u32TempDelta = u32TempHigh[0] - u32TempLow[0]; + } + else + { + u32TempDelta = 0; + } + + if (LSU4X_nACSamplesCount > LSU4X_au32ACSampleCount[0]) + { + LSU4X_aau32ACSamples[0][LSU4X_au32ACSampleCount[0]++] = u32TempDelta; + } + } + break; + } + case EH_IO_TMR18: + { + u32DCDL = u32ADCResult; + break; + } + case EH_IO_TMR17: + { + u32ADCResult = u32ADCResult - u32DCDL; + LSU4X_ai32PumpCurrentADC[0] = (sint32)u32ADCResult; + LSU4X_aas32DCSamples[0][LSU4X_au32DCSampleCount[0]++] = LSU4X_ai32PumpCurrentADC[0]; + + if (LSU4X_nPumpCurrSamples <= LSU4X_au32DCSampleCount[0])/*CR1_45*/ + { + LSU4X_ai32PumpCurrentADCFiltered[0] = + USERMATH_s32DiscardAndAverage32(&LSU4X_aas32DCSamples[0][0], LSU4X_au32DCSampleCount[0], 3u); + LSU4X_au32DCSampleCount[0] = 0; + } + break; + } + default: + { + break; + } + } +} + +void LSU4X_vEnablePumpControl(void) +{ + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenTriState enTriState; + uint32 u32DeviceIDX; + uint32 u32WarmUpDelayPumpMs; + uint32 u32WarmUpDelayMs = 1000u * (uint32)USERCAL_stRAMCAL.u8WarmUpDelay; + + u32WarmUpDelayMs = u32WarmUpDelayMs > LSU4X_nWarmMsMin ? u32WarmUpDelayMs : LSU4X_nWarmMsMin; + u32WarmUpDelayMs = u32WarmUpDelayMs < LSU4X_nWarmMsMax ? u32WarmUpDelayMs : LSU4X_nWarmMsMax; + + u32WarmUpDelayPumpMs = u32WarmUpDelayMs - LSU4X_nWarmPrePumpMs; + + for (u32DeviceIDX = 0; u32DeviceIDX < LSU_DEVICE_COUNT; u32DeviceIDX++) + { + enEHIOResource = (0 == u32DeviceIDX) ? LSU4X_nIENResource : LSU4X_nIENResource; + + if ((USERCAL_stRAMCAL.userCalRNernstReady > LSU4X_atNernstSenseOhms[u32DeviceIDX]) || + (USERCAL_stRAMCAL.userCalRHeaterThreshold < LSUH_atHeaterOhms[u32DeviceIDX])) + { + LSU4X_au32SensorReadyCount[u32DeviceIDX] = (u32WarmUpDelayMs > LSU4X_au32SensorReadyCount[u32DeviceIDX]) ? + LSU4X_au32SensorReadyCount[u32DeviceIDX] + 1 : LSU4X_au32SensorReadyCount[u32DeviceIDX]; + } + + /* Condition sensor ready flags for display and closed loop heater control */ + LSUH_aboSensorReady[u32DeviceIDX] = (u32WarmUpDelayMs <= LSU4X_au32SensorReadyCount[u32DeviceIDX]); + + /* Switch on the pump current before the sensor ready to obtain nernst impedence */ + enTriState = (u32WarmUpDelayPumpMs <= LSU4X_au32SensorReadyCount[u32DeviceIDX]) ? IOAPI_enLow : IOAPI_enHigh; + + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, + (void*)&enTriState, (void*)NULL); + } +} + +void LSU4X_vThread(void) +{ + while(1); +} + +#endif //BUILD_USER + + + diff --git a/source/Client/LSU4X.h b/source/Client/LSU4X.h new file mode 100644 index 0000000..f08bba6 --- /dev/null +++ b/source/Client/LSU4X.h @@ -0,0 +1,122 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. */ +/* All rights reserved. */ +/******************************************************************************/ +/* */ +/* PACKAGE TITLE: LSU4.X Header File */ +/* DESCRIPTION: This code module initialises the required ADC, DAC */ +/* CTRL, spread, table, DIO and TEPM resources for */ +/* managing the nernst cell voltage and impedence */ +/* measurement for the LSU4.X sensor/s */ +/* FILE NAME: LSU4X.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef LSU4X_H +#define LSU4X_H + +#include "ADCAPI.h" +#include "DACAPI.h" +#include "CTRLAPI.h" +#include "CONV.h" +#include "declarations.h" +#include "IOAPI.h" +#include "LSUH.h" +#include "SPREADSAPI.h" +#include "TABLESAPI.h" +#include "TEPMAPI.h" +#include "UNITS.h" +#include "USER.h" +#include "USERMATH.h" + + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define LSU4X_nDACQueueSize 1u +#define LSU4X_nDACRange 3200u +#define LSU4X_nADCRange 4095u +#define LSU4X_nPWMCycCount 40u +#define LSU4X_nStartACSample 5u +#define LSU4X_nEndACSample 18u +#define LSU4X_nPumpCurrSamples 10u +#define LSU4X_nACSamplesCount 20u +#define LSU4X_nDCSamplesCount 20u +#define LSU4X_nWarmMsMin 4000u +#define LSU4X_nWarmMsMax 10000u +#define LSU4X_nWarmPrePumpMs 2000u +/*CR1_105*/ + +#define LSU4X_nSWHResource EH_IO_GP6 +#define LSU4X_nSWLResource EH_IO_GP7 +#define LSU4X_nIENResource EH_IO_GPSE8 +#define LSU4X_nDACResource EH_O_DAC1 + +#define LSU4X_nADConfig \ +{ \ + {EH_I_ADD1, IOAPI_enADD, ADCAPI_en8Samples, ADCAPI_enDiffGain32, &LSU4X_vADCCallBack, ADCAPI_enTrigger1}, \ + {EH_IO_TMR18, IOAPI_enADSE, ADCAPI_en4Samples, ADCAPI_enDiffGain8, &LSU4X_vADCCallBack, ADCAPI_enTrigger1}, \ + {EH_IO_TMR17, IOAPI_enADSE, ADCAPI_en4Samples, ADCAPI_enDiffGain8, &LSU4X_vADCCallBack, ADCAPI_enTrigger1}, \ + {EH_IO_IIC1_SCL, IOAPI_enADSE, ADCAPI_en4Samples, ADCAPI_enDiffGain1, &LSU4X_vADCCallBack, ADCAPI_enTrigger1}, \ +} + + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _LSU4X_C + #define EXTERN +#else + #define EXTERN extern +#endif + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +/******************************************************************************* +* Description : Type to hold an AD resource configuration +*******************************************************************************/ +typedef struct +{ + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenEHIOType enEHIOType; + ADCAPI_tenSamplesAv enSamplesAv; + ADCAPI_tenDiffGain enDiffGain; + ADCAPI_tpfResultCB pfResultCB; + ADCAPI_tenTrigger enTrigger; +} LSU4X_tstADConfig; + + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +EXTERN uint32 LSU4X_au32ACSampleCount[LSU_DEVICE_COUNT]; +EXTERN uint32 LSU4X_au32DCSampleCount[LSU_DEVICE_COUNT]; +EXTERN uint16 LSU4X_u16PWMPeriod; +//ASAM mode=readvalue name="PWMPeriod" type=uint8 offset=0 min=0 max=5 m=0.001 b=1 units="dl" format=6.0 help="PWM Period" +EXTERN uint16 LSU4X_u16PWMLastStart; +//ASAM mode=readvalue name="PWMLastStart" type=uint8 offset=0 min=0 max=5 m=0.001 b=1 units="dl" format=6.0 help="PWM Period Last Origin" +EXTERN GPM6_ttOhms LSU4X_atNernstSenseOhms[LSU_DEVICE_COUNT]; +//ASAM mode=readvalue name="Nernst Rout 1" type=uint32 offset=0 min=0 max=1000 m=0.001 b=0 units="Ohm" format=3.0 help="Nernst 1 output impedence" +//ASAM mode=readvalue name="Nernst Rout 2" type=uint32 offset=4 min=0 max=1000 m=0.001 b=0 units="Ohm" format=3.0 help="Nernst 2 output impedence" +EXTERN GPM6_ttLambda LSU4X_atLambdaRaw[LSU_DEVICE_COUNT]; +//ASAM mode=readvalue name="Lambda 1" type=uint16 offset=0 min=0 max=5 m=0.001 b=0 units="dl" format=4.3 help="Lambda 1 Measurement (dimensionless)" +//ASAM mode=readvalue name="AFR 1" type=uint16 offset=0 min=0 max=50 m=0.0147 b=0 units="ARF" format=2.3 help="AFR 1 Measurement (dimensionless)" +//ASAM mode=readvalue name="Lambda 2" type=uint16 offset=2 min=0 max=5 m=0.001 b=0 units="dl" format=4.3 help="Lambda 2 Measurement (dimensionless)" +EXTERN uint32 LSU4X_aau32ACSamples[LSU_DEVICE_COUNT][LSU4X_nACSamplesCount]; +//ASAM mode=readvalue name="Samples1" type=uint32 offset=0 min=0 max=5 m=1 b=0 units="n" format=6.0 help="sample 1" +//ASAM mode=readvalue name="Samples2" type=uint32 offset=4 min=0 max=5 m=1 b=0 units="n" format=6.0 help="sample 2" +//ASAM mode=readvalue name="Samples3" type=uint32 offset=8 min=0 max=5 m=1 b=0 units="n" format=6.0 help="sample 3" +//ASAM mode=readvalue name="Samples4" type=uint32 offset=12 min=0 max=5 m=1 b=0 units="n" format=6.0 help="sample 4" +//ASAM mode=readvalue name="Samples5" type=uint32 offset=16 min=0 max=5 m=1 b=0 units="n" format=6.0 help="sample 5" +//ASAM mode=readvalue name="Samples6" type=uint32 offset=20 min=0 max=5 m=1 b=0 units="n" format=6.0 help="sample 6" +//ASAM mode=readvalue name="Samples7" type=uint32 offset=24 min=0 max=5 m=1 b=0 units="n" format=6.0 help="sample 7" +//ASAM mode=readvalue name="Samples8" type=uint32 offset=28 min=0 max=5 m=1 b=0 units="n" format=6.0 help="sample 8" +EXTERN sint32 LSU4X_aas32DCSamples[LSU_DEVICE_COUNT][LSU4X_nDCSamplesCount]; +EXTERN uint8 LSU4X_au8ACCallBackWait[LSU_DEVICE_COUNT]; + + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void LSU4X_vStart(uint32 * const pu32Arg); +void LSU4X_vRun(uint32* const pu32Arg); +void LSU4X_vTerminate(uint32* const pu32Arg); +void LSU4X_vCallBack(uint32* const pu32Arg); +void LSU4X_vThread(void); + +#endif // LSU4X_H + diff --git a/source/Client/LSUH.c b/source/Client/LSUH.c new file mode 100644 index 0000000..39ba41b --- /dev/null +++ b/source/Client/LSUH.c @@ -0,0 +1,651 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. */ +/* All rights reserved. */ +/******************************************************************************/ +/* */ +/* PACKAGE TITLE: LSUH */ +/* DESCRIPTION: This code module initialises the required ADC, DAC */ +/* CTRL, spread, table, DIO and TEPM resources for */ +/* managing the heater control for the LSU4.X sensor/s */ +/* */ +/* FILE NAME: LSUH.c */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _LSUH_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "LSUH.h" +#include "USERMATH.h" + +/* LOCAL MACRO DEFINITIONS ****************************************************/ +#define LSUH_nADConfigCount (sizeof(LSUH_rastADConfig) / sizeof(LSUH_tstADConfig)) + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +#ifdef LSUH_TEPM +TEPMAPI_tstTimedEvent LSUH_aastTimedEvents[LSU_DEVICE_COUNT][TEPMAPI_nEventsMax]; +#endif //LSUH_TEPM +uint32 LSUH_au32TEPMTimeout[LSU_DEVICE_COUNT]; +//ASAM mode=readvalue name="Heater Duty 1" type=uint32 offset=0 min=0 max=100 m=0.001 b=0 units="%" format=6.3 help="Heater Left Duty Cycle" +uint32 LSUH_u32HeaterDutyMax; +uint32 LSUH_au32HeaterLowADCOnRaw[LSU_DEVICE_COUNT]; +uint32 LSUH_au32HeaterLowADCOffRaw[LSU_DEVICE_COUNT]; +uint32 LSUH_au32HeaterLowADCDeltaFiltered[LSU_DEVICE_COUNT]; +GPM6_ttVolts LSUH_atHeaterSenseVolts[LSU_DEVICE_COUNT];/*CR1_54*/ +GPM6_ttAmps LSUH_atHeaterAmps[LSU_DEVICE_COUNT];/*CR1_54*/ +GPM6_ttMilliVolts LSUH_tHeaterEffMax;/*CR1_54*/ +GPM6_ttMilliWatts LSUH_atHeaterPower[LSU_DEVICE_COUNT]; +bool LSUH_aboADCQueuePending[LSU_DEVICE_COUNT]; +CTRLAPI_ttPIDIDX LSUH_atPIDLSUH1IDX[LSU_DEVICE_COUNT]; +sint32 LSUH_ai32PIDTarget[LSU_DEVICE_COUNT]; +sint32 LSUH_ai32PIDFeedback[LSU_DEVICE_COUNT]; +sint32 LSUH_ai32PIDOutput[LSU_DEVICE_COUNT]; +uint32 LSUH_au32ACSampleCounter[LSU_DEVICE_COUNT]; +bool LSUH_aboNernstRNewValue[LSU_DEVICE_COUNT]; +uint32 LSUH_au32NoNewNernstValueCount[LSU_DEVICE_COUNT]; +bool LSUH_aboNernstTempMode[LSU_DEVICE_COUNT]; + + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ +/******************************************************************************* +* Interface : LSUH_vADCCallBack +* +* Implementation : Callback to receive the measured ADC value +* +* Parameter +* Par1 : enEHIOResource enum of the ADC resource +* Par2 : u32ADCResult the ADC conversion value +* +* Return Value : NIL +*******************************************************************************/ +static void LSUH_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult);/*CR1_53*/ + +/******************************************************************************* +* Interface : LSUH_vInitiateTEPMQueue +* +* Implementation : Function to initiate a new TEPM queue timed output +* +* Parameter +* Par1 : enEHIOResource enum of the timer resource +* Par2 : tEventTime the timer value at the last timer event of interest +* +* Return Value : NIL +*******************************************************************************/ +#ifdef LSUH_TEPM +static void LSUH_vInitiateTEPMQueue(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime); +#endif //LSUH_TEPM + +/* LOCAL CONSTANT DEFINITIONS (STATIC) ****************************************/ +const LSUH_tstADConfig LSUH_rastADConfig[] = LSUH_nADConfig; + + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void LSUH_vStart(uint32 * const pu32Arg) +{ + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenEHIOType enEHIOType; + ADCAPI_tstADCCB stADCCB; + CTRLAPI_tstPIDCB stPIDCB; + CTRLAPI_tenCTRLType enCTRLType; + + IOAPI_tenDriveStrength enDriveStrength = IOAPI_enWeak; + uint32 u32ADConfigIDX; + bool boInitFailed = FALSE; + +#ifdef BUILD_SPARKDOG_PF + /* not yet tested */ + return; +#endif + + LSUH_tHeaterEffMax = LSUH_nHeaterEffInit; + LSUH_au32ACSampleCounter[0] = 0; + +#ifdef LSUH_TEPM + TEPMAPI_tstTEPMResourceCB stTEPMResourceCB; + TEPMAPI_tstTEPMChannelCB stTEPMChannelCB; + + /* Request and initialise FTM for EH_IO_TMR15 and EH_IO_TMR16 */ + enEHIOResource = EH_VIO_FTM0; + enEHIOType = IOAPI_enTEPM; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMResourceCB.enEHIOResource = EH_VIO_FTM0; + stTEPMResourceCB.enPreScalar = TEPMAPI_enDiv32; + stTEPMResourceCB.enCountType = TEPMAPI_enCountUp; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMResourceCB); + } + + /* Request and initialise EH_IO_TMR15 */ + enEHIOResource = EH_IO_TMR15; + enEHIOType = IOAPI_enCaptureCompare; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + /* Initialise the TEPM channel EH_IO_TMR15 */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMChannelCB.enAction = TEPMAPI_enToggle; + stTEPMChannelCB.boInterruptEnable = TRUE; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMChannelCB); + } + + /* Request and initialise EH_IO_TMR16 */ + enEHIOResource = EH_IO_TMR16; + enEHIOType = IOAPI_enCaptureCompare; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + /* Initialise the TEPM channel EH_IO_TMR16 */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMChannelCB.enAction = TEPMAPI_enToggle; + stTEPMChannelCB.boInterruptEnable = TRUE; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMChannelCB); + } +#endif //LSUH_TEPM + + /* Request and initialise AD converter resources */ + for (u32ADConfigIDX = 0; u32ADConfigIDX < LSUH_nADConfigCount; u32ADConfigIDX++) + { + enEHIOResource = LSUH_rastADConfig[u32ADConfigIDX].enEHIOResource; + enEHIOType = LSUH_rastADConfig[u32ADConfigIDX].enEHIOType; + stADCCB.enSamplesAv = LSUH_rastADConfig[u32ADConfigIDX].enSamplesAv; + stADCCB.pfResultCB = LSUH_rastADConfig[u32ADConfigIDX].pfResultCB; + stADCCB.enTrigger = LSUH_rastADConfig[u32ADConfigIDX].enTrigger; + + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stADCCB); + + if (SYSAPI_enOK != pstSVCDataStruct->enSVCResult) boInitFailed = TRUE; + } + else + { + boInitFailed = TRUE; + break; + } + } + + /* Initialise HMEN enable control lines */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + enEHIOResource = LSUH_nHMENResource; + enEHIOType = IOAPI_enDIOOutput; + enDriveStrength = IOAPI_enStrong; + + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&enDriveStrength); + + if (SYSAPI_enOK != pstSVCDataStruct->enSVCResult) boInitFailed = TRUE; + } + else + { + boInitFailed = TRUE; + } + } + + /* Request and initialise the LSUH1 PID controller */ + stPIDCB.enPIDRate = CTRLAPI_enPIDCall; + stPIDCB.pi32Target = &LSUH_ai32PIDTarget[0]; + stPIDCB.pi32Feedback = &LSUH_ai32PIDFeedback[0]; + stPIDCB.pi32Output = &LSUH_ai32PIDOutput[0]; + stPIDCB.u8PTerm = 0xFF; + stPIDCB.u8ITerm = 0x03; + stPIDCB.u8DTerm = 0x08; + stPIDCB.boNoWindUp = TRUE; + stPIDCB.boReset = FALSE; + stPIDCB.boResetIntegrator = FALSE; + stPIDCB.boRun = TRUE; + stPIDCB.i32OutputMin = -2500000; + stPIDCB.i32OutputMax = 2500000; + enCTRLType = CTRLAPI_enPID; + + USER_vSVC(SYSAPI_enInitialiseCTRLResource, (void*)&enCTRLType, (void*)&stPIDCB, NULL); + + LSUH_atPIDLSUH1IDX[0] = (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) ? + (CTRLAPI_ttPIDIDX)pstSVCDataStruct->tClientHandle : -1; + + *pu32Arg = ((SYSAPI_enOK == pstSVCDataStruct->enSVCResult) && !boInitFailed) ? + *pu32Arg | SYSAPI_CALL_MASK_FAIL_RES_INIT : + *pu32Arg & ~SYSAPI_CALL_MASK_FAIL_RES_INIT; + + + /* Initialise variables */ + LSUH_au32TEPMTimeout[0] = ~0; + LSUH_au32HeaterDuty[0] = 80 * LSU_DUTY_RES; + LSUH_ai32PIDTarget[0] = 300000u; + LSUH_au32ACADCDeltaFiltered[0] = 0; + LSUH_au32HeaterLowADCDeltaFiltered[0] = 0; + LSUH_aboSensorReady[0] = FALSE; + LSU4X_atNernstSenseOhms[0] = 1000000u; +} + +void LSUH_vRun(uint32* const pu32Arg ) +{ + uint32 u32Temp; + uint32 u32MaxDuty; + CTRLAPI_tenCTRLType enCTRLType; + ADCAPI_tenTrigger enTrigger = ADCAPI_enTrigger3; + static uint32 u32RunCount = 0;/*CR1_56*/; + static uint32 u32TempControllerRunCount; + +#ifdef BUILD_SPARKDOG_PF + /* not yet tested */ + return; +#endif + + if (0 == (u32RunCount++ % (uint32)LSUH_nCallsIn100Ms))/*CR1_57*/ + { + LSUH_tHeaterEffMax = (LSUH_nHeffVLimit > LSUH_tHeaterEffMax) ? + LSUH_tHeaterEffMax + (LSUH_nHeffVRampRate / LSUH_nRateHZ) : LSUH_tHeaterEffMax; /*CR1_57*/ + } + + +#ifdef LSUH_TEPM + enEHIOResourceTimer = (0 == u32LSUDeviceIDX ) ? EH_IO_TMR15 : EH_IO_TMR16; + enEHIOResourceADC = (0 == u32LSUDeviceIDX ) ? EH_IO_ADSE8 : EH_IO_ADSE9; + + /* Catch a lost TEPM for heater */ + if (10000 < LSUH_au32TEPMTimeout[u32LSUDeviceIDX]++) + { + LSUH_vInitiateTEPMQueue(enEHIOResourceTimer, 0u); + } +#endif //LSUH_TEPM + + /* ADC pending flags are expected to be syncronised... */ + if (TRUE == LSUH_aboADCQueuePending[0]) + { + USER_vSVC(SYSAPI_enTriggerADQueue, (void*)&enTrigger, NULL, NULL); + LSUH_aboADCQueuePending[0] = FALSE; + } + + /* Iterate the heater PID controller if new R value */ + if (TRUE == LSUH_aboNernstRNewValue[0]) + { + enCTRLType = CTRLAPI_enPID; + + USER_vSVC(SYSAPI_enIterateCTRLResource, (void*)&enCTRLType, (void*)&LSUH_atPIDLSUH1IDX[0], NULL); + LSUH_aboNernstRNewValue[0] = FALSE; + + LSUH_au32NoNewNernstValueCount[0] = + 200 < LSUH_au32NoNewNernstValueCount[0] ? + LSUH_au32NoNewNernstValueCount[0] - 200 : 0; + + LSUH_aboNernstTempMode[0] = 0 == LSUH_au32NoNewNernstValueCount[0] ? TRUE : + LSUH_aboNernstTempMode[0]; + + u32TempControllerRunCount = 0; + } + else + { + LSUH_au32NoNewNernstValueCount[0] = + 1000 > LSUH_au32NoNewNernstValueCount[0] ? + LSUH_au32NoNewNernstValueCount[0] + 1 : LSUH_au32NoNewNernstValueCount[0]; + + LSUH_aboNernstTempMode[0] = 999 < LSUH_au32NoNewNernstValueCount[0] ? FALSE : + LSUH_aboNernstTempMode[0]; + } + + /* Run the alternate heater resistance based controller if required */ + if ((FALSE == LSUH_aboNernstTempMode[0]) && (0 == (++u32TempControllerRunCount % 40))) + { + u32Temp = LSUH_atHeaterOhms[0]; + u32Temp = 14400 > u32Temp ? u32Temp : 14400; + LSU4X_atNernstSenseOhms[0] = (14400 - u32Temp) * 42; + + enCTRLType = CTRLAPI_enPID; + USER_vSVC(SYSAPI_enIterateCTRLResource, (void*)&enCTRLType, (void*)&LSUH_atPIDLSUH1IDX[0], NULL); + } + + + + LSUH_atHeaterSenseVolts[0] = CONV_tADCToVolts( + EH_IO_UART1_CTS, LSUH_au32HeaterLowADCDeltaFiltered[0]); + + LSUH_atHeaterAmps[0] = CONV_tOhmsVoltsToAmps(LSUH_nHeaterSenseOhms, LSUH_atHeaterSenseVolts[0]); + LSUH_atHeaterOhms[0] = CONV_tVoltsAmpsToOhms(BVM_tBattVolts - LSUH_atHeaterSenseVolts[0] - 800u, + LSUH_atHeaterAmps[0]); + + LSUH_ai32PIDFeedback[0] = LSU4X_atNernstSenseOhms[0]; + LSUH_atHeaterPower[0] = (10000000 - (3 * LSUH_ai32PIDOutput[0])) / 1000; + + /* Calculate the maximum duty cycle sustained by the current sense resistors */ + u32MaxDuty = (1000000u * (uint32)LSUH_nMaxDutyDenom) / LSUH_atHeaterAmps[0]; + u32MaxDuty /= LSUH_atHeaterAmps[0]; + + /* Calculated the duty cycle to deliver requested power (n = Preq / VI))*/ + u32Temp = LSUH_atHeaterPower[0] * 1000u; + u32Temp /= (BVM_tBattVolts - LSUH_atHeaterSenseVolts[0] - 800u); + u32Temp *= 1000; + u32Temp /= LSUH_atHeaterAmps[0]; + u32Temp = (u32MaxDuty > u32Temp) ? u32Temp : u32MaxDuty; + u32Temp = (LSUH_nMaxDuty > u32Temp) ? u32Temp : LSUH_nMaxDuty; + u32Temp = (LSUH_nMinDuty < u32Temp) ? u32Temp : LSUH_nMinDuty; + LSUH_au32HeaterDuty[0] = u32Temp; + + /* Max duty cycle until sensor ready */ + LSUH_au32HeaterDuty[0] = (FALSE == LSUH_aboSensorReady[0]) ? LSUH_nMaxDuty : LSUH_au32HeaterDuty[0]; + + /* Limit to max heater power during startup */ + u32Temp = LSUH_tHeaterEffMax * LSUH_tHeaterEffMax; + u32Temp /= (BVM_tBattVolts - LSUH_atHeaterSenseVolts[0] - 800u); + u32Temp *= 1000u; + u32Temp /= (BVM_tBattVolts - LSUH_atHeaterSenseVolts[0] - 800u); + + LSUH_u32HeaterDutyMax = u32Temp; + LSUH_au32HeaterDuty[0] = MIN(LSUH_au32HeaterDuty[0], LSUH_u32HeaterDutyMax); +} + +void LSUH_vTerminate(uint32* const pu32Arg ) +{ + +} + +void LSUH_vCallBack(uint32* const pu32Arg ) +{ + +} + +static void LSUH_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult) +{ + uint16 u16ADCDelta; + uint32 u32Temp;/*CR1_65*/ + + if (TRUE == LSUH_aboHeaterIsOn[0]) + { + LSUH_au32HeaterLowADCOnRaw[0] = u32ADCResult; + u32Temp = (LSUH_au32HeaterLowADCOnRaw[0] > LSUH_au32HeaterLowADCOffRaw[0]) ? + LSUH_au32HeaterLowADCOnRaw[0] - LSUH_au32HeaterLowADCOffRaw[0] : 0; + + u32Temp = MIN(u32Temp, 0xffff);/*CR1_65*/ + u16ADCDelta = (uint16)u32Temp;/*CR1_65*/ + + (void)USERMATH_u16SinglePoleLowPassFilter16(u16ADCDelta, LSUH_nHeatCurrFilt, + &LSUH_au32HeaterLowADCDeltaFiltered[0]); + } + else + { + LSUH_au32HeaterLowADCOffRaw[0] = 4; + } +} + +void LSUH_vTurnHeaterOff(void) +{ + uint32 u32SampleCount; + uint32 u32SampleDiscard; + puint32 pu32SampleArray; + uint32 u32SampleIDX; + bool boSamplesOK = TRUE; + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenTriState enTriState; + + enEHIOResource = LSUH_nHMENResource; + enTriState = IOAPI_enLow; + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, (void*)&enTriState, (void*)NULL); + + pu32SampleArray = (puint32)(&LSU4X_aau32ACSamples[0][0]); + + /* Limit the amount of samples - use the last 8 samples */ + if (8 < LSU4X_au32ACSampleCount[0]) + { + pu32SampleArray += (LSU4X_au32ACSampleCount[0] - 8); + LSU4X_au32ACSampleCount[0] = 8; + } + + u32SampleCount = LSU4X_au32ACSampleCount[0]; + u32SampleCount = MAX(u32SampleCount, 2u); + u32SampleDiscard = (u32SampleCount - 1) >> 1; + + LSUH_aboADCQueuePending[0] = TRUE; + LSUH_aboHeaterIsOn[0] = FALSE; + LSU4X_au8ACCallBackWait[0] = 0; + LSUH_au32ACADCDelta[0] = USERMATH_u32DiscardAndAverage32(pu32SampleArray, u32SampleCount, u32SampleDiscard); + + if ((LSUH_nHeaterOhmsSamples - 1) > LSUH_au32ACSampleCounter[0]) + { + LSUH_aau32ADADCSamples[0][LSUH_au32ACSampleCounter[0]] = LSUH_au32ACADCDelta[0]; + LSUH_au32ACSampleCounter[0]++; + } + else + { + u32SampleCount = LSUH_nHeaterOhmsSamples; + u32SampleDiscard = u32SampleCount >> 1; + LSUH_aau32ADADCSamples[0][LSUH_au32ACSampleCounter[0]] = LSUH_au32ACADCDelta[0]; + LSUH_au32ACADCDeltaFiltered[0] = USERMATH_u32DiscardAndAverage32(&LSUH_aau32ADADCSamples[0][0], u32SampleCount, u32SampleDiscard); + + for (u32SampleIDX = 0; u32SampleIDX < LSUH_nHeaterOhmsSamples; u32SampleIDX++) + { + if ((LSUH_nMinACSample > LSUH_aau32ADADCSamples[0][u32SampleIDX]) || + (LSUH_nMaxACSample < LSUH_aau32ADADCSamples[0][u32SampleIDX])) + { + boSamplesOK = FALSE; + } + } + + if (TRUE == boSamplesOK) + { + LSU4X_atNernstSenseOhms[0] = CONV_tADCToOhms(EH_I_ADD1, LSUH_au32ACADCDeltaFiltered[0]); + LSUH_aboNernstRNewValue[0] = true; + } + + LSUH_au32ACSampleCounter[0] = 0; + } +} + +void LSUH_vTurnHeaterOn(void) +{ + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenTriState enTriState; + + enEHIOResource = LSUH_nHMENResource; + enTriState = IOAPI_enHigh; + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, (void*)&enTriState, (void*)NULL); + + LSUH_aboADCQueuePending[0] = TRUE; + LSUH_aboHeaterIsOn[0] = TRUE; +} + +#ifdef LSUH_TEPM + IOAPI_tenEHIOType; + enEHIOType = IOAPI_enDIOOutput; + +void LSUH_vTEPMCallBackLow(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime) +{ + uint32 u32SampleCount; + uint32 u32SampleDiscard; + puint32 pu32SampleArray; + uint32 u32LSUDeviceIDX; + uint32 u32SampleIDX; + bool boSamplesOK = TRUE; + IOAPI_tenEHIOResource enEHIOResourceAD; + + switch (enEHIOResource) + { + case EH_IO_TMR15: + { + u32LSUDeviceIDX = 0; + enEHIOResourceAD = EH_I_ADD5; + break; + } + case EH_IO_TMR16: + { + u32LSUDeviceIDX = 1; + enEHIOResourceAD = EH_I_ADD7; + break; + } + default: + { + u32LSUDeviceIDX = 0xffffffff; + break; + } + } + + /* Trap invalid timer error */ + if (LSU_DEVICE_COUNT <= u32LSUDeviceIDX) return; + + pu32SampleArray = (puint32)(&LSU4X_aau32ACSamples[u32LSUDeviceIDX][0]); + + /* Limit the amount of samples - use the last 8 samples */ + if (8 < LSU4X_au32ACSampleCount[u32LSUDeviceIDX]) + { + pu32SampleArray += (LSU4X_au32ACSampleCount[u32LSUDeviceIDX] - 8); + LSU4X_au32ACSampleCount[u32LSUDeviceIDX] = 8; + } + + u32SampleCount = LSU4X_au32ACSampleCount[u32LSUDeviceIDX]; + u32SampleCount = MAX(u32SampleCount, 2u); + u32SampleDiscard = (u32SampleCount - 1) >> 1; + + LSUH_aboADCQueuePending[u32LSUDeviceIDX] = TRUE; + LSUH_aboHeaterIsOn[u32LSUDeviceIDX] = FALSE; + LSU4X_au8ACCallBackWait[u32LSUDeviceIDX] = 0; + LSUH_au32ACADCDelta[u32LSUDeviceIDX] = USERMATH_u32DiscardAndAverage32(pu32SampleArray, u32SampleCount, u32SampleDiscard); + + if ((LSUH_nHeaterOhmsSamples - 1) > LSUH_au32ACSampleCounter[u32LSUDeviceIDX]) + { + LSUH_aau32ADADCSamples[u32LSUDeviceIDX][LSUH_au32ACSampleCounter[u32LSUDeviceIDX]] = LSUH_au32ACADCDelta[u32LSUDeviceIDX]; + LSUH_au32ACSampleCounter[u32LSUDeviceIDX]++; + } + else + { + u32SampleCount = LSUH_nHeaterOhmsSamples; + u32SampleDiscard = u32SampleCount >> 1; + LSUH_aau32ADADCSamples[u32LSUDeviceIDX][LSUH_au32ACSampleCounter[u32LSUDeviceIDX]] = LSUH_au32ACADCDelta[u32LSUDeviceIDX]; + LSUH_au32ACADCDeltaFiltered[u32LSUDeviceIDX] = USERMATH_u32DiscardAndAverage32(&LSUH_aau32ADADCSamples[u32LSUDeviceIDX][0], u32SampleCount, u32SampleDiscard); + + for (u32SampleIDX = 0; u32SampleIDX < LSUH_nHeaterOhmsSamples; u32SampleIDX++) + { + if ((LSUH_nMinACSample > LSUH_aau32ADADCSamples[u32LSUDeviceIDX][u32SampleIDX]) || + (LSUH_nMaxACSample < LSUH_aau32ADADCSamples[u32LSUDeviceIDX][u32SampleIDX])) + { + boSamplesOK = FALSE; + } + } + + if (TRUE == boSamplesOK) + { + LSU4X_atNernstSenseOhms[u32LSUDeviceIDX] = CONV_tADCToOhms(enEHIOResourceAD, LSUH_au32ACADCDeltaFiltered[u32LSUDeviceIDX]); + LSUH_aboNernstRNewValue[u32LSUDeviceIDX] = true; + } + + LSUH_au32ACSampleCounter[u32LSUDeviceIDX] = 0; + } +} + +void LSUH_vTEPMCallBackHigh(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime) +{ + uint32 u32LSUDeviceIDX; + + switch (enEHIOResource) + { + case EH_IO_TMR15: + { + u32LSUDeviceIDX = 0; + break; + } + case EH_IO_TMR16: + { + u32LSUDeviceIDX = 1; + break; + } + default: + { + u32LSUDeviceIDX = 0xffffffff; + break; + } + } + + /* Trap invalid timer error */ + if (LSU_DEVICE_COUNT <= u32LSUDeviceIDX) return; + + LSUH_aboADCQueuePending[u32LSUDeviceIDX] = TRUE; + LSUH_aboHeaterIsOn[u32LSUDeviceIDX] = TRUE; + LSUH_vInitiateTEPMQueue(enEHIOResource, tEventTime); +} + +static void LSUH_vInitiateTEPMQueue(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime) +{ + TEPMAPI_ttEventCount tEventCount; + uint16 u16LongPhase; + uint16 u16ShortPhase; + sint16 s16PLLTrim; + uint32 u32LSUDeviceIDX; + + switch (enEHIOResource) + { + case EH_IO_TMR15: + { + u32LSUDeviceIDX = 0; + break; + } + case EH_IO_TMR16: + { + u32LSUDeviceIDX = 1; + break; + } + default: + { + u32LSUDeviceIDX = 0xffffffff; + break; + } + } + + /* Trap invalid timer error */ + if (LSU_DEVICE_COUNT <= u32LSUDeviceIDX) return; + + /* Calculate the phase error between AC waveform and heater duty start */ + u16LongPhase = (uint16)tEventTime - LSU4X_u16PWMLastStart; + u16ShortPhase = u16LongPhase % (LSU4X_u16PWMPeriod / 10); + + /* Calculate the required PLL trim */ + s16PLLTrim = (LSU4X_u16PWMPeriod / 20) < u16ShortPhase ? + (sint16)(u16ShortPhase - (LSU4X_u16PWMPeriod / 10)) : + (sint16)u16ShortPhase; + + s16PLLTrim /= 4; + tEventCount = 2; + + LSUH_aastTimedEvents[u32LSUDeviceIDX][0].enAction = TEPMAPI_enSetLow; + LSUH_aastTimedEvents[u32LSUDeviceIDX][0].enMethod = TEPMAPI_enHardLinkedTimeStep; + LSUH_aastTimedEvents[u32LSUDeviceIDX][0].tEventTime = + ((uint16)(LSU4X_u16PWMPeriod - s16PLLTrim) * LSUH_au32HeaterDuty[u32LSUDeviceIDX]) / (100ul * LSU_DUTY_RES); + LSUH_aastTimedEvents[u32LSUDeviceIDX][0].pfEventCB = &LSUH_vTEPMCallBackLow; + + LSUH_aastTimedEvents[u32LSUDeviceIDX][1].enAction = TEPMAPI_enSetHigh; + LSUH_aastTimedEvents[u32LSUDeviceIDX][1].enMethod = TEPMAPI_enHardLinkedTimeStep; + LSUH_aastTimedEvents[u32LSUDeviceIDX][1].tEventTime = + ((uint16)(LSU4X_u16PWMPeriod - s16PLLTrim) * (100ul * LSU_DUTY_RES - LSUH_au32HeaterDuty[u32LSUDeviceIDX]) / (100ul * LSU_DUTY_RES)); + LSUH_aastTimedEvents[u32LSUDeviceIDX][1].pfEventCB = &LSUH_vTEPMCallBackHigh; + + USER_vSVC(SYSAPI_enAppendTEPMQueue, (void*)&enEHIOResource, + (void*)&LSUH_aastTimedEvents[u32LSUDeviceIDX][0], (void*)&tEventCount); + + LSUH_au32TEPMTimeout[u32LSUDeviceIDX] = 0; +} +#endif //LSUH_TEPM + + +#endif //BUILD_USER + + + + diff --git a/source/Client/LSUH.h b/source/Client/LSUH.h new file mode 100644 index 0000000..0980ac2 --- /dev/null +++ b/source/Client/LSUH.h @@ -0,0 +1,101 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. */ +/* All rights reserved. */ +/******************************************************************************/ +/* */ +/* PACKAGE TITLE: LSUH Header File */ +/* DESCRIPTION: This code module initialises the required ADC, DAC */ +/* CTRL, spread, table, DIO and TEPM resources for */ +/* managing the heater control for the LSU4.X sensor/s */ +/* */ +/* FILE NAME: LSUH.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef LSUH_H +#define LSUH_H + +#include "ADCAPI.h" +#include "CONV.h" +#include "CTRLAPI.h" +#include "declarations.h" +#include "IOAPI.h" +#include "LSU4X.h" +#include "TEPMAPI.h" +#include "UNITS.h" +#include "USER.h" +#include "USERMATH.h" + + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define LSUH_nADConfig \ +{ \ + {EH_IO_UART1_CTS, IOAPI_enADSE, ADCAPI_en4Samples, ADCAPI_enDiffGain1, &LSUH_vADCCallBack, ADCAPI_enTrigger3}, \ +} + +#define LSU_DUTY_RES 10u +#define LSUH_nRateHZ 1000u +#define LSUH_nHeaterEffInit 7000u /* 7 volts effective heater at startup */ +#define LSUH_nHeaterSenseOhms 180u +#define LSUH_nHeaterOhmsSamples 3u +#define LSUH_nMinACSample 10000u +#define LSUH_nMaxACSample 1600000u +#define LSUH_nCurrSenseOhms 0.18 +#define LSUH_nCurrSensePower 0.5 +#define LSUH_nMaxDutyDenom ((1000 * LSUH_nCurrSensePower) / LSUH_nCurrSenseOhms) +#define LSUH_nMinDuty 200u +#define LSUH_nMaxDuty 900u +#define LSUH_nCallsIn100Ms (0.1 * LSUH_nRateHZ) +#define LSUH_nHeffVLimit 13000u +#define LSUH_nHeffVRampRate 40000u +#define LSUH_nTEPMTimeOut (10 * LSUH_nRateHZ) +#define LSUH_nHeatCurrFilt 16u + +#define LSUH_nHMENResource EH_IO_GP1 +#define LSUH_nHMFResource EH_IO_UART1_CTS + +#undef EXTERN +#ifdef _LSUH_C + #define EXTERN +#else + #define EXTERN extern +#endif + +EXTERN uint32 LSUH_au32HeaterDuty[LSU_DEVICE_COUNT]; + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +/******************************************************************************* +* Description : Type to hold an AD resource configuration +*******************************************************************************/ +typedef struct +{ + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenEHIOType enEHIOType; + ADCAPI_tenSamplesAv enSamplesAv; + ADCAPI_tenDiffGain enDiffGain; + ADCAPI_tpfResultCB pfResultCB; + ADCAPI_tenTrigger enTrigger; +} LSUH_tstADConfig; + + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +EXTERN bool LSUH_aboHeaterIsOn[LSU_DEVICE_COUNT]; +EXTERN bool LSUH_aboSensorReady[LSU_DEVICE_COUNT]; +EXTERN uint32 LSUH_au32ACADCDeltaFiltered[LSU_DEVICE_COUNT]; +EXTERN uint32 LSUH_aau32ADADCSamples[LSU_DEVICE_COUNT][LSUH_nHeaterOhmsSamples]; +EXTERN uint32 LSUH_au32ACADCDelta[LSU_DEVICE_COUNT]; +EXTERN GPM6_ttOhms LSUH_atHeaterOhms[LSU_DEVICE_COUNT]; +//ASAM mode=readvalue name="Heater Ohms 1" type=uint32 offset=0 min=0 max=10 m=0.001 b=0 units="Ohms" format=5.3 help="Heater 1 Ohms" + + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void LSUH_vStart(uint32 * const pu32Arg); +void LSUH_vRun(uint32* const pu32Arg); +void LSUH_vTerminate(uint32* const pu32Arg); +void LSUH_vCallBack(uint32* const pu32Arg); +void LSUH_vTurnHeaterOff(void); +void LSUH_vTurnHeaterOn(void); + +#endif // LSUH_H + diff --git a/source/Client/MAP.c b/source/Client/MAP.c new file mode 100644 index 0000000..0a53039 --- /dev/null +++ b/source/Client/MAP.c @@ -0,0 +1,422 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Manifold Pressure Sensor */ +/* DESCRIPTION: This code module initialises the required ADC */ +/* resources and functions for manifold pressure */ +/* measurement */ +/* FILE NAME: MAP.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _MAP_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "MAP.h" + + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +bool MAP_boNewSample; + +SPREADAPI_ttSpreadIDX MAP_tSpreadVExIDX; +SPREADAPI_ttSpreadIDX MAP_tSpreadVEyIDX; +TABLEAPI_ttTableIDX MAP_tMapVEIDX; +SPREADAPI_ttSpreadIDX MAP_tSpreadPseudoMAPxIDX; +SPREADAPI_ttSpreadIDX MAP_tSpreadPseudoMAPyIDX; +TABLEAPI_ttTableIDX MAP_tMapPseudoMAPIDX; + + +SPREADAPI_ttSpreadIDX MAP_tSpreadPressureValveFeedForwardIDX; +TABLEAPI_ttTableIDX MAP_tTablePressureValveFeedForwardIDX; + +EXTERN GPM6_ttUg MAP_tManChargeMassOldUg; + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ +/******************************************************************************* +* Interface : MAP_vADCCallBack +* +* Implementation : Callback to receive the measured ADC value +* +* Parameter +* Par1 : enEHIOResource enum of the ADC resource +* Par2 : u32ADCResult the ADC conversion value +* +* Return Value : NIL +*******************************************************************************/ +static void MAP_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult); + + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void MAP_vStart(puint32 const pu32Arg) +{ + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenEHIOType enEHIOType; + ADCAPI_tstADCCB stADCCB; + + if (EH_IO_Invalid != USERCAL_stRAMCAL.u16MAPADResource) + { + enEHIOResource = USERCAL_stRAMCAL.u16MAPADResource; + enEHIOType = IOAPI_enADSE; + stADCCB.enSamplesAv = ADCAPI_en32Samples; + stADCCB.pfResultCB = &MAP_vADCCallBack; + stADCCB.enTrigger = ADCAPI_enTrigger4; + + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stADCCB); + + if (SYSAPI_enOK != pstSVCDataStruct->enSVCResult) + { + *pu32Arg |= (uint32)SYSAPI_enResourceRequestFailed;/*CR1_13*/ + } + } + else + { + *pu32Arg |= (uint32)SYSAPI_enResourceInitFailed;/*CR1_13*/ + } + } + + MAP_tKiloPaFiltered = MAP_nVoltsFilteredInitVal; + MAP_u32ADCRaw = MAP_nADCRawInitVal; + MAP_tKiloPaRaw = 101300; + + MAP_tManChargeMassUg = 0; + MAP_s32ManDeltaChargeMassPerSUg = 0; + + /* Request and initialise required Kernel managed spread for VEx */ + MAP_tSpreadVExIDX = SETUP_tSetupSpread((void*)&CAM_u32RPMFiltered, (void*)&USERCAL_stRAMCAL.aUserVExSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for VEy */ + MAP_tSpreadVEyIDX = SETUP_tSetupSpread((void*)&MAP_tKiloPaFiltered, (void*)&USERCAL_stRAMCAL.aUserVEySpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for VE*/ + MAP_tMapVEIDX = SETUP_tSetupMap((void*)&USERCAL_stRAMCAL.aUserMAPVE, (void*)&MAP_u16VE, TYPE_enUInt16, 17, 17, MAP_tSpreadVExIDX, MAP_tSpreadVEyIDX, NULL); + + /* Request and initialise required Kernel managed spread for pressure control valve feedforward */ + MAP_tSpreadPressureValveFeedForwardIDX = SETUP_tSetupSpread((void*)&MAP_tKiloPaTargetError, (void*)&USERCAL_stRAMCAL.aUserPressureValveFeedForwardSpread, TYPE_enInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for pressure control valve feedforward */ + MAP_tTablePressureValveFeedForwardIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserPressureValveFeedForwardTable, (void*)&MAP_u16PressureValveFeedForward, TYPE_enUInt16, 17, MAP_tSpreadPressureValveFeedForwardIDX, NULL); + + /* Request and initialise required Kernel managed spread for Pseudo MAP x */ + MAP_tSpreadPseudoMAPxIDX = SETUP_tSetupSpread((void*)&CAM_u32RPMFiltered, (void*)&USERCAL_stRAMCAL.aUserPseudoMAPxSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed spread for Pseudo MAP y */ + MAP_tSpreadPseudoMAPyIDX = SETUP_tSetupSpread((void*)&TPS_tThetaFiltered, (void*)&USERCAL_stRAMCAL.aUserPseudoMAPySpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for Pseudo MAP */ + MAP_tMapPseudoMAPIDX = SETUP_tSetupMap((void*)&USERCAL_stRAMCAL.aUserPseudoMAPMap, (void*)&MAP_u32PseudoMAP, TYPE_enUInt32, 17, 17, MAP_tSpreadPseudoMAPxIDX, MAP_tSpreadPseudoMAPyIDX, NULL); + + +} + +void MAP_vRun(puint32 const pu32Arg) +{ + static GPM6_ttPa MAP_tKiloPaOld = 0; + static uint32 u32Count; + static sint32 s32ErrorDerivativeFiltered; + static sint32 s32ErrorOld; + static bool boEnableVELearn = false; + sint32 s32DeltaMAP; + sint32 s32DeltaManifoldMass; + sint32 s32Temp; + SPREADAPI_tstSpreadResult* pstSpreadResultVEx; + SPREADAPI_tstSpreadResult* pstSpreadResultVEy; + uint32 u32TableIDXx = ~0; + uint32 u32TableIDXy = ~0; + uint8 u8MapFilter = 0x40; + uint32 u32Temp; + uint32 u32TPSWeightLimit; + + + /* Reduce filtering on RPM transitions */ + if (0 != CAM_u32RPMTransitionCounter) + { + u8MapFilter *= 2; + } + + /* Reduce filtering on TPS transitions */ + if ((0 != TPS_u32TransitionCounter) || (0 != TPS_u32ThrottleMovingCounter)) + { + u8MapFilter *= 2; + } + + if (EH_IO_Invalid != USERCAL_stRAMCAL.u16MAPADResource) + { + /* MAP sensor is configured go ahead and filter */ + USERMATH_u16SinglePoleLowPassFilter16(MAP_u32ADCRaw, u8MapFilter, &MAP_u32ADCFiltered); + + s32Temp = MAP_u32ADCFiltered * SENSORS_nADRefVolts; + s32Temp /= SENSORS_nADScaleMax; + s32Temp /= SENSORS_nVDivRatio; + + MAP_tSensorVolts = s32Temp; + + /* Calculate manifold pressure */ + s32Temp = (USERCAL_stRAMCAL.s32MapSensorGain * MAP_tSensorVolts) / 1000; + u32Temp = 0 > (s32Temp + USERCAL_stRAMCAL.s32MapSensorOffset) ? 0 : (uint32)(s32Temp + USERCAL_stRAMCAL.s32MapSensorOffset); + + if (FALSE == USERCAL_stRAMCAL.u8BoostChargeMAPEnable) + { + MAP_tKiloPaFiltered = u32Temp; + } + else + { + s32Temp = u32Temp; + + u32TPSWeightLimit = USERCAL_stRAMCAL.u16BoostChargeTPSLimit + 4 * CAM_u32RPMFiltered; + + /* 9923 * airflowUGPS / RPM * VE * CAPACITY = MAP */ + u32Temp = (11500 * (AFM_tAirFlowAFMUg / CAM_u32RPMFiltered)) / (USERCAL_stRAMCAL.u16CylinderCC * USERCAL_stRAMCAL.u8CylCount); + u32Temp = 10000 > u32Temp ? 10000 : u32Temp; + u32Temp = 200000 < u32Temp ? 200000 : u32Temp; + + + if (u32TPSWeightLimit < TPS_tThetaFiltered) + { + /* Low charge pipe pressure - use charge pressure MAP*/ + MAP_tKiloPaFiltered = (uint32)s32Temp; + } + else + { + /* Mix */ + s32Temp /= 10; + s32Temp *= TPS_tThetaFiltered; + s32Temp /= u32TPSWeightLimit; + s32Temp *= 10; + + u32Temp /= 10; + u32Temp *= (u32TPSWeightLimit - TPS_tThetaFiltered); + u32Temp /= u32TPSWeightLimit; + u32Temp *= 10; + + MAP_tKiloPaFiltered = (uint32)s32Temp + u32Temp; + } + } + + /* Calculate the current spread for VEx */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&MAP_tSpreadVExIDX, + NULL, NULL); + + /* Calculate the current spread for VEy */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&MAP_tSpreadVEyIDX, + NULL, NULL); + + /* Lookup the current value for VE */ + USER_vSVC(SYSAPI_enCalculateMap, (void*)&MAP_tMapVEIDX, + NULL, NULL); + } + else if (TRUE == USERCAL_stRAMCAL.u8PseudoMAPEnable) + { + /* Calculate the current spread for Pseudo MAP x */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&MAP_tSpreadPseudoMAPxIDX, + NULL, NULL); + + /* Calculate the current spread for Pseudo MAP y */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&MAP_tSpreadPseudoMAPyIDX, + NULL, NULL); + + /* Lookup the current value for Pseudo MAP */ + USER_vSVC(SYSAPI_enCalculateMap, (void*)&MAP_tMapPseudoMAPIDX, + NULL, NULL); + + MAP_tKiloPaFiltered = MAP_u32PseudoMAP; + + /* Calculate the current spread for VEx */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&MAP_tSpreadVExIDX, + NULL, NULL); + + /* Calculate the current spread for VEy */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&MAP_tSpreadVEyIDX, + NULL, NULL); + + /* Lookup the current value for VE */ + USER_vSVC(SYSAPI_enCalculateMap, (void*)&MAP_tMapVEIDX, + NULL, NULL); + } + else + { + /* Back calculate the manifold pressure from airflow */ + /* 9923 * airflowUGPS / RPM * VE * CAPACITY = MAP */ + u32Temp = (11500 * (AFM_tAirFlowAFMUg / CAM_u32RPMFiltered)) / (USERCAL_stRAMCAL.u16CylinderCC * USERCAL_stRAMCAL.u8CylCount); + u32Temp = 10000 > u32Temp ? 10000 : u32Temp; + u32Temp = 200000 < u32Temp ? 200000 : u32Temp; + MAP_tKiloPaFiltered = u32Temp; + } + + + if ((0 == TPS_u32ThrottleMovingCounter) && (400 < CAM_u32RPMRaw) && (0 == (u32Count % 5))) + { + /* Get the current x spread for VE */ + pstSpreadResultVEx = BOOSTED_pstGetSpread(MAP_tSpreadVExIDX); + + /* Get the current x spread for VE */ + pstSpreadResultVEy = BOOSTED_pstGetSpread(MAP_tSpreadVEyIDX); + + u32TableIDXx = (0x4000 > pstSpreadResultVEx->uSpreadData.stSpreadResult.u16SpreadOffset) ? pstSpreadResultVEx->uSpreadData.stSpreadResult.u16SpreadIndex : u32TableIDXx; + u32TableIDXx = (0xc000 < pstSpreadResultVEx->uSpreadData.stSpreadResult.u16SpreadOffset) ? pstSpreadResultVEx->uSpreadData.stSpreadResult.u16SpreadIndex + 1 : u32TableIDXx; + u32TableIDXy = (0x4000 > pstSpreadResultVEy->uSpreadData.stSpreadResult.u16SpreadOffset) ? pstSpreadResultVEy->uSpreadData.stSpreadResult.u16SpreadIndex : u32TableIDXy; + u32TableIDXy = (0xc000 < pstSpreadResultVEy->uSpreadData.stSpreadResult.u16SpreadOffset) ? pstSpreadResultVEy->uSpreadData.stSpreadResult.u16SpreadIndex + 1 : u32TableIDXy; + + /* If the indexes are valid then learn the new VE */ + if ((0xffffffff != u32TableIDXx) && (0xffffffff != u32TableIDXy) && (true == boEnableVELearn)) + { + if (AFM_u16LearnVE < USERCAL_stRAMCAL.aUserMAPVE[u32TableIDXx][u32TableIDXy]) + { + USERCAL_stRAMCAL.aUserMAPVE[u32TableIDXx][u32TableIDXy] = 400 < USERCAL_stRAMCAL.aUserMAPVE[u32TableIDXx][u32TableIDXy] ? + USERCAL_stRAMCAL.aUserMAPVE[u32TableIDXx][u32TableIDXy] - 1 : 400; + } + else if (AFM_u16LearnVE > USERCAL_stRAMCAL.aUserMAPVE[u32TableIDXx][u32TableIDXy]) + { + USERCAL_stRAMCAL.aUserMAPVE[u32TableIDXx][u32TableIDXy] = 1000 > USERCAL_stRAMCAL.aUserMAPVE[u32TableIDXx][u32TableIDXy] ? + USERCAL_stRAMCAL.aUserMAPVE[u32TableIDXx][u32TableIDXy] + 1 : 1000; + } + } + } + + + if (0 == (u32Count % 5)) + { + s32DeltaMAP = MAP_tKiloPaFiltered - MAP_tKiloPaOld; + s32DeltaManifoldMass = (USERCAL_stRAMCAL.u16ManifoldVolumeCC * MAP_nAirDensMgpL) / 1000; + s32DeltaManifoldMass *= s32DeltaMAP; + MAP_s32ManDeltaChargeMassPerSUg = (MAP_nRunFreq * -s32DeltaManifoldMass) / 10000; + MAP_tKiloPaOld = MAP_tKiloPaFiltered; + } + + MAP_boHighVacuum = USERCAL_stRAMCAL.u16HighVacuumEnableKpa > MAP_tKiloPaFiltered ? TRUE : MAP_boHighVacuum; + MAP_boHighVacuum = USERCAL_stRAMCAL.u16HighVacuumDisableKpa < MAP_tKiloPaFiltered ? FALSE : MAP_boHighVacuum; + + s32Temp = MAP_tKiloPaFiltered - (USERCAL_stRAMCAL.au16BoostTarget[5] * 10); + + if (s32Temp > (MAP_tKiloPaTargetError + USERCAL_stRAMCAL.u16PressureControlHyst)) + { + MAP_tKiloPaTargetError = s32Temp - USERCAL_stRAMCAL.u16PressureControlHyst; + } + else if (s32Temp < (MAP_tKiloPaTargetError - USERCAL_stRAMCAL.u16PressureControlHyst)) + { + MAP_tKiloPaTargetError = s32Temp - USERCAL_stRAMCAL.u16PressureControlHyst; + } + + + + if (1 == (u32Count % 5)) + { + s32ErrorDerivativeFiltered = (s32ErrorDerivativeFiltered / 2) + + ((MAP_tKiloPaTargetError - s32ErrorOld) / 2); + + s32ErrorOld = MAP_tKiloPaTargetError; + + if (0 > s32ErrorDerivativeFiltered) + { + s32Temp = s32ErrorDerivativeFiltered; + s32Temp *= USERCAL_stRAMCAL.u16PressureControlDNeg; + } + else if (0 < s32ErrorDerivativeFiltered) + { + s32Temp = s32ErrorDerivativeFiltered; + s32Temp *= USERCAL_stRAMCAL.u16PressureControlDPos; + } + else + { + s32Temp = 0; + } + + + /* Calculate the current spread for pressure valve feedforward */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&MAP_tSpreadPressureValveFeedForwardIDX, + NULL, NULL); + + /* Lookup the current pressure valve feedforward */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&MAP_tTablePressureValveFeedForwardIDX, + NULL, NULL); + + CPU_vEnterCritical(); + + if (0 < TORQUE_u16GearShiftPressureControlCount) + { + MAP_u16PressureValveDuty = USERCAL_stRAMCAL.u16ShiftPressureControl * 650; + } + else + { + if (0 < s32Temp) + { + if (0 < ((sint32)MAP_u16PressureValveFeedForward - s32Temp)) + { + MAP_u16PressureValveDuty = (uint16)((sint32)MAP_u16PressureValveFeedForward - s32Temp); + } + else + { + MAP_u16PressureValveDuty = 0; + } + } + else + { + if (0xffff > ((sint32)MAP_u16PressureValveFeedForward - s32Temp)) + { + MAP_u16PressureValveDuty = (uint16)((sint32)MAP_u16PressureValveFeedForward - s32Temp); + } + else + { + MAP_u16PressureValveDuty = 0xffff; + } + + } + } + + CPU_vExitCritical(); + + if (-USERCAL_stRAMCAL.u16PressureControlThreshold < MAP_tKiloPaTargetError) + { + /* Overboost */ + u32Temp = (USERCAL_stRAMCAL.u16ThrottlePressureControlCal * + (MAP_tKiloPaTargetError + USERCAL_stRAMCAL.u16PressureControlThreshold)) / 160000; + + if (31 > u32Temp) + { + MAP_u8PressureThrottleTrim = 0x3f - u32Temp; + } + else + { + MAP_u8PressureThrottleTrim = 0x21; + } + } + else + { + MAP_u8PressureThrottleTrim = 0x3f; + } + } + + u32Count++; +} + +void MAP_vTerminate(puint32 const pu32Arg) +{ + +} + + +void MAP_vCallBack(puint32 const pu32Arg) +{ + +} + + +static void MAP_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult) +{ + MAP_u32ADCRaw = u32ADCResult; + MAP_boNewSample = TRUE; +} + +#endif //BUILD_USER diff --git a/source/Client/MAP.h b/source/Client/MAP.h new file mode 100644 index 0000000..d912fa4 --- /dev/null +++ b/source/Client/MAP.h @@ -0,0 +1,65 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Manifold Pressure Sensor Header File */ +/* DESCRIPTION: This code module initialises the required ADC */ +/* resources and functions for manifold pressure */ +/* measurement */ +/* FILE NAME: MAP.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef MAP_H +#define MAP_H + +#include +#include "IOAPI.h" +#include "USER.h" + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define MAP_nVoltsFilteredInitVal (uint32)(101300u) +#define MAP_nADFiltVal (0x40) +#define MAP_nSensorGain (26000u) +#define MAP_nSensorOffset (-2200u) +#define MAP_nAirDensMgpL (1190u) +#define MAP_nRunFreq (200) +#define MAP_nADCRawInitVal (2500) + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _MAP_C + #define EXTERN +#else + #define EXTERN extern +#endif + + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +EXTERN uint32 MAP_u32ADCRaw; +//ASAM mode=readvalue name="MAP Sensor ADC" type=uint32 offset=0 min=0 max=4095 m=1 b=0 units="dl" format=5.3 help="MAP Sensor ADC Counts" +EXTERN uint32 MAP_u32ADCFiltered; +EXTERN GPM6_ttVolts MAP_tSensorVolts;/*CR1_88*/ +//ASAM mode=readvalue name="MAP Sensor Voltage" type=uint32 offset=0 min=0 max=5 m=0.001 b=0 units="V" format=5.3 help="MAP Sensor Voltage" +EXTERN GPM6_ttPa MAP_tKiloPaRaw; +EXTERN volatile GPM6_ttPa MAP_tKiloPaFiltered; +//ASAM mode=readvalue name="MAP kPa" type=uint32 offset=0 min=0 max=500 m=0.001 b=0 units="kPa" format=5.3 help="Manifold Pressure" +EXTERN volatile sint32 MAP_tKiloPaTargetError; +EXTERN GPM6_ttUg MAP_tManChargeMassUg; +EXTERN sint32 MAP_s32ManDeltaChargeMassPerSUg; +EXTERN uint16 MAP_u16VE; +EXTERN bool MAP_boHighVacuum; +EXTERN uint16 MAP_u16PressureValveFeedForward; +EXTERN uint16 MAP_u16PressureValveDuty; +EXTERN uint8 MAP_u8PressureThrottleTrim; +EXTERN uint32 MAP_u32PseudoMAP; + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void MAP_vStart(uint32 * const pu32Arg); +void MAP_vRun(uint32* const pu32Arg); +void MAP_vTerminate(uint32* const pu32Arg); +void MAP_vCallBack(puint32 const pu32Arg); + +#endif // MAP_H diff --git a/source/Client/MCP23S08.c b/source/Client/MCP23S08.c new file mode 100644 index 0000000..6f03a0f --- /dev/null +++ b/source/Client/MCP23S08.c @@ -0,0 +1,160 @@ +/******************************************************************************/ +/* Copyright (c) 2017 MD Automotive Controls. */ +/* All rights reserved. */ +/******************************************************************************/ +/* */ +/* PACKAGE TITLE: MCP23S08 */ +/* DESCRIPTION: This code module provides functions to invoke the SPI */ +/* data transfers to/from the MCP23S08 device */ +/* */ +/* FILE NAME: MCP23S08.c */ +/* REVISION HISTORY: 11-01-2017 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "MCP23S08.h" + + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +uint8 MCP23S08_au8TXData[MCP23S08_TXRXBufferSize];/*CR1_71*/ +uint8 MCP23S08_au8RXData[MCP23S08_TXRXBufferSize];/*CR1_71*/ +IOAPI_tenEHIOResource MCP23S08_enIOResource; +bool MCP23S08_boBusy; +MCP23S08_tpfCB MCP23S08_pfCallBack; + + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ +/******************************************************************************* +* Interface : MCP23S08_vNotifyCB +* +* Implementation : Function called when the MCP23S08 data transfer is complete +* +* Parameter +* Par1 : enEHIOResource enum of the IIC resource used +* Par2 : enTransferType enum of the R/W mode +* Par3 : pvData pointer to data read +* +* Return Value : NIL +*******************************************************************************/ +static void MCP23S08_vNotifyCB(IOAPI_tenEHIOResource enEHIOResource, uint8* pu8Data, uint32 u32ByteCount, IOAPI_enTransferType enTransferType);/*CR1_74*/ + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void MCP23S08_vStart(puint32 const pu32Arg) +{ + MCP23S08_enIOResource = EH_VIO_SPI1; + MCP23S08_boBusy = FALSE; + MCP23S08_pfCallBack = NULL; +} + +void MCP23S08_vRun(puint32 const pu32Arg) +{ + +} + +void MCP23S08_vTerminate(puint32 const pu32Arg) +{ + +} + +bool MCP23S08_boSetCallback(MCP23S08_tpfCB pfCB) +{ + bool boRetVal = FALSE; + + if (NULL == MCP23S08_pfCallBack) + { + MCP23S08_pfCallBack = pfCB; + boRetVal = TRUE; + } + + return boRetVal; +} + +bool MCP23S08_boTransferData(IOAPI_enTransferType enTransferType, void* pvData, uint32 u32DataCount) +{ + IOAPI_tstTransferCB stTransferCB; + bool boRetVal = true; + + if ((FALSE == MCP23S08_boBusy) && ((MCP23S08_TXRXBufferSize - 2) >= u32DataCount)) + { + if (IOAPI_IO_TX == enTransferType) + { + if (NULL != pvData)/*CR1_72*/ + { + memcpy((void*)&MCP23S08_au8TXData[2], pvData, u32DataCount); + MCP23S08_au8TXData[0] = MCP23S08_nCmdWrite; + MCP23S08_au8TXData[1] = MCP23S08_nRegOLAT; + } + } + + stTransferCB.enEHIOResource = MCP23S08_enIOResource; + stTransferCB.enTransferType = enTransferType; + stTransferCB.pfCB = &MCP23S08_vNotifyCB; + stTransferCB.pvData = (void*)&MCP23S08_au8TXData[0]; + stTransferCB.u32ByteCount = u32DataCount + 2; + stTransferCB.boBlockingMode = FALSE; + + USER_vSVC(SYSAPI_enRequestIOBusTransfer, (void*)EH_VIO_SPI1, (void*)&stTransferCB, NULL); + MCP23S08_boBusy = TRUE; + } + else + { + boRetVal = false; + } + + return boRetVal; +} + +void MCP23S08_vSetDataDirection(uint8 u8DirMask1) +{ + IOAPI_tstTransferCB stTransferCB; + + if (FALSE == MCP23S08_boBusy) + { + MCP23S08_au8TXData[0] = MCP23S08_nCmdWrite; + MCP23S08_au8TXData[1] = MCP23S08_nRegIODIR; + MCP23S08_au8TXData[2] = u8DirMask1; + + stTransferCB.enEHIOResource = MCP23S08_enIOResource; + stTransferCB.enTransferType = IOAPI_IO_TX; + stTransferCB.pfCB = &MCP23S08_vNotifyCB; + stTransferCB.pvData = (void*)&MCP23S08_au8TXData[0]; + stTransferCB.u32ByteCount = 3; + + USER_vSVC(SYSAPI_enRequestIOBusTransfer, (void*)EH_VIO_SPI1, (void*)&stTransferCB, NULL); + MCP23S08_boBusy = TRUE; + } +} + +void MCP23S08_vThread(void) +{ + while(1); +} + +void MCP23S08_vCallBack(puint32 const pu32Arg) +{ + +} + +static void MCP23S08_vNotifyCB(IOAPI_tenEHIOResource enEHIOResource, uint8* pu8Data, uint32 u32ByteCount, IOAPI_enTransferType enTransferType) +{ + uint32 u32Flags; + + if (MCP23S08_enIOResource == enEHIOResource) + { + MCP23S08_boBusy = FALSE; + + if (NULL != MCP23S08_pfCallBack) + { + MCP23S08_pfCallBack(&u32Flags); + } + } +} + +#endif //BUILD_USER diff --git a/source/Client/MCP23S08.h b/source/Client/MCP23S08.h new file mode 100644 index 0000000..5472c07 --- /dev/null +++ b/source/Client/MCP23S08.h @@ -0,0 +1,72 @@ +/******************************************************************************/ +/* Copyright (c) 2017 MD Automotive Controls. */ +/* All rights reserved. */ +/******************************************************************************/ +/* */ +/* PACKAGE TITLE: MCP23S08 */ +/* DESCRIPTION: This code module provides functions to invoke the SPI */ +/* data transfers to/from the MCP23S08 device */ +/* */ +/* FILE NAME: MCP23S08.c */ +/* REVISION HISTORY: 11-01-2017 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef MCP23S08_H +#define MCP23S08_H + +#include +#include "IOAPI.h" +#include "USER.h" + + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define MCP23S08_TXRXBufferSize 16u + +#define MCP23S08_nCmdWrite 0x46 +#define MCP23S08_nCmdRead 0x47 + +#define MCP23S08_nRegIODIR 0x00 +#define MCP23S08_nRegIPOL 0x01 +#define MCP23S08_nRegGPINTEN 0x02 +#define MCP23S08_nRegDEFVAL 0x03 +#define MCP23S08_nRegINTCON 0x04 +#define MCP23S08_nRegIOCON 0x05 +#define MCP23S08_nRegGPPU 0x06 +#define MCP23S08_nRegINTF 0x07 +#define MCP23S08_nRegINTCAP 0x08 +#define MCP23S08_nRegGPIO 0x09 +#define MCP23S08_nRegOLAT 0x0a + +#define MCP23S08_nMaskAllOutput 0 + +typedef void (*MCP23S08_tpfCB)(puint32); + + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void MCP23S08_vStart(uint32 * const pu32Arg); +void MCP23S08_vRun(uint32* const pu32Arg); +void MCP23S08_vTerminate(uint32* const pu32Arg); +void MCP23S08_vThread(void); +void MCP23S08_vCallBack(puint32 const pu32Arg); +bool MCP23S08_boSetCallback(MCP23S08_tpfCB pfCB); + +/******************************************************************************* +* Interface : +* +* Implementation : +* +* Return Value : +*******************************************************************************/ +bool MCP23S08_boTransferData(IOAPI_enTransferType enTransferType, void* pvData, uint32 u32DataCount); + +/******************************************************************************* +* Interface : +* +* Implementation : +* +* Return Value : +*******************************************************************************/ +void MCP23S08_vSetDataDirection(uint8 u8DirMask1); + +#endif // MCP23S08_H + diff --git a/source/Client/RELAYS.c b/source/Client/RELAYS.c new file mode 100644 index 0000000..8a4bf84 --- /dev/null +++ b/source/Client/RELAYS.c @@ -0,0 +1,454 @@ +/******************************************************************************/ +/* Copyright (c) 2017 MD Automotive Controls. */ +/* All rights reserved. */ +/******************************************************************************/ +/* */ +/* PACKAGE TITLE: RELAYS */ +/* DESCRIPTION: This code module initialises the required resources */ +/* for driving the user application relays and functions */ +/* for controlling the on/off state */ +/* */ +/* FILE NAME: RELAYS.c */ +/* REVISION HISTORY: 11-01-2017 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _RELAYS_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "RELAYS.h" + + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +uint8 RELAYS_u8RelayBitState; +bool RELAYS_boInit; +const RELAY_tenBit RELAY_raenMAP[] = RELAY_MAP; + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ + + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void RELAYS_vStart(uint32 * const pu32Arg) +{ + uint32 u32ResIDX; + IOAPI_tenEHIOType enEHIOType; + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tstPortConfigCB stPortConfigCB; + IOAPI_tenDriveStrength enDriveStrength; + uint32 u32Flags; + uint32 u32VarAddress; + uint32 u32Temp; + + /* Setup the RELAYS SPI resources */ + enEHIOResource = EH_VIO_SPI1; + + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, NULL, NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stPortConfigCB.stNetConfig.uNetInfo.stIICNetInfo.u32SlaveAddress = 0; + stPortConfigCB.enPortMode = IOAPI_enPortSerialTransfer; + stPortConfigCB.u32BaudRateHz = RELAYS_nSPIFrequency; + stPortConfigCB.enVIOResource = EH_VIO_SPI1; + stPortConfigCB.stPinConfig.uPinInfo.stSPIPinInfo.enMOSIPin = EH_IO_SPI1_MOSI; + stPortConfigCB.stPinConfig.uPinInfo.stSPIPinInfo.enMISOPin = EH_IO_SPI1_MISO; + stPortConfigCB.stPinConfig.uPinInfo.stSPIPinInfo.enSCKPin = EH_IO_SPI1_CLK; + stPortConfigCB.enLLProtocol = PROTAPI_enLLNone; + stPortConfigCB.enTLProtocol = PROTAPI_enTLNone; + stPortConfigCB.pfRXTransferCB = NULL; + stPortConfigCB.pfTXTransferCB = NULL; + stPortConfigCB.stPinConfig.uPinInfo.stSPIPinInfo.boCaptureRising = TRUE; + stPortConfigCB.stPinConfig.uPinInfo.stSPIPinInfo.boShiftRising = FALSE; + stPortConfigCB.stPinConfig.uPinInfo.stSPIPinInfo.boDataIdleHigh = TRUE; + + enEHIOType = IOAPI_enSPIBus; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stPortConfigCB); + } + + enEHIOResource = RELAYS_nSPI_CS_RESOURCE; + enEHIOType = IOAPI_enDIOOutput; + enDriveStrength = IOAPI_enStrong; + + /* Set up the CS line */ + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, &u32Flags); + SETUP_vSetDigitalIOHigh(RELAYS_nSPI_CS_RESOURCE); + + /* Start the SPI I/O expander IC */ + MCP23S08_vStart(NULL); + + /* Set MCP23S08 port to output direction */ + (void)MCP23S08_boSetCallback(&RELAYS_vCallBack); + SETUP_vSetDigitalIOLow(RELAYS_nSPI_CS_RESOURCE); + MCP23S08_vSetDataDirection(0); + + + for (u32ResIDX = 0; u32ResIDX < 8; u32ResIDX++) + { + u32VarAddress = USERCAL_stRAMCAL.aLogicBlockVar[u32ResIDX] & 0xfffff; + + if (0 != u32VarAddress) + { + switch (USERCAL_stRAMCAL.aLogicBlockChainOutput[u32ResIDX]) + { + case NO_OUT: break; + case AND_NEXT:break; + case OR_NEXT:break; + case NOT_NEXT: break; + case XOR_NEXT: break; + default: + { + u32Temp = USERCAL_stRAMCAL.aLogicBlockChainOutput[u32ResIDX] - (uint32)OUT1_ON; + enEHIOResource = (IOAPI_tenEHIOResource)(u32Temp / 2); + enEHIOType = IOAPI_enDIOOutput; + + if (EH_IO_IIC1_SDA > enEHIOResource) + { + /* Only do this for a real pin not a virtual pin */ + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + } + } + } + } + } + + + if (SYSAPI_enOK != pstSVCDataStruct->enSVCResult) + { + *pu32Arg |= (uint32)SYSAPI_enResourceInitFailed; + } + + RELAYS_u8RelayBitState = 0; + RELAYS_boInit = false; +} + + +void RELAYS_vRun(uint32* const pu32Arg) +{ + static uint32 u32Count; + static uint32 u32LogicIDX; + static bool boResultPrev; + uint32 u32VarAddress; + bool boIsSigned; + uint32 u32ByteCount; + RELAYS_tenCompare enCompare; + bool boResult = false; + static RELAYS_tenChainOutput enChainOutputPrev; + uint32 u32Temp; + IOAPI_tenTriState enTriState; + IOAPI_tenEHIOResource enEHIOResource; + RELAY_tenBit enBit; + + return;/*TODO*/ + + if (false == RELAYS_boInit) return; + + if (511 < u32Count++) + { + SETUP_vSetDigitalIOLow(RELAYS_nSPI_CS_RESOURCE); + MCP23S08_vSetDataDirection(0); + u32Count = 0; + } + else + { + SETUP_vSetDigitalIOLow(RELAYS_nSPI_CS_RESOURCE); + (void)MCP23S08_boTransferData(IOAPI_IO_TX, (void*)&RELAYS_u8RelayBitState, 1); + } + + u32VarAddress = USERCAL_stRAMCAL.aLogicBlockVar[u32LogicIDX] & 0xfffff; + + if (0 != u32VarAddress) + { + u32VarAddress += 0x20000000; + + boIsSigned = (USERCAL_stRAMCAL.aLogicBlockVar[u32LogicIDX] & 0x400000) != 0 ? true : false; + u32ByteCount = 1 + ((USERCAL_stRAMCAL.aLogicBlockVar[u32LogicIDX] & 0x300000) >> 20); + enCompare = (USERCAL_stRAMCAL.aLogicBlockVar[u32LogicIDX] & 0x3800000) >> 23; + + if (false == boIsSigned) + { + switch (enCompare) + { + case GT: + { + switch (u32ByteCount) + { + case 4: + { + if (*(uint32*)u32VarAddress > USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX]) + { + boResult = TRUE; + } + else + { + boResult = FALSE; + } + + break; + } + case 2: + { + if (*(uint16*)u32VarAddress > USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX]) + { + boResult = TRUE; + } + else + { + boResult = FALSE; + } + + break; + } + case 1: + { + if (*(uint8*)u32VarAddress > USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX]) + { + boResult = TRUE; + } + else + { + boResult = FALSE; + } + + break; + } + default: + { + boResult = false; + break; + } + } + break; + } + case LT: + { + switch (u32ByteCount) + { + case 4: + { + if (*(uint32*)u32VarAddress < USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX]) + { + boResult = TRUE; + } + else + { + boResult = FALSE; + } + + break; + } + case 2: + { + if (*(uint16*)u32VarAddress < USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX]) + { + boResult = TRUE; + } + else + { + boResult = FALSE; + } + + break; + } + case 1: + { + if (*(uint8*)u32VarAddress < USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX]) + { + boResult = TRUE; + } + else + { + boResult = FALSE; + } + + break; + } + + default: + { + boResult = false; + break; + } + } + break; + } + case EE: + { + switch (u32ByteCount) + { + case 4: + + boResult = ((*((uint32*)u32VarAddress)) == USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX]) ? TRUE : FALSE; break; + case 2: + + boResult = ((*((uint16*)u32VarAddress)) == USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX]) ? TRUE : FALSE; break; + case 1: + + boResult = ((*((uint8*)u32VarAddress)) == USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX]) ? TRUE : FALSE; break; + default: boResult = false; break; + } + break; + } + case NE: + { + switch (u32ByteCount) + { + case 4: boResult = ((*((uint32*)u32VarAddress)) != USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX]) ? TRUE : FALSE; break; + case 2: boResult = ((*((uint16*)u32VarAddress)) != USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX]) ? TRUE : FALSE; break; + case 1: boResult = ((*((uint8*)u32VarAddress)) != USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX]) ? TRUE : FALSE; break; + default: boResult = false; break; + } + break; + } + } + } + else + { + switch (enCompare) + { + case GT: + { + switch (u32ByteCount) + { + case 4: boResult = *(sint32*)u32VarAddress > USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX] ? TRUE : FALSE; break; + case 2: boResult = *(sint16*)u32VarAddress > USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX] ? TRUE : FALSE; break; + case 1: boResult = *(sint8*)u32VarAddress > USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX] ? TRUE : FALSE; break; + default: boResult = false; break; + } + break; + } + case LT: + { + switch (u32ByteCount) + { + case 4: boResult = *(sint32*)u32VarAddress < USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX] ? TRUE : FALSE; break; + case 2: boResult = *(sint16*)u32VarAddress < USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX] ? TRUE : FALSE; break; + case 1: boResult = *(sint8*)u32VarAddress < USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX] ? TRUE : FALSE; break; + default: boResult = false; break; + } + break; + } + case EE: + { + switch (u32ByteCount) + { + case 4: boResult = *(sint32*)u32VarAddress == USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX] ? TRUE : FALSE; break; + case 2: boResult = *(sint16*)u32VarAddress == USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX] ? TRUE : FALSE; break; + case 1: boResult = *(sint8*)u32VarAddress == USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX] ? TRUE : FALSE; break; + default: boResult = false; break; + } + break; + } + case NE: + { + switch (u32ByteCount) + { + case 4: boResult = *(sint32*)u32VarAddress != USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX] ? TRUE : FALSE; break; + case 2: boResult = *(sint16*)u32VarAddress != USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX] ? TRUE : FALSE; break; + case 1: boResult = *(sint8*)u32VarAddress != USERCAL_stRAMCAL.aLogicBlockOperand[u32LogicIDX] ? TRUE : FALSE; break; + default: boResult = false; break; + } + break; + } + } + } + + + switch (enChainOutputPrev) + { + case NO_OUT: break; + case AND_NEXT: boResult &= boResultPrev; break; + case OR_NEXT: boResult |= boResultPrev; break; + case NOT_NEXT: + { + boResult = boResultPrev & !boResult; + break; + } + case XOR_NEXT: boResult ^= boResultPrev; break; + default: break; + } + + + switch (USERCAL_stRAMCAL.aLogicBlockChainOutput[u32LogicIDX]) + { + case NO_OUT: break; + case AND_NEXT: boResultPrev = boResult; break; + case OR_NEXT: boResultPrev = boResult; break; + case NOT_NEXT: boResultPrev = boResult; break; + case XOR_NEXT: boResultPrev = boResult; break; + + default: + { + if (true == boResult) + { + u32Temp = USERCAL_stRAMCAL.aLogicBlockChainOutput[u32LogicIDX] - (uint32)OUT1_ON; + enTriState = u32Temp & 0x01 ? IOAPI_enLow : IOAPI_enHigh; + enEHIOResource = (IOAPI_tenEHIOResource)(u32Temp / 2); + + if (EH_IO_IIC1_SDA > enEHIOResource) + { + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, + (void*)&enTriState, (void*)NULL); + } + else + { + enBit = RELAY_raenMAP[enEHIOResource - EH_IO_IIC1_SDA]; + boResult = IOAPI_enHigh == enTriState; + RELAYS_vOutputBit(enBit, boResult); + } + + break; + } + + boResultPrev = false; + } + } + + enChainOutputPrev = USERCAL_stRAMCAL.aLogicBlockChainOutput[u32LogicIDX]; + } + + u32LogicIDX = (u32LogicIDX + 1) & 0x7; +} + + +void RELAYS_vTerminate(uint32* const pu32Arg) +{ + +} + + +void RELAYS_vOutputBit(RELAY_tenBit enBit, bool boBitOn) +{ + if (FALSE == boBitOn) + { + RELAYS_u8RelayBitState &= ~enBit; + } + else + { + RELAYS_u8RelayBitState |= enBit; + } +} + + +void RELAYS_vCallBack(uint32* const pu32Arg) +{ + SETUP_vSetDigitalIOHigh(RELAYS_nSPI_CS_RESOURCE); + RELAYS_boInit = true; +} + +void RELAYS_vThread(void) +{ + while(1); +} + + +#endif //BUILD_USER + + + diff --git a/source/Client/RELAYS.h b/source/Client/RELAYS.h new file mode 100644 index 0000000..6024f4a --- /dev/null +++ b/source/Client/RELAYS.h @@ -0,0 +1,125 @@ +/******************************************************************************/ +/* Copyright (c) 2017 MD Automotive Controls. */ +/* All rights reserved. */ +/******************************************************************************/ +/* */ +/* PACKAGE TITLE: RELAYS header file */ +/* DESCRIPTION: This code module initialises the required resources */ +/* for driving the user application relays and functions */ +/* for controlling the on/off state */ +/* */ +/* FILE NAME: RELAYS.c */ +/* REVISION HISTORY: 11-01-2017 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef RELAYS_H +#define RELAYS_H + + +#include "declarations.h" +#include "MCP23S08.h" +#include "IOAPI.h" +#include "SYSAPI.h" +#include "USER.h" + + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define RELAYS_nSPIFrequency 2000000u +#define RELAYS_nSPI_CS_RESOURCE EH_IO_GP6 +#define RELAYS_TELLTALE_1 EH_IO_GPSE2 +#define RELAYS_TELLTALE_2 EH_IO_GPSE3 + +#undef EXTERN +#ifdef _RELAYS_C + #define EXTERN +#else + #define EXTERN extern +#endif + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +/******************************************************************************* +* Description : Type to hold an RELAYS character configuration +*******************************************************************************/ +typedef enum +{ + RELAY_BIT0 = 1, + RELAY_BIT1 = 2, + RELAY_BIT2 = 4, + RELAY_BIT3 = 8, + RELAY_BIT4 = 16, + RELAY_BIT5 = 32, + RELAY_BIT6 = 64, + RELAY_BIT7 = 128, +} RELAY_tenBit; + +typedef enum +{ + NO_OUT, + AND_NEXT, + OR_NEXT, + NOT_NEXT, + XOR_NEXT, + OUT1_ON, + OUT1_OFF, + OUT2_ON, + OUT2_OFF, + OUT3_ON, + OUT3_OFF, + OUT4_ON, + OUT4_OFF, + OUT5_ON, + OUT5_OFF, + OUT6_ON, + OUT6_OFF, + OUT7_ON, + OUT7_OFF, + OUT8_ON, + OUT8_OFF, + OUT9_ON, + OUT9_OFF, + OUT10_ON, + OUT10_OFF +} RELAYS_tenChainOutput; + +typedef enum +{ + GT, + LT, + EE, + NE +} RELAYS_tenCompare; + +typedef enum +{ + REL_INVALID, + REL_HIGH, + REL_LOW, + REL_TOGGLE, +} RELAYS_tenAction; + +#define RELAY_MAP \ +{\ + RELAY_BIT5,\ + RELAY_BIT4,\ + RELAY_BIT6,\ + RELAY_BIT7,\ + RELAY_BIT2,\ + RELAY_BIT3,\ + RELAY_BIT1,\ + RELAY_BIT0\ +} + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ + + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void RELAYS_vStart(uint32 * const pu32Arg ); +void RELAYS_vRun(uint32* const pu32Arg ); +void RELAYS_vTerminate(uint32* const pu32Arg ); +void RELAYS_vCallBack(uint32* const pu32Arg ); +void RELAYS_vOutputBit(RELAY_tenBit enBit, bool boBitOn); +void RELAYS_vThread(void); + +#endif // RELAYS_H + diff --git a/source/Client/SENSORS.c b/source/Client/SENSORS.c new file mode 100644 index 0000000..ce10b66 --- /dev/null +++ b/source/Client/SENSORS.c @@ -0,0 +1,852 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Sensors */ +/* DESCRIPTION: This code manages the sensors AD conversions */ +/* */ +/* */ +/* FILE NAME: SENSORS.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _SENSORS_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "SENSORS.h" +#include "USERMATH.h" +#include "IAC.h" +#include "FME.h" + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +uint32 SENSORS_u32RunCounter; +uint8 SENSORS_au8CANBufferMap[] = SENSORS_nCANBufferMap; +SENSORS_tenADConfig SENSORS_aenADConfig[SENSORS_enADCount]; +uint16 SENSORS_au16ADSensorValue[SENSORS_enADCount]; +uint16 SENSORS_au16ADSensorFiltered[SENSORS_enADCount]; +SPREADAPI_ttSpreadIDX SENSORS_tSpreadPedalTransferIDX; +TABLEAPI_ttTableIDX SENSORS_tTablePedalTransferIDX; + + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ +static void SENSORS_vCEMCallBack(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime); +static void SENSORS_vGetCANSensorData(void); +static void SENSORS_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult); +static void SENSORS_vAddConfiguredAD(SENSORS_tenADConfig enADConfig); + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void SENSORS_vStart(puint32 const pu32Arg) +{ + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenEHIOType enEHIOType; + IOAPI_tenDriveStrength enDriveStrength; + TEPMAPI_tstTEPMChannelCB stTEPMChannelCB; + TEPMAPI_tstTEPMResourceCB stTEPMResourceCB; + TEPMAPI_tstTimedUserEvent stTimedEvent; + SENSORS_u32RunCounter = 0; + uint32 u32IDX; + bool boOK; + + +#ifdef BUILD_CTS_PULLUP_SENSE + enEHIOResource = CTS_nSwitchPin; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); +#endif + + + /* Request and initialise required Kernel managed spread for pedal transfer */ + SENSORS_tSpreadPedalTransferIDX = SETUP_tSetupSpread((void*)&SENSORS_u32PPSMVoltsRamp, (void*)&USERCAL_stRAMCAL.aUserPedalTransferSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for coolant sensor */ + SENSORS_tTablePedalTransferIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserPedalTransferTable, (void*)&SENSORS_u16TPSSafeMax, TYPE_enUInt16, 17, SENSORS_tSpreadPedalTransferIDX, NULL); + + + /* Request and initialise FTM for CRANK_nInput */ + enEHIOResource = EH_VIO_FTM3; + enEHIOType = IOAPI_enTEPM; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + /* ONLY CONFIGURE THE TC3 MODULE ONCE PER PROJECT! */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMResourceCB.enEHIOResource = EH_VIO_FTM3; + stTEPMResourceCB.enPreScalar = SENSORS_nFastFTMDivisor; + stTEPMResourceCB.enCountType = TEPMAPI_enCountUp; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMResourceCB); + } + + /* Request and initialise CRANK_nInput */ + enEHIOResource = CRANK_nInput; + enEHIOType = IOAPI_enCaptureCompare; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + /* Initialise the TEPM channel CRANK_nInput */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMChannelCB.enAction = TEPMAPI_enCapRising; + stTEPMChannelCB.boInterruptEnable = TRUE; + stTEPMChannelCB.enLinkedResource = VR_nPhaseTelltalePin; + stTEPMChannelCB.boRecursive = TRUE; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMChannelCB); + } + + stTimedEvent.enMethod = TEPMAPI_enLinkPrimaryProgram; + stTimedEvent.pfEventCB = &SENSORS_vCEMCallBack; + + USER_vSVC(SYSAPI_enConfigureUserTEPMInput, (void*)&enEHIOResource, + (void*)&stTimedEvent, (void*)NULL); + + +#ifdef BUILD_BSP_AFM_FREQ + /* Request and initialise AFM_FREQ_nInput */ + enEHIOResource = AFM_FREQ_nInput; + enEHIOType = IOAPI_enCaptureCompare; + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + /* Initialise the TEPM channel AFM_FREQ_nInput */ + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stTEPMChannelCB.enAction = TEPMAPI_enCapRising; + stTEPMChannelCB.boInterruptEnable = TRUE; + stTEPMChannelCB.boRecursive = FALSE; + + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stTEPMChannelCB); + } + + stTimedEvent.enMethod = TEPMAPI_enLinkFreqInput; + stTimedEvent.pfEventCB = &SENSORS_vCEMCallBack; +#endif //BUILD_BSP_AFM_FREQ + + USER_vSVC(SYSAPI_enConfigureUserTEPMInput, (void*)&enEHIOResource, + (void*)&stTimedEvent, (void*)NULL); + + /* Enable the Hall-Effect sensor type */ + enEHIOResource = VRA_nPullupEnablePin; + enEHIOType = IOAPI_enDIOOutput; + enDriveStrength = IOAPI_enStrong; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + enEHIOResource = VRB_nPullupEnablePin; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + enEHIOResource = VRA_nVREnablePin; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + enEHIOResource = VRB_nVREnablePin; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + enEHIOResource = VR_nHystHighPin; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + enEHIOResource = VR_nHystLowPin; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + enEHIOResource = VVTAB_nPullupEnablePin; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + enEHIOResource = VVTCD_nPullupEnablePin; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + enEHIOResource = VR_nPhaseTelltalePin; + SETUP_vSetupDigitalIO(enEHIOResource, enEHIOType, enDriveStrength, pu32Arg); + + + if (TRUE == USERCAL_stRAMCAL.u8UserPrimaryVREnable) + { + SETUP_vSetDigitalIOHigh(VRA_nVREnablePin); + SETUP_vSetDigitalIOLow(VRA_nPullupEnablePin); + } + else + { + SETUP_vSetDigitalIOLow(VRA_nVREnablePin); + SETUP_vSetDigitalIOHigh(VRA_nPullupEnablePin); + } + + if (TRUE == USERCAL_stRAMCAL.u8UserSecondaryVREnable) + { + SETUP_vSetDigitalIOLow(VRB_nPullupEnablePin); + SETUP_vSetDigitalIOHigh(VRB_nVREnablePin); + } + else + { + SETUP_vSetDigitalIOHigh(VRB_nPullupEnablePin); + SETUP_vSetDigitalIOLow(VRB_nVREnablePin); + } + + if (TRUE == USERCAL_stRAMCAL.u8VCTABPullupEnable) + { + SETUP_vSetDigitalIOHigh(VVTAB_nPullupEnablePin); + } + else + { + SETUP_vSetDigitalIOLow(VVTAB_nPullupEnablePin); + } + + if (TRUE == USERCAL_stRAMCAL.u8VCTCDPullupEnable) + { + SETUP_vSetDigitalIOHigh(VVTCD_nPullupEnablePin); + } + else + { + SETUP_vSetDigitalIOLow(VVTCD_nPullupEnablePin); + } + + SETUP_vSetDigitalIOHigh(VR_nHystHighPin); + SETUP_vSetDigitalIOLow(VR_nHystLowPin); + + + SENSORS_u8CANCTS = 0xff; + SENSORS_u8CANATS = 0xff; + SENSORS_u8CANSTT[0] = 0xff; + SENSORS_u8CANSTT[1] = 0xff; + SENSORS_u8CANLTT[0] = 0xff; + SENSORS_u8CANLTT[1] = 0xff; + DIAG_u8PowerModeActive = 0; + + for (u32IDX = 0; u32IDX < SENSORS_enADCount; u32IDX++) + { + SENSORS_aenADConfig[u32IDX] = SENSORS_enADInvalid; + } + + /* Start CAN right away */ + DIAG_u16PowerModeActiveCount = 1000; + + if (EH_IO_Invalid != USERCAL_stRAMCAL.u16AFRADResource) + { + /* Request and initialise the AFR ADC input channel */ + boOK = SETUP_boSetupADSE(USERCAL_stRAMCAL.u16AFRADResource, IOAPI_enADSE, ADCAPI_en32Samples, &SENSORS_vADCCallBack, ADCAPI_enTrigger2, pu32Arg); + + if (TRUE == boOK) + { + SENSORS_vAddConfiguredAD(SENSORS_enADAFR); + } + } + + if (EH_IO_Invalid != USERCAL_stRAMCAL.u16PPSMADResource) + { + /* Request and initialise the PPSM ADC input channel */ + boOK = SETUP_boSetupADSE(USERCAL_stRAMCAL.u16PPSMADResource, IOAPI_enADSE, ADCAPI_en32Samples, &SENSORS_vADCCallBack, ADCAPI_enTrigger2, pu32Arg); + + if (TRUE == boOK) + { + SENSORS_vAddConfiguredAD(SENSORS_enADPPSM); + } + } + + if (EH_IO_Invalid != USERCAL_stRAMCAL.u16PPSSADResource) + { + /* Request and initialise the PPSS ADC input channel */ + boOK = SETUP_boSetupADSE(USERCAL_stRAMCAL.u16PPSSADResource, IOAPI_enADSE, ADCAPI_en32Samples, &SENSORS_vADCCallBack, ADCAPI_enTrigger2, pu32Arg); + + if (TRUE == boOK) + { + SENSORS_vAddConfiguredAD(SENSORS_enADPPSS); + } + } + + if (EH_IO_Invalid != USERCAL_stRAMCAL.au16AuxInputResource[0]) + { + /* Request and initialise the PPSS ADC input channel */ + boOK = SETUP_boSetupADSE(USERCAL_stRAMCAL.au16AuxInputResource[0], IOAPI_enADSE, ADCAPI_en32Samples, &SENSORS_vADCCallBack, ADCAPI_enTrigger2, pu32Arg); + + if (TRUE == boOK) + { + SENSORS_vAddConfiguredAD(SENSORS_enAUX1); + } + } + + if (EH_IO_Invalid != USERCAL_stRAMCAL.au16AuxInputResource[1]) + { + /* Request and initialise the PPSS ADC input channel */ + boOK = SETUP_boSetupADSE(USERCAL_stRAMCAL.au16AuxInputResource[1], IOAPI_enADSE, ADCAPI_en32Samples, &SENSORS_vADCCallBack, ADCAPI_enTrigger2, pu32Arg); + + if (TRUE == boOK) + { + SENSORS_vAddConfiguredAD(SENSORS_enAUX2); + } + } + + if (EH_IO_Invalid != USERCAL_stRAMCAL.au16AuxInputResource[2]) + { + /* Request and initialise the PPSS ADC input channel */ + boOK = SETUP_boSetupADSE(USERCAL_stRAMCAL.au16AuxInputResource[2], IOAPI_enADSE, ADCAPI_en32Samples, &SENSORS_vADCCallBack, ADCAPI_enTrigger2, pu32Arg); + + if (TRUE == boOK) + { + SENSORS_vAddConfiguredAD(SENSORS_enAUX3); + } + } + + if (EH_IO_Invalid != USERCAL_stRAMCAL.au16AuxInputResource[3]) + { + /* Request and initialise the PPSS ADC input channel */ + boOK = SETUP_boSetupADSE(USERCAL_stRAMCAL.au16AuxInputResource[3], IOAPI_enADSE, ADCAPI_en32Samples, &SENSORS_vADCCallBack, ADCAPI_enTrigger2, pu32Arg); + + if (TRUE == boOK) + { + SENSORS_vAddConfiguredAD(SENSORS_enAUX4); + } + } + + for (u32IDX = 0; u32IDX < SENSORS_enADCount; u32IDX++) + { + SENSORS_au16ADSensorValue[u32IDX] = 0xffff; + } +} + +static void SENSORS_vAddConfiguredAD(SENSORS_tenADConfig enADConfig) +{ + uint32 u32IDX; + + for (u32IDX = 0; u32IDX < SENSORS_enADCount; u32IDX++) + { + if (SENSORS_enADInvalid == SENSORS_aenADConfig[u32IDX]) + { + SENSORS_aenADConfig[u32IDX] = enADConfig; + break; + } + } +} + +void SENSORS_vRun(puint32 const pu32Arg) +{ + ADCAPI_tenTrigger enTrigger; + uint8 u8TriggerHystLow = 2 - USERCAL_stRAMCAL.u8TriggerPullStrength; + uint8 u8TriggerHystHigh = 4 + USERCAL_stRAMCAL.u8TriggerPullStrength; + uint32 u32AUXIDX = SENSORS_u32RunCounter & 0x7; + uint16 u32Temp; + static bool boSensorRPMHystLimit; + + boSensorRPMHystLimit = USERCAL_stRAMCAL.u16SensorHystLimitRPM > CAM_u32RPMFiltered ? FALSE : boSensorRPMHystLimit; + boSensorRPMHystLimit = ((9 * USERCAL_stRAMCAL.u16SensorHystLimitRPM) / 8) < CAM_u32RPMFiltered ? + TRUE : boSensorRPMHystLimit; + + if (0 == (SENSORS_u32RunCounter % SENSORS_nFastPeriod)) + { + enTrigger = ADCAPI_enTrigger4; + USER_vSVC(SYSAPI_enTriggerADQueue, (void*)&enTrigger, (void*)NULL, (void*)NULL);/*CR1_12*/ + } + +#ifdef BUILD_CTS_PULLUP_SENSE + static uint32 u32Count; + + if (0 == (SENSORS_u32RunCounter % SENSORS_nSlowPeriod)) + { + if (0 == (u32Count++ % 2)) + { + SENSORS_boCTSACBiasHigh = TRUE; + SETUP_vSetDigitalIOHigh(CTS_nSwitchPin); + } + else + { + SENSORS_boCTSACBiasHigh = FALSE; + SETUP_vSetDigitalIOLow(CTS_nSwitchPin); + } + } +#endif + + if (1 == (SENSORS_u32RunCounter % SENSORS_nSlowPeriod)) + { + enTrigger = ADCAPI_enTrigger2; + USER_vSVC(SYSAPI_enTriggerADQueue, (void*)&enTrigger, (void*)NULL, (void*)NULL);/*CR1_12*/ + } + + if (FALSE == boSensorRPMHystLimit) + { + if (0 == SENSORS_u32RunCounter % 0x05) + { + if (0 < u8TriggerHystLow) + { + SETUP_vSetDigitalIOHigh(VR_nHystLowPin); + } + else + { + SETUP_vSetDigitalIOLow(VR_nHystLowPin); + } + + if (0 < u8TriggerHystHigh) + { + SETUP_vSetDigitalIOHigh(VR_nHystHighPin); + } + else + { + SETUP_vSetDigitalIOLow(VR_nHystHighPin); + } + } + else if (u8TriggerHystLow == SENSORS_u32RunCounter % 0x05) + { + SETUP_vSetDigitalIOLow(VR_nHystLowPin); + } + if (u8TriggerHystHigh == SENSORS_u32RunCounter % 0x05) + { + SETUP_vSetDigitalIOLow(VR_nHystHighPin); + } + } + else + { + SETUP_vSetDigitalIOLow(VR_nHystLowPin); + SETUP_vSetDigitalIOHigh(VR_nHystHighPin); + } + + + if (0 == SENSORS_u32RunCounter % 0x08) + { + SENSORS_vGetCANSensorData(); + } + + SENSORS_au16ADSensorFiltered[u32AUXIDX] = + (SENSORS_au16ADSensorValue[u32AUXIDX] + + 3 * SENSORS_au16ADSensorFiltered[u32AUXIDX]) / 4; + + + SENSORS_aboAUXActive[u32AUXIDX] = + SENSORS_au16ADSensorValueFiltered[u32AUXIDX] < + USERCAL_stRAMCAL.au16AuxInputLowThres[u32AUXIDX - SENSORS_enAUX1] ? FALSE : SENSORS_aboAUXActive[u32AUXIDX]; + + SENSORS_aboAUXActive[u32AUXIDX] = + SENSORS_au16ADSensorValueFiltered[u32AUXIDX] > + USERCAL_stRAMCAL.au16AuxInputHighThres[u32AUXIDX - SENSORS_enAUX1] ? TRUE : SENSORS_aboAUXActive[u32AUXIDX]; + + if (SENSORS_enADAFR == u32AUXIDX) + { + SENSORS_au16ADSensorValueFiltered[u32AUXIDX] = + CONV_tADCToVolts(USERCAL_stRAMCAL.u16AFRADResource, SENSORS_au16ADSensorFiltered[u32AUXIDX]); + } + + if (SENSORS_enADPPSM == u32AUXIDX) + { + SENSORS_au16ADSensorValueFiltered[u32AUXIDX] = + CONV_tADCToVolts(USERCAL_stRAMCAL.u16PPSMADResource, SENSORS_au16ADSensorFiltered[u32AUXIDX]); + + SENSORS_u32PPSMVolts = SENSORS_au16ADSensorValueFiltered[u32AUXIDX]; + + u32Temp = CONV_tADCToVolts(USERCAL_stRAMCAL.u16PPSMADResource, SENSORS_au16ADSensorValue[u32AUXIDX]); + + if (u32Temp < SENSORS_u32PPSMVoltsRamp) + { + if ((SENSORS_u32PPSMVoltsRamp - u32Temp) > PPSM_RAMP_MAX_NEG) + { + if (SENSORS_u32PPSMVoltsRamp > PPSM_RAMP_MAX_NEG) + { + SENSORS_u32PPSMVoltsRamp -= PPSM_RAMP_MAX_NEG; + } + } + else + { + SENSORS_u32PPSMVoltsRamp = u32Temp; + } + } + else + { + if ((u32Temp - SENSORS_u32PPSMVoltsRamp) > PPSM_RAMP_MAX_POS) + { + SENSORS_u32PPSMVoltsRamp += PPSM_RAMP_MAX_POS; + } + else + { + SENSORS_u32PPSMVoltsRamp = u32Temp; + } + } + + + /* Calculate the current spread for pedal transfer */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&SENSORS_tSpreadPedalTransferIDX, + NULL, NULL); + + /* Lookup the current spread for pedal transfer */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&SENSORS_tTablePedalTransferIDX, + NULL, NULL); + + if (3000 > SENSORS_u32PPSMVoltsRamp) + { + if ((0 != TORQUE_u16GearShiftCount) && (TRUE == TORQUE_boDownShift)) + { + SENSORS_u16TPSSafeMaxModified = SENSORS_u16TPSSafeMax + FME_nBLIP_THROTTLE_DELTA_MAX; + } + else if (0x1234 != USERCAL_stRAMCAL.u16ETCOverrideKeys) + { + /* No higher than pedal authority */ + SENSORS_u16TPSSafeMaxModified = SENSORS_u32PPSMVoltsRamp > (uint32)SENSORS_u16TPSSafeMax ? + SENSORS_u16TPSSafeMax : (uint16)SENSORS_u32PPSMVoltsRamp; + } + else + { + /* Else in short overrides by diag */ + SENSORS_u16TPSSafeMaxModified = SENSORS_u16TPSSafeMax + FME_nOVERRIDE_DELTA_MAX; + } + } + else + { + SENSORS_u16TPSSafeMaxModified = (5 * SENSORS_u32PPSMVoltsRamp) / 4; + } + } + + if (SENSORS_enADPPSS == u32AUXIDX) + { + SENSORS_au16ADSensorValueFiltered[u32AUXIDX] = + CONV_tADCToVolts(USERCAL_stRAMCAL.u16PPSSADResource, SENSORS_au16ADSensorFiltered[u32AUXIDX]); + } + + if ((SENSORS_enAUX1 <= u32AUXIDX) && (SENSORS_enAUX4 <= u32AUXIDX)) + { + SENSORS_au16ADSensorValueFiltered[u32AUXIDX] = + CONV_tADCToVolts(USERCAL_stRAMCAL.au16AuxInputResource[u32AUXIDX - SENSORS_enAUX1], SENSORS_au16ADSensorFiltered[u32AUXIDX]); + } + +#ifdef BUILD_FME + /* FME calls */ + if ((EH_IO_Invalid != USERCAL_stRAMCAL.u16PPSMADResource) && + (EH_IO_Invalid != USERCAL_stRAMCAL.u16PPSSADResource)) + { + FME_enUpdateDiagState(FME_enPPSPair, SENSORS_au16ADSensorFiltered[SENSORS_enADPPSM], + SENSORS_au16ADSensorFiltered[SENSORS_enADPPSS]); + FME_enUpdateDiagState(FME_enPPSMSingle, SENSORS_au16ADSensorFiltered[SENSORS_enADPPSM], 0); + FME_enUpdateDiagState(FME_enPPSSSingle, SENSORS_au16ADSensorFiltered[SENSORS_enADPPSS], 0); + } + + /* FME calls */ + if ((EH_IO_Invalid != USERCAL_stRAMCAL.u16PPSMADResource) && + (EH_IO_Invalid != USERCAL_stRAMCAL.u16TPSADResource)) + { + FME_enUpdateDiagState(FME_enPedalTransfer, SENSORS_u16TPSSafeMaxModified, + TPS_tSensorVolts); + } +#endif //BUILD_FME + + SENSORS_u32RunCounter++; +} + +void SENSORS_vInvalidateCAN16Data(uint32 u32MSGIDX, uint32 u32DataOffset) +{ + IOAPI_tenEHIOResource enEHIOResource; + puint8 pu8CANDataBuffer; + enEHIOResource = EH_VIO_CAN1; + + USER_vSVC(SYSAPI_enGetRawCommsBuffer, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + pu8CANDataBuffer = (puint8)pstSVCDataStruct->pvArg1; + pu8CANDataBuffer += (8 * u32MSGIDX); + pu8CANDataBuffer += u32DataOffset; + memset(pu8CANDataBuffer, 0xff, 2); + } +} + +static void SENSORS_vGetCANSensorData() +{ + IOAPI_tenEHIOResource enEHIOResource; + uint8* pu8CANDataBuffer = {0}; + enEHIOResource = EH_VIO_CAN1; + uint16 u16Temp; + sint16 s16Temp; + sint32 s32Temp; + static uint8 u8OldGear; + static uint8 u8OldDistCount; + static sint16 s16OldDistance; + + USER_vSVC(SYSAPI_enGetRawCommsBuffer, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + pu8CANDataBuffer = (puint8)pstSVCDataStruct->pvArg1; + } + + if (NULL != pu8CANDataBuffer) + { + SENSORS_boCANNewGearPositionSample = pu8CANDataBuffer[11] != 0xff; + + if (TRUE == SENSORS_boCANNewGearPositionSample) + { + switch ((pu8CANDataBuffer[11] & 0xf0) >> 4) + { + case 8: DIAG_u8GearSelectorReport = 0; break; + case 7: DIAG_u8GearSelectorReport = 1; break; + case 6: DIAG_u8GearSelectorReport = 2; break; + case 5: DIAG_u8GearSelectorReport = 3; break; + case 12: DIAG_u8GearSelectorReport = 4; break; + case 10: DIAG_u8GearSelectorReport = 5; break; + case 11: DIAG_u8GearSelectorReport = 6; break; + default: DIAG_u8GearSelectorReport = 15; break; + } + + SENSORS_boCANNewGearPositionSample = FALSE; + } + + + SENSORS_boCANNewBrakePressedSample = pu8CANDataBuffer[30] != 0xff; + + if (TRUE == SENSORS_boCANNewBrakePressedSample) + { + SENSORS_boBrakePedalPressed = 0 != (pu8CANDataBuffer[30] & 0x40); + SENSORS_boCANNewBrakePressedSample = FALSE; + } + + /* Check CAN torque reduction requests */ + SENSORS_boCANNewTorqueRequestSample = pu8CANDataBuffer[19] != 0xff; + + if (TRUE == SENSORS_boCANNewTorqueRequestSample) + { + if ((0xf & pu8CANDataBuffer[18]) != u8OldGear) + { + TORQUE_u8ATXSelectedGear = 0xf & pu8CANDataBuffer[18]; + TORQUE_boDownShift = u8OldGear > (0xf & pu8CANDataBuffer[18]) ? TRUE : FALSE; + u8OldGear = 0xf & pu8CANDataBuffer[18]; + TORQUE_u16GearShiftCount = USERCAL_stRAMCAL.u16ShiftCountLimit; + TORQUE_u16GearShiftPressureControlCount = USERCAL_stRAMCAL.u16ShiftCountPressureControlLimit; + } + else + { + TORQUE_u16GearShiftCount = 0 != TORQUE_u16GearShiftCount ? TORQUE_u16GearShiftCount - 1 : 0; + TORQUE_u16GearShiftPressureControlCount = 0 != TORQUE_u16GearShiftPressureControlCount ? + TORQUE_u16GearShiftPressureControlCount - 1 : 0; + } + + if (0x80 == (0x80 & pu8CANDataBuffer[19])) + { + if (0 != TORQUE_u16GearShiftCount) + { + /* DSG torque reduction request */ + if (EST_nIgnitionReqDSGCutsStage3 != EST_enIgnitionTimingRequest) + { + EST_enIgnitionTimingRequest = EST_nIgnitionReqDSGStage2; + } + } + } + else if (0x05 == (0x05 & pu8CANDataBuffer[19])) + { + /* DSG torque reduction request */ + EST_enIgnitionTimingRequest = EST_nIgnitionReqDSGStage1; + } + else + { + /* DSG normal */ + EST_enIgnitionTimingRequest = EST_nIgnitionReqPrimary; + } + + TORQUE_u32ATXTorqueLimit = pu8CANDataBuffer[16]; + } + + /* Get power mode */ + u16Temp = pu8CANDataBuffer[0] + (pu8CANDataBuffer[1] << 8); + + if (DIAG_u16PowerModeCode != u16Temp) + { + DIAG_u8PowerModeActive = TRUE; + DIAG_u16PowerModeActiveCount = 200; + DIAG_u16PowerModeCode = u16Temp; + } + else + { + DIAG_u16PowerModeActiveCount = 0 < DIAG_u16PowerModeActiveCount ? + DIAG_u16PowerModeActiveCount - 1 : DIAG_u16PowerModeActiveCount; + + DIAG_u8PowerModeActive = 0 < DIAG_u16PowerModeActiveCount; + } + + /* Get VSS */ + if (u8OldDistCount != (0x80 & pu8CANDataBuffer[8])) + { + u8OldDistCount = 0x80 & pu8CANDataBuffer[8]; + + s16Temp = pu8CANDataBuffer[13] * 0x100 + pu8CANDataBuffer[14]; + + if (s16Temp >= s16OldDistance) + { + s32Temp = (sint32)s16Temp - (sint32)s16OldDistance; + } + else if (s16Temp < s16OldDistance) + { + s32Temp = (sint32)s16Temp - (sint32)s16OldDistance; + s32Temp += 2048; + } + + s32Temp *= USERCAL_stRAMCAL.u16VSSCANCal; + s32Temp /= 100; + + s32Temp = 0x10000 > s32Temp ? s32Temp : 0xffff; + SENSORS_u16CANVSS = ((uint16)s32Temp / 2) + (SENSORS_u16CANVSS / 2); + + s16OldDistance = s16Temp; + } + + + + /* Calculate gear */ + + /* Calculate km/h per 1000 rpm */ + s32Temp = SENSORS_u16CANVSS * 1000 / CAM_u32RPMFiltered; + + /* Default to no gear */ + SENSORS_u8VSSCalcGear = 0; + SENSORS_u16VSSCalcGearRPMSlip = 65535; + + for (u16Temp = 0; u16Temp < 8; u16Temp++) + { + s16Temp = (sint16)s32Temp - USERCAL_stRAMCAL.u16VSSPerRPM[u16Temp]; + + if ((USERCAL_stRAMCAL.u16VSSPerRPM[0] / 4) > (ABS(s16Temp))) + { + /* If small error then this is correct gear */ + SENSORS_u8VSSCalcGear = u16Temp + 1; + + /* Calculate RPM slip */ + s32Temp = (1000 * SENSORS_u16CANVSS) / USERCAL_stRAMCAL.u16VSSPerRPM[u16Temp]; + s32Temp -= (sint32)CAM_u32RPMFiltered; + s32Temp = ABS(s32Temp); + + SENSORS_u16VSSCalcGearRPMSlip = (uint16)s32Temp; + break; + } + } + } +} + + +void SENSORS_vTerminate(puint32 const pu32Arg) +{ + +} + + +void SENSORS_vCallBack(puint32 const pu32Arg) +{ + +} + +static void SENSORS_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult) +{ + sint32 s32Temp; + + if (USERCAL_stRAMCAL.u16AFRADResource == enEHIOResource) + { + s32Temp = USERCAL_stRAMCAL.s32AFRADInputGain * (sint32)u32ADCResult; + s32Temp /= 1000; + s32Temp += USERCAL_stRAMCAL.s32AFRADInputOffset; + CLO2_au16AFRMeasured[0] = (uint32)s32Temp; + s32Temp *= (sint32)USERCAL_stRAMCAL.u16AFRFuelTypeGain; + s32Temp /= 1000; + + if (65536 > s32Temp) + { + CLO2_au16AFRDisplayMeasured[0] = (uint16)(s32Temp); + } + else + { + CLO2_au16AFRDisplayMeasured[0] = 0xffff; + } + } + else if (USERCAL_stRAMCAL.u16PPSMADResource == enEHIOResource) + { + SENSORS_au16ADSensorValue[SENSORS_enADPPSM] = u32ADCResult; + } + else if (USERCAL_stRAMCAL.u16PPSSADResource == enEHIOResource) + { + SENSORS_au16ADSensorValue[SENSORS_enADPPSS] = u32ADCResult; + } + else if (USERCAL_stRAMCAL.au16AuxInputResource[0] == enEHIOResource) + { + SENSORS_au16ADSensorValue[SENSORS_enAUX1] = (uint16)u32ADCResult; + } + else if (USERCAL_stRAMCAL.au16AuxInputResource[1] == enEHIOResource) + { + SENSORS_au16ADSensorValue[SENSORS_enAUX2] = (uint16)u32ADCResult; + } + else if (USERCAL_stRAMCAL.au16AuxInputResource[2] == enEHIOResource) + { + SENSORS_au16ADSensorValue[SENSORS_enAUX3] = (uint16)u32ADCResult; + } + else if (USERCAL_stRAMCAL.au16AuxInputResource[3] == enEHIOResource) + { + SENSORS_au16ADSensorValue[SENSORS_enAUX4] = (uint16)u32ADCResult; + } +} + +static void SENSORS_vCEMCallBack(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime) +{ + uint32 u32Hertz; + uint32 u32Temp; + static uint32 au32Hertz[SENSORS_nAFMHertzSamples]; + static uint32 u32HertzSampleIDX; + + + switch (enEHIOResource) + { + case CRANK_nInput: + { + CAM_vEngineSpeedCB(tEventTime); + break; + } +#ifdef BUILD_BSP_AFM_FREQ + case AFM_FREQ_nInput: + { + au32Hertz[u32HertzSampleIDX] = (uint32)SENSORS_nSlowFTMFreq / tEventTime; + u32Hertz = USERMATH_u32DiscardAndAverage32(au32Hertz, SENSORS_nAFMHertzSamples, 1); + + u32Temp = 20 + (TPS_tThetaFiltered / 1500); + + if ((AFM_tSensorHertz + u32Temp) < u32Hertz) + { + AFM_tSensorHertz += u32Temp; + } + else if (((AFM_tSensorHertz - u32Temp) > u32Hertz) && + (100u < AFM_tSensorHertz)) + { + AFM_tSensorHertz -= u32Temp; + } + else + { + AFM_tSensorHertz = u32Hertz; + } + + u32HertzSampleIDX = (u32HertzSampleIDX + 1) % SENSORS_nAFMHertzSamples; + + break; + } +#endif //BUILD_BSP_AFM_FREQ + default: + { + break; + } + } +} + +bool SENSORS_boGetAuxActive(SENSORS_tenAUXConfig enAUXConfig) +{ + uint32 u32IDX; + bool boFound = FALSE; + bool boActiveLow; + bool boActive = FALSE; + + for (u32IDX = 0; u32IDX < SENSORS_nAuxChannelCount; u32IDX++) + { + if (USERCAL_stRAMCAL.au16AuxInputFunction[u32IDX] == enAUXConfig) + { + boFound = TRUE; + break; + } + } + + if (TRUE == boFound) + { + boActiveLow = (0 == (USERCAL_stRAMCAL.au16AuxInputFunction[u32IDX] & 1)); + + if (TRUE == boActiveLow) + { + boActive = !SENSORS_aboAUXActive[u32IDX + SENSORS_enAUX1]; + } + else + { + boActive = SENSORS_aboAUXActive[u32IDX + SENSORS_enAUX1]; + } + } + + return boActive; +} + + +#endif //BUILD_USER diff --git a/source/Client/SENSORS.h b/source/Client/SENSORS.h new file mode 100644 index 0000000..cc4d6e5 --- /dev/null +++ b/source/Client/SENSORS.h @@ -0,0 +1,217 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Sensors Header */ +/* DESCRIPTION: This code manages the sensors AD conversions */ +/* */ +/* */ +/* FILE NAME: SENSORS.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef SENSORS_H +#define SENSORS_H + +#include +#include "CONV.h" +#include "IOAPI.h" +#include "USER.h" +#include "SYS.h" +#include "TEPMAPI.h" + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +typedef enum +{ + SENSORS_enADAFR, + SENSORS_enADPPSM, + SENSORS_enADPPSS, + SENSORS_enAUX1, + SENSORS_enAUX2, + SENSORS_enAUX3, + SENSORS_enAUX4, + SENSORS_enADInvalid, + SENSORS_enADCount +} SENSORS_tenADConfig; + +typedef enum +{ + SENSORS_enAUX_OFF = 0, + SENSORS_enAUX_SECONDARY_Timing_Map_LOW = 2 , + SENSORS_enAUX_SECONDARY_Timing_Map_HIGH = 3, + SENSORS_enAUX_SECONDARY_TAFR_Map_LOW = 4, + SENSORS_enAUX_SECONDARY_TAFR_Map_HIGH = 5, + SENSORS_enAUX_ANTILAG_LOW = 6, + SENSORS_enAUX_ANTILAG_HIGH = 7, + SENSORS_enAUX_DRAG_MODE_LOW = 8, + SENSORS_enAUX_DRAG_MODE_HIGH = 9, + SENSORS_enAUX_LAUNCH_LOW = 10, + SENSORS_enAUX_LAUNCH_HIGH = 11, +} SENSORS_tenAUXConfig; + +#define SENSORS_nFastPeriod (2u) +#define SENSORS_nSlowPeriod (8u) +#define SENSORS_nADScaleMax (4095u) +#define SENSORS_nSensorsRefVolts (5000u) +#define SENSORS_nADRefVolts (3300u) +#define SENSORS_nVDivRatio (128u) /* 1/2 voltage divider for 3.3V ECUHost */ +#define SENSORS_nFastFTMDivisor TEPMAPI_enDiv128 +#define SENSORS_nFastFTMFreq (SYS_FREQ_BUS / (1 << SENSORS_nFastFTMDivisor)) +#define SENSORS_nSlowFTMDivisor TEPMAPI_enDiv128 +#define SENSORS_nSlowFTMFreq (SYS_FREQ_BUS / (1 << SENSORS_nSlowFTMDivisor)) +#define SENSORS_nAFMHertzSamples (5) +#define SENSORS_nSENSORADMAX (2850) + +#ifdef BUILD_SPARKDOG_PF +#define VRA_nPullupEnablePin EH_IO_GP2 +#define VRB_nPullupEnablePin EH_IO_UART2_TX +#define VRA_nVREnablePin EH_IO_UART2_RX +#define VRB_nVREnablePin EH_IO_GPSE7 +#define VR_nHystHighPin EH_IO_GP7 +#define VR_nHystLowPin EH_IO_GP1 +#define VR_nPhaseTelltalePin EH_IO_GP10 +#define VVTAB_nPullupEnablePin EH_IO_IIC1_SDA +#define VVTCD_nPullupEnablePin EH_IO_IIC1_SCL +#endif //BUILD_SPARKDOG_PF + +#ifdef BUILD_SPARKDOG_TEENSY_ADAPT +#define VRA_nPullupEnablePin EH_IO_GP11 +#define VRB_nPullupEnablePin EH_IO_UART2_TX +#define VRA_nVREnablePin EH_IO_UART2_RX +#define VRB_nVREnablePin EH_IO_GPSE7 +#define VR_nHystHighPin EH_IO_GP13 +#define VR_nHystLowPin EH_IO_GP12 +#define VR_nPhaseTelltalePin EH_IO_GP10 +#define VVTAB_nPullupEnablePin EH_IO_IIC1_SDA +#define VVTCD_nPullupEnablePin EH_IO_IIC1_SCL +#endif //BUILD_SPARKDOG_TEENSY_ADAPT + + +#ifdef BUILD_SPARKDOG_PF +#define CRANK_nInput EH_IO_TMR11 +#endif //BUILD_SPARKDOG_PF + +#ifdef BUILD_SPARKDOG_TEENSY_ADAPT +#define CRANK_nInput EH_IO_TMR10 +#endif //BUILD_SPARKDOG_TEENSY_ADAPT + +#ifdef BUILD_BSP_AFM_FREQ + +#ifdef BUILD_SPARKDOG_PF +#define AFM_FREQ_nInput EH_IO_TMR10 +#endif //BUILD_SPARKDOG_PF + +#ifdef BUILD_SPARKDOG_TEENSY_ADAPT +#define AFM_FREQ_nInput EH_IO_TMR11 +#endif //BUILD_SPARKDOG_TEENSY_ADAPT + +#endif //BUILD_BSP_AFM_FREQ + +//#define CTS_nSwitchPin EH_IO_GPSE1 + +#if 0 +#define CLO2_nSwitchBank1Pin EH_IO_GPSE2 +#define CLO2_nSwitchBank2Pin EH_IO_GPSE3 +#define CLO2_nOxBank2Pin EH_IO_GPSE4 +#define CLO2_nOxBank1Pin EH_IO_GPSE5 +#endif + +//#define CAM_nDebug EH_IO_GPSE1 + +#define SENSORS_nOBDSTT1PID 6 +#define SENSORS_nOBDLTT1PID 7 +#define SENSORS_nOBDSTT2PID 8 +#define SENSORS_nOBDLTT2PID 9 +#define SENSORS_nOBDESTADVPID 14 +#define SENSORS_nAuxChannelCount 4 +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _SENSORS_C + #define EXTERN +#else + #define EXTERN extern +#endif + +#define SENSORS_nCANBufferMap \ +{3,2,1,0,7,6,5,4,8+3,8+2,8+1,8+0,8+7,8+6,8+5,8+4,16+3,16+2,16+1,16+0,16+7,16+6,16+5,16+4,24+3,24+2,24+1,24+0,24+7,24+6,24+5,24+4} + +#define PPSM_RAMP_MAX_NEG 25 +#define PPSM_RAMP_MAX_POS 100 + + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +EXTERN bool SENSORS_boCTSACBiasHigh; +EXTERN uint8 SENSORS_u8CANCTS; +//ASAM mode=readvalue name="CAN CTS" type=uint8 offset=0 min=0 max=255 m=1 b=0 units="dl" format=3.0 help="CTS CAN" +EXTERN uint8 SENSORS_u8CANATS; +//ASAM mode=readvalue name="CAN ATS" type=uint8 offset=0 min=0 max=255 m=1 b=0 units="dl" format=3.0 help="ATS CAN" +EXTERN uint16 SENSORS_u16CANTPS; +//ASAM mode=readvalue name="CAN TPS" type=uint16 offset=0 min=0 max=65535 m=1 b=0 units="dl" format=5.0 help="TPS CAN" +EXTERN uint8 SENSORS_u8CANPPS; +//ASAM mode=readvalue name="CAN PPS" type=uint8 offset=0 min=0 max=255 m=1 b=0 units="dl" format=3.0 help="PPS CAN" +EXTERN uint16 SENSORS_u16CANVSS; +//ASAM mode=readvalue name="CAN VSS" type=uint16 offset=0 min=0 max=65535 m=1 b=0 units="dl" format=3.0 help="VSS CAN" +EXTERN uint16 SENSORS_au16CANAFR[2]; +//ASAM mode=readvalue name="CAN AFR" type=uint16 offset=0 min=0 max=65535 m=1 b=0 units="dl" format=3.0 help="VSS AFR" +EXTERN uint8 SENSORS_u8CANSTT[2]; + + + +EXTERN uint8 SENSORS_u8CANLTT[2]; + +EXTERN uint8 SENSORS_u8OBDAdv; + +EXTERN bool SENSORS_boBrakePedalPressed; + +EXTERN bool SENSORS_boCANCTSNewSample; +EXTERN bool SENSORS_boCANATSNewSample; +EXTERN bool SENSORS_boCANTPSNewSample; +EXTERN bool SENSORS_boCANPPSNewSample; +EXTERN bool SENSORS_boCANVSSNewSample; +EXTERN bool SENSORS_aboCANUEGONewSample[2]; +EXTERN bool SENSORS_boOBDAdvNewSample; +EXTERN bool SENSORS_boCANNewBrakePressedSample; +EXTERN bool SENSORS_boCANNewGearPositionSample; +EXTERN bool SENSORS_boCANNewTorqueRequestSample; + +EXTERN uint32 SENSORS_u32PPSMVolts; +//ASAM mode=readvalue name="PPSM Voltage" type=uint16 offset=0 min=0 max=5 m=0.001 b=0 units="V" format=3.2 help="PPSM Voltage" +EXTERN uint16 SENSORS_u16TPSSafeMax; +EXTERN uint16 SENSORS_u16TPSSafeMaxModified; +EXTERN uint16 SENSORS_u16CANVSS; +//ASAM mode=readvalue name="CAN VSS" type=uint16 offset=0 min=0 max=300 m=0.1 b=0 units="km/h" format=4.1 help="CAN Vehicle Speed" +EXTERN uint8 SENSORS_u8VSSCalcGear; +//ASAM mode=readvalue name="Calculated Gear" type=uint8 offset=0 min=0 max=255 m=1 b=0 units="dl" format=1.0 help="VSS Calculated Gear" +EXTERN uint16 SENSORS_u16VSSCalcGearRPMSlip; +//ASAM mode=readvalue name="Calculated Gear RPM Slip" type=uint16 offset=0 min=0 max=65535 m=1 b=0 units="RPM" format=4.0 help="VSS Calculated Gear RPM Slip" +EXTERN uint32 SENSORS_u32PPSMVoltsRamp; + +EXTERN uint16 SENSORS_au16ADSensorValueFiltered[SENSORS_enADCount]; +//ASAM mode=readvalue name="AFR Voltage" type=uint16 offset=0 min=0 max=10 m=0.001 b=0 units="V" format=3.2 help="AFR Filtered Voltage" +//ASAM mode=readvalue name="PPSM Voltage" type=uint16 offset=2 min=0 max=10 m=0.001 b=0 units="V" format=3.2 help="AFR Filtered Voltage" +//ASAM mode=readvalue name="PPSS Voltage" type=uint16 offset=4 min=0 max=10 m=0.001 b=0 units="V" format=3.2 help="AFR Filtered Voltage" +//ASAM mode=readvalue name="AUX1 Voltage" type=uint16 offset=6 min=0 max=10 m=0.001 b=0 units="V" format=3.2 help="AUX1 Filtered Voltage" +//ASAM mode=readvalue name="AUX2 Voltage" type=uint16 offset=8 min=0 max=10 m=0.001 b=0 units="V" format=3.2 help="AUX2 Filtered Voltage" +//ASAM mode=readvalue name="AUX3 Voltage" type=uint16 offset=10 min=0 max=10 m=0.001 b=0 units="V" format=3.2 help="AUX3 Filtered Voltage" +//ASAM mode=readvalue name="AUX4 Voltage" type=uint16 offset=12 min=0 max=10 m=0.001 b=0 units="V" format=3.2 help="AUX4 Filtered Voltage" + +EXTERN bool SENSORS_aboAUXActive[SENSORS_enADCount]; +//ASAM mode=readvalue name="AUX1 State" type=uint8 offset=3 min=0 max=1 units="ENUMERATION LOW=0 HIGH=1" format=3.0 help="AUX1 State" +//ASAM mode=readvalue name="AUX2 State" type=uint8 offset=4 min=0 max=1 units="ENUMERATION LOW=0 HIGH=1" format=3.0 help="AUX2 State" +//ASAM mode=readvalue name="AUX3 State" type=uint8 offset=5 min=0 max=1 units="ENUMERATION LOW=0 HIGH=1" format=3.0 help="AUX3 State" +//ASAM mode=readvalue name="AUX4 State" type=uint8 offset=6 min=0 max=1 units="ENUMERATION LOW=0 HIGH=1" format=3.0 help="AUX4 State" + + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void SENSORS_vStart(uint32 * const pu32Arg); +void SENSORS_vRun(uint32* const pu32Arg); +void SENSORS_vTerminate(uint32* const pu32Arg); +void SENSORS_vCallBack(puint32 const pu32Arg); +bool SENSORS_boSetupADSE(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tenEHIOType enEHIOType, ADCAPI_tenSamplesAv enSamplesAv, ADCAPI_tpfResultCB pfResultCB, ADCAPI_tenTrigger enTrigger, puint32 pu32Arg); +void SENSORS_vInvalidateCAN16Data(uint32 u32MSGIDX, uint32 u32DataOffset); +bool SENSORS_boGetAuxActive(SENSORS_tenAUXConfig enAUXConfig); + +#endif // CTS_H + diff --git a/source/Client/SETUP.c b/source/Client/SETUP.c new file mode 100644 index 0000000..3e3989b --- /dev/null +++ b/source/Client/SETUP.c @@ -0,0 +1,199 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Setup */ +/* DESCRIPTION: This code assist with the setup of kernel managed */ +/* resources */ +/* */ +/* FILE NAME: SETUP.c */ +/* REVISION HISTORY: 14-04-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _SETUP_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "SETUP.h" +#include "diag.h" + + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ + + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ + + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +bool SETUP_boSetupADSE(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tenEHIOType enEHIOType, ADCAPI_tenSamplesAv enSamplesAv, ADCAPI_tpfResultCB pfResultCB, ADCAPI_tenTrigger enTrigger, puint32 pu32Arg) +{ + bool boRetVal = FALSE; + ADCAPI_tstADCCB stADCCB; + + stADCCB.enSamplesAv = enSamplesAv; + stADCCB.enDiffGain = ADCAPI_enDiffGain1; + stADCCB.pfResultCB = pfResultCB; + stADCCB.enTrigger = enTrigger; + + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stADCCB); + + if (SYSAPI_enOK != pstSVCDataStruct->enSVCResult) + { + *pu32Arg |= (uint32)SYSAPI_enResourceRequestFailed;/*CR1_13*/ + } + else + { + boRetVal = TRUE; + } + } + else + { + *pu32Arg |= (uint32)SYSAPI_enResourceInitFailed;/*CR1_13*/ + } + + return boRetVal; +} + +TABLEAPI_ttTableIDX SETUP_tSetupTable(void* pvTableData, void* pvOutputData, TYPE_tenDataType enDataType, sint16 s16TableSize, SPREADAPI_ttSpreadIDX tSpreadIDX, TABLEAPI_pfPIDResultCB pfResultCB) +{ + TABLEAPI_tstTableCB stTableCB; + TABLEAPI_ttTableIDX tTableIDX; + + /* Request and initialise required Kernel managed tables */ + stTableCB.pvTableData = pvTableData; + stTableCB.pvOutputData = pvOutputData; + stTableCB.enDataType = enDataType; + stTableCB.i16TableSize = s16TableSize; + stTableCB.tSpreadIDX = tSpreadIDX; + stTableCB.pfResultCB = NULL; + + USER_vSVC(SYSAPI_enInitialiseTableResource, (void*)&stTableCB, NULL, NULL); + tTableIDX = (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) ? + (TABLEAPI_ttTableIDX)pstSVCDataStruct->tClientHandle : -1; + + return tTableIDX; +} + +MAPSAPI_ttMapIDX SETUP_tSetupMap(void* pvMapData, void* pvOutputData, TYPE_tenDataType enDataType, sint16 s16MapSizeX, sint16 s16MapSizeY, SPREADAPI_ttSpreadIDX tSpreadIDXX, SPREADAPI_ttSpreadIDX tSpreadIDXY,TABLEAPI_pfPIDResultCB pfResultCB) +{ + MAPSAPI_tstMapCB stMapCB; + MAPSAPI_ttMapIDX tMapIDX; + + /* Request and initialise required Kernel managed tables */ + stMapCB.pvMapData = pvMapData; + stMapCB.pvOutputData = pvOutputData; + stMapCB.enDataType = enDataType; + stMapCB.i16MapSizeX = s16MapSizeX; + stMapCB.i16MapSizeY = s16MapSizeY; + stMapCB.tSpreadIDXX = tSpreadIDXX; + stMapCB.tSpreadIDXY = tSpreadIDXY; + stMapCB.pfResultCB = NULL; + + USER_vSVC(SYSAPI_enInitialiseMapResource, (void*)&stMapCB, NULL, NULL); + tMapIDX = (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) ? + (MAPSAPI_ttMapIDX)pstSVCDataStruct->tClientHandle : -1; + + return tMapIDX; +} + +SPREADAPI_ttSpreadIDX SETUP_tSetupSpread(void* pvSourceData, void* pvSpreadData, TYPE_tenDataType enDataType, sint16 s16SpreadSize, SPREADAPI_tenSpreadRate enSpreadRate, SPREADAPI_pfPIDResultCB pfResultCB) +{ + SPREADAPI_tstSpreadCB stSpreadCB; + SPREADAPI_ttSpreadIDX tSpreadIDX; + USERDIAG_tstSpreadIDXAddressPair stSpreadIDXAddressPair; + + stSpreadCB.pvSourceData = pvSourceData; + stSpreadCB.pvSpreadData = pvSpreadData; + stSpreadCB.enDataType = enDataType; + stSpreadCB.s16SpreadSize = s16SpreadSize; + stSpreadCB.enSpreadRate = enSpreadRate; + stSpreadCB.pfResultCB = pfResultCB; + + USER_vSVC(SYSAPI_enInitialiseSpreadResource, (void*)&stSpreadCB, NULL, NULL); + tSpreadIDX = (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) ? + (SPREADAPI_ttSpreadIDX)pstSVCDataStruct->tClientHandle : -1; + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + stSpreadIDXAddressPair.pData = pvSpreadData; + stSpreadIDXAddressPair.tSpreadIDX = tSpreadIDX; + USERDIAG_vAddIDXAddressPair(&stSpreadIDXAddressPair); + } + + return tSpreadIDX; +} + +void SETUP_vSetupDigitalIO(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tenEHIOType enEHIOType, IOAPI_tenDriveStrength enDriveStrength, puint32 pu32Arg) +{ + if (EH_IO_Invalid != enEHIOResource) + { + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&enDriveStrength); + + if (SYSAPI_enOK != pstSVCDataStruct->enSVCResult) + { + *pu32Arg |= (uint32)SYSAPI_enResourceRequestFailed;/*CR1_13*/ + } + } + else + { + *pu32Arg |= (uint32)SYSAPI_enResourceInitFailed;/*CR1_13*/ + } + } + else + { + *pu32Arg |= (uint32)SYSAPI_enResourceInitFailed;/*CR1_13*/ + } +} + + +void SETUP_vSetDigitalIOHigh(IOAPI_tenEHIOResource enEHIOResource) +{ + IOAPI_tenTriState enTriState = IOAPI_enHigh; + + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, + (void*)&enTriState, (void*)NULL); +} + +void SETUP_vSetDigitalIOLow(IOAPI_tenEHIOResource enEHIOResource) +{ + IOAPI_tenTriState enTriState = IOAPI_enLow; + + USER_vSVC(SYSAPI_enAssertDIOResource, (void*)&enEHIOResource, + (void*)&enTriState, (void*)NULL); +} + +bool SETUP_vGetDigitalIO(IOAPI_tenEHIOResource enEHIOResource) +{ + bool boResult; + + USER_vSVC(SYSAPI_enGetDIOResource, (void*)&enEHIOResource, + (void*)NULL, (void*)NULL); + + boResult = *(bool*)pstSVCDataStruct->pvArg1; + + return boResult; +} + +void SETUP_vSetupSimpleCamSync(IOAPI_tenEHIOResource enEHIOResource, bool boCamSyncHighLate, uint32 u32CamSyncSampleToothCount) +{ + USER_vSVC(SYSAPI_enSetupSimpleCamSync, (void*)&enEHIOResource, + (void*)&boCamSyncHighLate, (void*)&u32CamSyncSampleToothCount); +} + +#endif //BUILD_USER diff --git a/source/Client/SETUP.h b/source/Client/SETUP.h new file mode 100644 index 0000000..e6c955f --- /dev/null +++ b/source/Client/SETUP.h @@ -0,0 +1,44 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Setup Header */ +/* DESCRIPTION: This code assist with the setup of kernel managed */ +/* resources */ +/* */ +/* FILE NAME: SETUP.c */ +/* REVISION HISTORY: 14-04-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef SETUP_H +#define SETUP_H + +#include +#include "IOAPI.h" +#include "MAPSAPI.h" +#include "USER.h" +#include "SYS.h" +#include "SPREADSAPI.h" +#include "TABLESAPI.h" +#include "TEPMAPI.h" + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ + + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ + + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +bool SETUP_boSetupADSE(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tenEHIOType enEHIOType, ADCAPI_tenSamplesAv enSamplesAv, ADCAPI_tpfResultCB pfResultCB, ADCAPI_tenTrigger enTrigger, puint32 pu32Arg); +TABLEAPI_ttTableIDX SETUP_tSetupTable(void* pvTableData, void* pvOutputData, TYPE_tenDataType enDataType, sint16 s16TableSize, SPREADAPI_ttSpreadIDX tSpreadIDX, TABLEAPI_pfPIDResultCB pfResultCB); +MAPSAPI_ttMapIDX SETUP_tSetupMap(void* pvMapData, void* pvOutputData, TYPE_tenDataType enDataType, sint16 s16MapSizeX, sint16 s16MapSizeY, SPREADAPI_ttSpreadIDX tSpreadIDXX, SPREADAPI_ttSpreadIDX tSpreadIDXY,TABLEAPI_pfPIDResultCB pfResultCB); +SPREADAPI_ttSpreadIDX SETUP_tSetupSpread(void* pvSourceData, void* pvSpreadData, TYPE_tenDataType enDataType, sint16 s16SpreadSize, SPREADAPI_tenSpreadRate enSpreadRate, SPREADAPI_pfPIDResultCB pfResultCB); +void SETUP_vSetupDigitalIO(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tenEHIOType enEHIOType, IOAPI_tenDriveStrength enDriveStrength, puint32 pu32Arg); +void SETUP_vSetDigitalIOHigh(IOAPI_tenEHIOResource); +void SETUP_vSetDigitalIOLow(IOAPI_tenEHIOResource); +bool SETUP_vGetDigitalIO(IOAPI_tenEHIOResource); +void SETUP_vSetupSimpleCamSync(IOAPI_tenEHIOResource, bool, uint32); + +#endif // SETUP_H + diff --git a/source/Client/TORQUE.c b/source/Client/TORQUE.c new file mode 100644 index 0000000..cabceb1 --- /dev/null +++ b/source/Client/TORQUE.c @@ -0,0 +1,216 @@ + +/******************************************************************************/ +/* Copyright (c) 2020 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Torque Control Module */ +/* DESCRIPTION: This code module initialises the required ADC */ +/* resources and functions for throttle position */ +/* measurement */ +/* FILE NAME: TORQUE.c */ +/* REVISION HISTORY: 01-04-2020 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _TORQUE_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "TPS.h" +#include "SENSORS.h" +#include "usercal.h" +#include "EST.h" + + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +uint32 TORQUE_u32OutputTorqueEstimateScaled; +SPREADAPI_ttSpreadIDX TORQUE_tSpreadTorquePedalIDX; +TABLEAPI_ttTableIDX TORQUE_tTableTorquePedalIDX; +SPREADAPI_ttSpreadIDX TORQUE_tSpreadETCScaleIDX; +TABLEAPI_ttTableIDX TORQUE_tTableETCScaleIDX; + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ + + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void TORQUE_vStart(puint32 const pu32Arg) +{ + /* Request and initialise required Kernel managed spread for ETC scale function */ + TORQUE_tSpreadETCScaleIDX = SETUP_tSetupSpread((void*)&CAM_u32RPMFiltered, (void*)&USERCAL_stRAMCAL.aUserETCScaleSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for ETC scale function */ + TORQUE_tTableETCScaleIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserETCScaleTable, (void*)&TORQUE_u16ETCScale, TYPE_enUInt16, 17, TORQUE_tSpreadETCScaleIDX, NULL); +} + +void TORQUE_vRun(puint32 const pu32Arg) +{ + uint32 u32Temp; + static uint32 u32DSGCutsCount; + + + if (10000 < MAP_tKiloPaFiltered) + { + if (239000 > MAP_tKiloPaFiltered) + { + TORQUE_u32TorqueModelEstimateScaled = 2 * ((MAP_tKiloPaFiltered - 10000) / 7); + } + else + { + TORQUE_u32TorqueModelEstimateScaled = 65500; + } + } + else + { + TORQUE_u32TorqueModelEstimateScaled = 0; + } + + + if (26000 >= TPS_tThetaFiltered) + { + if (6000 < TPS_tThetaFiltered) + { + u32Temp = (TPS_tThetaFiltered - 6000) / 120; + } + else + { + u32Temp = 0; + } + } + else + { + u32Temp = 164 + (TPS_tThetaFiltered - 26000) / 700; + } + + if (20000 < MAP_tKiloPaFiltered) + { + if (122000 > MAP_tKiloPaFiltered) + { + TORQUE_u32OutputTorqueEstimate = u32Temp / 2 + ((MAP_tKiloPaFiltered - 20000) / 800); + } + else + { + TORQUE_u32OutputTorqueEstimate = u32Temp / 2 + 127; + } + } + else + { + TORQUE_u32OutputTorqueEstimate = u32Temp / 2; + } + + /* Calculate pedal percentage scaled */ + u32Temp = MAX(USERCAL_stRAMCAL.userCalPPSCalMin, SENSORS_u32PPSMVolts); + u32Temp = MIN(USERCAL_stRAMCAL.userCalPPSCalMax, u32Temp); + u32Temp -= USERCAL_stRAMCAL.userCalPPSCalMin; + + u32Temp *= TORQUE_nPPSRange; + u32Temp /= (USERCAL_stRAMCAL.userCalPPSCalMax - + USERCAL_stRAMCAL.userCalPPSCalMin); + + TORQUE_u32TorquePedalEstimateScaled = u32Temp; + + /* Apply ATX torque mode */ + if (EST_nIgnitionReqDSGStage1 == EST_enIgnitionTimingRequest) + { + TORQUE_u32ESTTorqueModifier = 160; + TORQUE_u32FuelTorqueModifier = 220; + + TORQUE_u32OutputTorqueModified = (TORQUE_u32OutputTorqueEstimate * + TORQUE_u32ESTTorqueModifier * + TORQUE_u32DBWTorqueModifier * + TORQUE_u32FuelTorqueModifier) / 0x1000000; + + u32DSGCutsCount = 0; + } + else if ((EST_nIgnitionReqDSGStage2 == EST_enIgnitionTimingRequest) || + (EST_nIgnitionReqDSGCutsStage3 == EST_enIgnitionTimingRequest)) + { + if (u32DSGCutsCount > USERCAL_stRAMCAL.u16TorqueReductionMaxDuration) + { + EST_enIgnitionTimingRequest = EST_nIgnitionReqDSGStage2; + } + else + { + u32DSGCutsCount++; + EST_enIgnitionTimingRequest = EST_nIgnitionReqDSGCutsStage3; + } + + TORQUE_u32FuelTorqueModifier = 200; + + TORQUE_u32OutputTorqueModified = (TORQUE_u32OutputTorqueEstimate * + TORQUE_u32ESTTorqueModifier * + TORQUE_u32DBWTorqueModifier * + TORQUE_u32FuelTorqueModifier) / 0x1000000; + + if ((TORQUE_u32ATXTorqueLimit - 20) < TORQUE_u32OutputTorqueModified) + { + TORQUE_u32ESTTorqueModifier--; + } + else if ((TORQUE_u32ATXTorqueLimit - 20) > TORQUE_u32OutputTorqueModified) + { + if (200 > TORQUE_u32ESTTorqueModifier) TORQUE_u32ESTTorqueModifier++; + } + } + else + { + TORQUE_u32OutputTorqueModified = TORQUE_u32OutputTorqueEstimate; + TORQUE_u32ESTTorqueModifier = 0x100; + TORQUE_u32DBWTorqueModifier = 0x100; + TORQUE_u32FuelTorqueModifier = 0x100; + TORQUE_u32IdleStabilisationTorque = 20; + u32DSGCutsCount = 0; + } + + /* Reverse lookup pedal from torque */ + TORQUE_u32OutputTorqueEstimateScaled = 100 * TORQUE_u32OutputTorqueEstimate; + + /* Lookup the current Torque Pedal */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&TORQUE_tTableTorquePedalIDX, + NULL, NULL); + + /* Calculate the current spread for ETC scale */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&TORQUE_tSpreadETCScaleIDX, + NULL, NULL); + + /* Lookup the current ETC scale */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&TORQUE_tTableETCScaleIDX, + NULL, NULL); + + /* Compute rev match RPM */ + if (0 != TORQUE_u16GearShiftCount) + { + if (TRUE == TORQUE_boDownShift) + { + if ((6 > TORQUE_u8ATXSelectedGear) && (0 < TORQUE_u8ATXSelectedGear)) + { + u32Temp = 1000 * SENSORS_u16CANVSS; + TORQUE_u16RevMatchRPM = (uint16)(u32Temp / USERCAL_stRAMCAL.u16VSSPerRPM[TORQUE_u8ATXSelectedGear - 1]); + } + } + else + { + TORQUE_u16RevMatchRPM = 1500; + } + } + else + { + TORQUE_u16RevMatchRPM = 1500; + } +} + +void TORQUE_vTerminate(puint32 const pu32Arg) +{ + +} + +void TORQUE_vCallBack(puint32 const pu32Arg) +{ + +} + + +#endif //BUILD_USER diff --git a/source/Client/TORQUE.h b/source/Client/TORQUE.h new file mode 100644 index 0000000..53afa66 --- /dev/null +++ b/source/Client/TORQUE.h @@ -0,0 +1,67 @@ +/******************************************************************************/ +/* Copyright (c) 2020 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Torque Control Module Header File */ +/* DESCRIPTION: This code module initialises the required ADC */ +/* resources and functions for torque control */ +/* */ +/* FILE NAME: TORQUE.c */ +/* REVISION HISTORY: 01-04-2020 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef TORQUE_H +#define TORQUE_H + +#include +#include "IOAPI.h" +#include "USER.h" +#include "USERCAL.h" + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ + + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _MAP_C + #define EXTERN +#else + #define EXTERN extern +#endif + +#define TORQUE_nPPSRange 25400 + + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +EXTERN uint32 TORQUE_u32ATXTorqueLimit; +EXTERN uint32 TORQUE_u32OutputTorqueModified; +EXTERN uint32 TORQUE_u32OutputTorqueEstimate; +//ASAM mode=readvalue name="Output Torque Estimate" type=uint32 offset=0 min=0 max=255 m=1 b=0 units="dl" format=3.1 help="Torque Estimate" + + +EXTERN uint32 TORQUE_u32ESTTorqueModifier; +EXTERN uint32 TORQUE_u32DBWTorqueModifier; +EXTERN uint32 TORQUE_u32FuelTorqueModifier; +EXTERN uint32 TORQUE_u32IdleStabilisationTorque; +EXTERN uint32 TORQUE_u32TorquePedalEstimateScaled; +EXTERN uint32 TORQUE_u32TorqueModelEstimateScaled; +EXTERN uint16 TORQUE_u16ETCScale; +EXTERN uint16 TORQUE_u16GearShiftCount; +//ASAM mode=readvalue name="Shift Control Count" type=uint16 offset=0 min=0 max=65535 m=1 b=0 units="dl" format=5.0 help="Shift Control Count" +EXTERN bool TORQUE_boDownShift; +EXTERN uint16 TORQUE_u16GearShiftPressureControlCount; +//ASAM mode=readvalue name="Shift Control Pressure Count" type=uint16 offset=0 min=0 max=65535 m=1 b=0 units="dl" format=5.0 help="Shift Control Pressure Count" +EXTERN uint8 TORQUE_u8ATXSelectedGear; +//ASAM mode=readvalue name="ATX Selected Gear" type=uint8 offset=0 min=0 max=255 m=1 b=0 units="dl" format=1.0 help="ATX Selected Gear" +EXTERN uint16 TORQUE_u16RevMatchRPM; +//ASAM mode=readvalue name="Rev Match RPM" type=uint16 offset=0 min=0 max=65535 m=1 b=0 units="RPM" format=4.0 help="Rev Match Downshift RPM" + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void TORQUE_vStart(uint32 * const pu32Arg); +void TORQUE_vRun(uint32* const pu32Arg); +void TORQUE_vTerminate(uint32* const pu32Arg); +void TORQUE_vCallBack(puint32 const pu32Arg); + +#endif // TORQUE_H diff --git a/source/Client/TPS.c b/source/Client/TPS.c new file mode 100644 index 0000000..91c5d73 --- /dev/null +++ b/source/Client/TPS.c @@ -0,0 +1,381 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Throttle Position Sensor */ +/* DESCRIPTION: This code module initialises the required ADC */ +/* resources and functions for throttle position */ +/* measurement */ +/* FILE NAME: TPS.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _TPS_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#ifdef BUILD_FME +#include "FME.h" +#endif //BUILD_FME + +#include "TPS.h" +#include "SENSORS.h" +#include "usercal.h" + + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +bool TPS_boNewSample; +const uint32 TPS_au32AreaVolRatio[] = TPS_nAreaVolRatioData; +const uint32 TPS_au32AngleSpread[] = TPS_nAngleSpreadData; +SPREADAPI_ttSpreadIDX TPS_tSpreadAreaVolRatioIDX; +TABLEAPI_ttTableIDX TPS_tAreaVolRatioTableIDX; +SPREADAPI_ttSpreadIDX TPS_tSpreadTPSMovingIDX; +TABLEAPI_ttTableIDX TPS_tTPSMovingTableIDX; +SPREADAPI_ttSpreadIDX TPS_tSpreadTipInIDX; +TABLEAPI_ttTableIDX TPS_tTipInTableIDX; +uint32 TPS_u32TipInEnrichmentLookup; + +/* LOCAL FUNCTION PROTOTYPES (STATIC) *****************************************/ +/******************************************************************************* +* Interface : TPS_vADCCallBack +* +* Implementation : Callback to receive the measured ADC value +* +* Parameter +* Par1 : enEHIOResource enum of the ADC resource +* Par2 : u32ADCResult the ADC conversion value +* +* Return Value : NIL +*******************************************************************************/ +static void TPS_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult); + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void TPS_vStart(puint32 const pu32Arg) +{ + IOAPI_tenEHIOResource enEHIOResource; + IOAPI_tenEHIOType enEHIOType; + ADCAPI_tstADCCB stADCCB; + + TPS_u32ADCRaw = 0; + TPS_tThetaRaw = 0; + TPS_tThetaFiltered = 0; + TPS_u32ManifoldVolumeTau = 0; + TPS_u32AreaVolRatio = 0; + TPS_boNewSample = FALSE; + TPS_u32ThrottleMovingCounter = 0; + + TPS_u32TipInEnrichment = 1000; + + enEHIOResource = USERCAL_stRAMCAL.u16TPSADResource; + enEHIOType = IOAPI_enADSE; + stADCCB.enSamplesAv = ADCAPI_en32Samples; + stADCCB.pfResultCB = &TPS_vADCCallBack; + stADCCB.enTrigger = ADCAPI_enTrigger4; + + USER_vSVC(SYSAPI_enRequestIOResource, (void*)&enEHIOResource, (void*)NULL, (void*)NULL); + + /* Request and initialise required Kernel managed spread for area volume ratio */ + TPS_tSpreadAreaVolRatioIDX = SETUP_tSetupSpread((void*)&TPS_tThetaRaw, (void*)&TPS_au32AngleSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for area volume ratio */ + TPS_tAreaVolRatioTableIDX = SETUP_tSetupTable((void*)&TPS_au32AreaVolRatio, (void*)&TPS_u32AreaVolRatio, TYPE_enUInt32, 17, TPS_tSpreadAreaVolRatioIDX, NULL); + + /* Request and initialise required Kernel managed spread for moving throttle enrichment */ + TPS_tSpreadTPSMovingIDX = SETUP_tSetupSpread((void*)&TPS_tThetaDerivativeNormalised, (void*)&USERCAL_stRAMCAL.aUserTPSMovementCorrectionSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for moving throttle enrichment */ + TPS_tTPSMovingTableIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserTPSMovementCorrectionTable, (void*)&TPS_u32MovingTPSEnrichment, TYPE_enUInt16, 17, TPS_tSpreadTPSMovingIDX, NULL); + + /* Request and initialise required Kernel managed spread for tip in throttle enrichment */ + TPS_tSpreadTipInIDX = SETUP_tSetupSpread((void*)&CAM_u32RPMFiltered, (void*)&USERCAL_stRAMCAL.aUserTipInCorrectionSpread, TYPE_enUInt32, 17, SPREADAPI_enSpread4ms, NULL); + + /* Request and initialise required Kernel managed table for tip in throttle enrichment */ + TPS_tTipInTableIDX = SETUP_tSetupTable((void*)&USERCAL_stRAMCAL.aUserTipInCorrectionTable, (void*)&TPS_u32TipInEnrichmentLookup, TYPE_enUInt16, 17, TPS_tSpreadTipInIDX, NULL); + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + USER_vSVC(SYSAPI_enInitialiseIOResource, (void*)&enEHIOResource, + (void*)&enEHIOType, (void*)&stADCCB); + + if (SYSAPI_enOK != pstSVCDataStruct->enSVCResult) + { + *pu32Arg |= (uint32)SYSAPI_enResourceRequestFailed;/*CR1_13*/ + } + } + else + { + *pu32Arg |= (uint32)SYSAPI_enResourceInitFailed;/*CR1_13*/ + } +} + +void TPS_vRun(puint32 const pu32Arg) +{ + uint32 u32Temp; + sint16 s16Temp; + sint32 s32Temp; + static GPM6_ttTheta TPS_tThetaRawOld; + static uint32 u32Count; + static sint32 s32SecondDerivativeLimitNeg = 0; + static sint32 s32SecondDerivativeLimitPos = 0; + static uint16 s16OldCANTPS; + + if (TRUE == USERCAL_stRAMCAL.boTPSCANPrimary) + { + if (TRUE == SENSORS_boCANTPSNewSample) + { + if (s16OldCANTPS == SENSORS_u16CANTPS) + { + TPS_u16CANTPSDeltaNegCount = 1 > TPS_u16CANTPSDeltaNegCount ? 0 : TPS_u16CANTPSDeltaNegCount - 1; + TPS_u16CANTPSDeltaPosCount = 1 > TPS_u16CANTPSDeltaPosCount ? 0 : TPS_u16CANTPSDeltaPosCount - 1; + } + else + { + s16Temp = SENSORS_u16CANTPS - s16OldCANTPS; + + if (0 > s16Temp) + { + s16Temp = ABS(s16Temp); + s16Temp = 5 > s16Temp ? 0 : s16Temp - 5; + s16Temp = 30 > s16Temp ? s16Temp : 30; + s16Temp *= 10; + TPS_u16CANTPSDeltaNegCount += s16Temp; + TPS_u16CANTPSDeltaNegCount = MIN(TPS_u16CANTPSDeltaNegCount, 200); + } + else + { + s16Temp = 5 > s16Temp ? 0 : s16Temp - 5; + s16Temp = 30 > s16Temp ? s16Temp : 30; + s16Temp *= 10; + TPS_u16CANTPSDeltaPosCount += s16Temp; + TPS_u16CANTPSDeltaPosCount = MIN(TPS_u16CANTPSDeltaPosCount, 200); + } + } + + /* Calculate CAN based throttle angle */ + u32Temp = SENSORS_u16CANTPS; + u32Temp = MAX(1750, u32Temp); + u32Temp = MIN(2500, u32Temp); + u32Temp -= 1750; + + u32Temp *= TPS_nAngleRange; + u32Temp /= 750; + + TPS_tThetaRaw = u32Temp; + + /* User can add filtering */ + TPS_tThetaPreFiltered = USERMATH_u32SinglePoleLowPassFilter32(TPS_tThetaRaw, 0x80, &TPS_tThetaPreFiltered); + + TPS_tThetaFiltered = TPS_tThetaPreFiltered; + + s16OldCANTPS = SENSORS_u16CANTPS; + SENSORS_boCANTPSNewSample = FALSE; + SENSORS_vInvalidateCAN16Data(1, 2); + } + } + else + { + if (TRUE == TPS_boNewSample) + { + /* Adding critical sections per code review but not actually needed yet */ + USER_xEnterCritical();/*CR1_16*/ + (void)USERMATH_u16SinglePoleLowPassFilter16((uint16)TPS_u32ADCRaw, TPS_nADFiltVal, + &TPS_u32ADCFiltered); + TPS_boNewSample = FALSE; + USER_xExitCritical();/*CR1_16*/ + +#ifdef BUILD_FME + FME_enUpdateDiagState(FME_enTPSMSingle, TPS_u32ADCFiltered / 0x100, 0); +#endif //BUILD_FME + + u32Temp = TPS_u32ADCFiltered * SENSORS_nADRefVolts; + u32Temp /= SENSORS_nADScaleMax; + u32Temp /= SENSORS_nVDivRatio; + + TPS_tSensorVolts = u32Temp; + + u32Temp = MAX(USERCAL_stRAMCAL.userCalTPSCalMin, TPS_tSensorVolts); + u32Temp = MIN(USERCAL_stRAMCAL.userCalTPSCalMax, u32Temp); + u32Temp -= USERCAL_stRAMCAL.userCalTPSCalMin; + + u32Temp *= TPS_nAngleRange; + u32Temp /= (USERCAL_stRAMCAL.userCalTPSCalMax - + USERCAL_stRAMCAL.userCalTPSCalMin); + + TPS_tThetaRaw = u32Temp; + + /* User can add filtering */ + TPS_tThetaPreFiltered = USERMATH_u32SinglePoleLowPassFilter32(TPS_tThetaRaw, 0x80, &TPS_tThetaPreFiltered); + + if (TPS_tThetaPreFiltered > TPS_tThetaFiltered) + { + /* New sample higher than pre-filter */ + if (s32SecondDerivativeLimitPos < (sint32)(TPS_tThetaPreFiltered - TPS_tThetaFiltered)) + { + s32SecondDerivativeLimitPos = TPS_nFirstDLimitPos > s32SecondDerivativeLimitPos ? s32SecondDerivativeLimitPos + TPS_nSecondDLimit : TPS_nFirstDLimitPos; + + if (s32SecondDerivativeLimitPos < (sint32)(TPS_tThetaPreFiltered - TPS_tThetaFiltered)) + { + TPS_tThetaFiltered += s32SecondDerivativeLimitPos; + } + else + { + TPS_tThetaFiltered = TPS_tThetaPreFiltered; + } + } + else + { + TPS_tThetaFiltered = TPS_tThetaPreFiltered; + } + + s32SecondDerivativeLimitNeg = 0 > s32SecondDerivativeLimitNeg ? s32SecondDerivativeLimitNeg + TPS_nSecondDLimit : 0; + s32SecondDerivativeLimitNeg = 0 > s32SecondDerivativeLimitNeg ? s32SecondDerivativeLimitNeg + TPS_nSecondDLimit : 0; + } + else if (TPS_tThetaPreFiltered < TPS_tThetaFiltered) + /* New sample lower than pre-filter */ + { + if (s32SecondDerivativeLimitNeg > (sint32)(TPS_tThetaPreFiltered - TPS_tThetaFiltered)) + { + s32SecondDerivativeLimitNeg = TPS_nFirstDLimitNeg < s32SecondDerivativeLimitNeg ? s32SecondDerivativeLimitNeg - TPS_nSecondDLimit : TPS_nFirstDLimitNeg; + TPS_tThetaFiltered += s32SecondDerivativeLimitNeg; + } + else + { + TPS_tThetaFiltered = TPS_tThetaPreFiltered; + } + + s32SecondDerivativeLimitPos = 0 < s32SecondDerivativeLimitPos ? s32SecondDerivativeLimitPos - TPS_nSecondDLimit : 0; + s32SecondDerivativeLimitPos = 0 < s32SecondDerivativeLimitPos ? s32SecondDerivativeLimitPos - TPS_nSecondDLimit : 0; + } + else + { + s32SecondDerivativeLimitPos = 0 < s32SecondDerivativeLimitPos ? s32SecondDerivativeLimitPos - TPS_nSecondDLimit : 0; + s32SecondDerivativeLimitNeg = 0 > s32SecondDerivativeLimitNeg ? s32SecondDerivativeLimitNeg + TPS_nSecondDLimit : 0; + s32SecondDerivativeLimitPos = 0 < s32SecondDerivativeLimitPos ? s32SecondDerivativeLimitPos - TPS_nSecondDLimit : 0; + s32SecondDerivativeLimitNeg = 0 > s32SecondDerivativeLimitNeg ? s32SecondDerivativeLimitNeg + TPS_nSecondDLimit : 0; + } + + TPS_tThetaFiltered = (uint32)0x7fffffff < TPS_tThetaFiltered ? 0 : TPS_tThetaFiltered; + + + /* Calculate the current spread for area volume ratio */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&TPS_tSpreadAreaVolRatioIDX, + NULL, NULL); + + /* Lookup the current table value for area volume ratio */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&TPS_tAreaVolRatioTableIDX, + NULL, NULL); + + u32Temp = USERCAL_stRAMCAL.u8ManifoldTimeConstantTrim * TPS_u32AreaVolRatio; + //u32Temp = 255 * TPS_u32AreaVolRatio; + TPS_u32ManifoldVolumeTau = u32Temp / 0x1000; + + /* Calculate throttle derivative */ + if (0 == (u32Count++ % TPS_nDerivCalcRate)) + { + s32Temp = (sint32)TPS_tThetaFiltered - (sint32)TPS_tThetaRawOld; + TPS_tThetaDerivative = s32Temp * (sint32)TPS_nRunRate; + TPS_tThetaDerivative /= (sint32)TPS_nDerivCalcRate; + + if ((150000 < TPS_tThetaDerivative) || (-150000 > TPS_tThetaDerivative)) + { + TPS_u32ThrottleMovingCounter = (TPS_nRunRate * TPS_nThrottleMovingCounterDurationMs) / (1000 * TPS_nDerivCalcRate); + } + else + { + TPS_u32ThrottleMovingCounter = 0 < TPS_u32ThrottleMovingCounter ? TPS_u32ThrottleMovingCounter - 1 : 0; + } + + TPS_tThetaRawOld = TPS_tThetaFiltered; + TPS_tThetaDerivativeNormalised = 0x80000000 + TPS_tThetaDerivative; + + /* Calculate the current spread for TPS movement enrichment */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&TPS_tSpreadTPSMovingIDX, + NULL, NULL); + + /* Lookup the current spread for TPS movement enrichment */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&TPS_tTPSMovingTableIDX, + NULL, NULL); + } + + if ((500 < s32SecondDerivativeLimitPos) || (-5000 > s32SecondDerivativeLimitNeg)) + { + TPS_u32ThrottleMovingCounter = (TPS_nRunRate * TPS_nThrottleMovingCounterDurationMs) / (1000 * TPS_nDerivCalcRate); + } + else + { + TPS_u32ThrottleMovingCounter = 0 < TPS_u32ThrottleMovingCounter ? TPS_u32ThrottleMovingCounter - 1 : 0; + } + } + } + + + if (TRUE == USERCAL_stRAMCAL.boPPSCANPrimary) + { + if (0xff != SENSORS_u8CANPPS) + { + TPS_boThrottleClosed = (0 == SENSORS_u8CANPPS) ? TRUE : TPS_boThrottleClosed; + TPS_boThrottleClosed = (1 < SENSORS_u8CANPPS) ? FALSE : TPS_boThrottleClosed; + } + else + { + TPS_boThrottleClosed = USERCAL_stRAMCAL.u32TPSClosedLower > TPS_tThetaFiltered ? TRUE : TPS_boThrottleClosed; + TPS_boThrottleClosed = USERCAL_stRAMCAL.u32TPSClosedUpper < TPS_tThetaFiltered ? FALSE : TPS_boThrottleClosed; + } + } + else + { + if (USERCAL_stRAMCAL.u32TPSClosedLower > TPS_tThetaFiltered) + { + TPS_boThrottleClosed = TRUE; + TPS_u32TipInEnrichment = 1000; + } + else if (USERCAL_stRAMCAL.u32TPSClosedUpper < TPS_tThetaFiltered) + { + if (TPS_boThrottleClosed == TRUE) + { + TPS_boThrottleClosed = FALSE; + + TPS_u32TransitionCounter = TPS_nTransitionCounterTipIn; + + /* Calculate the current spread for tip in enrichment */ + USER_vSVC(SYSAPI_enCalculateSpread, (void*)&TPS_tSpreadTipInIDX, + NULL, NULL); + + /* Lookup the current value for tip in enrichment */ + USER_vSVC(SYSAPI_enCalculateTable, (void*)&TPS_tTipInTableIDX, + NULL, NULL); + + if (TPS_u32TipInEnrichmentLookup > TPS_u32TipInEnrichment) + { + TPS_u32TipInEnrichment = TPS_u32TipInEnrichmentLookup; + } + } + } + } + + TPS_u32TransitionCounter = 0 < TPS_u32TransitionCounter ? TPS_u32TransitionCounter - 1 : 0; +} + +void TPS_vTerminate(puint32 const pu32Arg) +{ + +} + +void TPS_vCallBack(puint32 const pu32Arg) +{ + +} + +static void TPS_vADCCallBack(IOAPI_tenEHIOResource enEHIOResource, uint32 u32ADCResult) +{ + TPS_u32ADCRaw = u32ADCResult; + TPS_boNewSample = TRUE; +} + +#endif //BUILD_USER diff --git a/source/Client/TPS.h b/source/Client/TPS.h new file mode 100644 index 0000000..c620ff5 --- /dev/null +++ b/source/Client/TPS.h @@ -0,0 +1,117 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Throttle Position Sensor Header File */ +/* DESCRIPTION: This code module initialises the required ADC */ +/* resources and functions for throttle position */ +/* measurement */ +/* FILE NAME: TPS.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef TPS_H +#define TPS_H + +#include +#include "IOAPI.h" +#include "USER.h" +#include "USERCAL.h" + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define TPS_nADFiltVal (0x80) +#define TPS_nAngleRange (90000u) +#define TPS_nDerivCalcRate (20u) +#define TPS_nRunRate (1000u) +#define TPS_nThrottleMovingCounterDurationMs (500u) +#define TPS_nFirstDLimitPos (600u) +#define TPS_nFirstDLimitNeg (-600u) +#define TPS_nSecondDLimit (25u) + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _MAP_C + #define EXTERN +#else + #define EXTERN extern +#endif + +#define TPS_nAreaVolRatioData \ +{0xFFFF,\ + 0x619E,\ + 0x186B,\ + 0xADD,\ + 0x61E,\ + 0x3EC,\ + 0x2BB,\ + 0x203,\ + 0x18B,\ + 0x139,\ + 0xFF,\ + 0xD3,\ + 0xB2,\ + 0x66,\ + 0x43,\ + 0x30,\ +0x1F} + +#define TPS_nAngleSpreadData \ +{0x0,\ +0xB32,\ +0x1664,\ +0x2196,\ +0x2CC8,\ +0x37FB,\ +0x432D,\ +0x4E5F,\ +0x5991,\ +0x64C3,\ +0x6FF6,\ +0x7B28,\ +0x865A,\ +0xB323,\ +0xDFEC,\ +0x10CB4,\ +0x15F8E} + +#define TPS_nTransitionCounterTipIn 500 + + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +EXTERN uint32 TPS_u32ADCRaw; +//ASAM mode=readvalue name="TPS Sensor ADC" type=uint32 offset=0 min=0 max=4095 m=1 b=0 units="dl" format=5.3 help="TPS Sensor ADC Counts" +EXTERN uint32 TPS_u32ADCFiltered; +EXTERN GPM6_ttVolts TPS_tSensorVolts;/*CR1_88*/ +//ASAM mode=readvalue name="TPS Sensor Voltage" type=uint32 offset=0 min=0 max=5 m=0.001 b=0 units="V" format=5.3 help="TPS Sensor Voltage" +EXTERN GPM6_ttTheta TPS_tThetaRaw; +EXTERN GPM6_ttTheta TPS_tThetaPreFiltered; +EXTERN GPM6_ttTheta TPS_tThetaFiltered; +//ASAM mode=readvalue name="Throttle Angle" type=uint32 offset=0 min=0 max=90 m=0.001 b=0 units="degrees" format=3.1 help="Throttle Angle" +EXTERN GPM6_ttThetaDT TPS_tThetaDerivative; +//ASAM mode=readvalue name="TPS Movement Rate" type=sint32 offset=0 min=-1000 max=1000 m=0.001 b=0 units="degrees/s" format=5.3 help="Throttle Angle Movement" +EXTERN uint32 TPS_tThetaDerivativeNormalised; +EXTERN uint32 TPS_u32ManifoldVolumeTau; +EXTERN uint32 TPS_u32AreaVolRatio; +EXTERN uint32 TPS_u32ThrottleMovingCounter; +//ASAM mode=readvalue name="TPS Moving Counter" type=int32 offset=0 min=0 max=2000 m=1 b=0 units="dl" format=4.0 help="TPS Moving Counter" +EXTERN bool TPS_boThrottleClosed; +EXTERN uint16 TPS_u16CANTPSDeltaNegCount; +//ASAM mode=readvalue name="CAN TPS Move Neg Count" type=uint16 offset=0 min=0 max=1000 m=1 b=0 units="dl" format=4.0 help="Throttle Angle Movement" +EXTERN uint16 TPS_u16CANTPSDeltaPosCount; +//ASAM mode=readvalue name="CAN TPS Move Pos Count" type=uint16 offset=0 min=0 max=1000 m=1 b=0 units="dl" format=4.0 help="Throttle Angle Movement" +EXTERN uint32 TPS_u32MovingTPSEnrichment; +//ASAM mode=readvalue name="Moving TPS Enrichment" type=int32 offset=0 min=0 max=2000 m=1 b=0 units="dl" format=4.0 help="Throttle Enrichment" +EXTERN uint32 TPS_u32TipInEnrichment; +//ASAM mode=readvalue name="Tip In Enrichment" type=int32 offset=0 min=0 max=2000 m=1 b=0 units="dl" format=4.0 help="Tip In Enrichment" +EXTERN uint32 TPS_u32TransitionCounter; +//ASAM mode=readvalue name="TPS Transition Counter" type=int32 offset=0 min=0 max=2000 m=1 b=0 units="dl" format=4.0 help="TPS Transition Counter" + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void TPS_vStart(uint32 * const pu32Arg); +void TPS_vRun(uint32* const pu32Arg); +void TPS_vTerminate(uint32* const pu32Arg); +void TPS_vCallBack(puint32 const pu32Arg); + +#endif // TPS_H diff --git a/source/Client/Test_60_M2.h b/source/Client/Test_60_M2.h new file mode 100644 index 0000000..290dc00 --- /dev/null +++ b/source/Client/Test_60_M2.h @@ -0,0 +1,1891 @@ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-braces" + +#define USERCAL_nROMCAL {\ +/* userCalADRefH */\ + 3290u,\ +/* userCalVRef445 */\ + 4530u,\ +/* userCalVNernstTarget */\ + 4450u,\ +/* userCalRNernstReady */\ + 300000u,\ +/* userCalRHeaterThreshold */\ + 6500u,\ +/* au32UserCalPumpCurrentPFactor */\ + {9300u},\ +/* au32UserCalPumpCurrentMFactor */\ + {9300u},\ +/* ai32UserCalPumpCurrentOffset */\ + {2u},\ +/* aUserCalPumpSpread */\ + {-1850000u,\ + -1465000u,\ + -1080000u,\ + -920000u,\ + -760000u,\ + -615000u,\ + -470000u,\ + -235000u,\ + 0,\ + 170000u,\ + 340000u,\ + 510000u,\ + 680000u,\ + 815000u,\ + 950000u,\ + 1400000u,\ + 2550000u},\ +/* aUserCalPumpLambda */\ + {700u,\ + 750u,\ + 800u,\ + 825,\ + 850u,\ + 875u,\ + 900u,\ + 955u,\ + 1000u,\ + 1094u,\ + 1180u,\ + 1305u,\ + 1430u,\ + 1565u,\ + 1700u,\ + 2350u,\ + 4160u},\ +/* au8UserCalPumpSensorTrim */\ + {74u},\ +/* aUserStoichFuelCal */\ + 1470u,\ +/* au8UserCalPumpDeadband */\ + {2u},\ +/* au16UserCalFreeAirPoints */\ + {3310u,\ + 3320u,\ + 3330u,\ + 3340u,\ + 3350u,\ + 3360u,\ + 3370u,\ + 3380u,\ + 3390u,\ + 3400u,\ + 3410u,\ + 3420u,\ + 3430u,\ + 3440u,\ + 3450u,\ + 3460u,\ + 3470u,\ + 3480u,\ + 3490u},\ +/* aUserHeaterAlarmCurrent */\ + {2600u},\ +/* u8WarmUpDelay */\ + 10u,\ +/* u8DisplayMode */\ + 1u,\ +/* u8BackLightEnable */\ + 1u,\ +/* userCalTPSCalMin */\ + 500u,\ +/* userCalTPSCalMax */\ + 4500u,\ +/* aUserCURVEAfmTFSpread */\ + {500u,\ + 1000u,\ + 1500u,\ + 2000u,\ + 2500u,\ + 3000u,\ + 3500u,\ + 4000u,\ + 4500u,\ + 5000u,\ + 5500u,\ + 6000u,\ + 7000u,\ + 8000u,\ + 9000u,\ + 10000u,\ + 11000u},\ +/* aUserCURVEAfmTFTable */\ + {0,\ + 720000,\ + 1440000,\ + 2400000,\ + 3360000,\ + 5600000,\ + 9040000,\ + 13600000,\ + 20000000,\ + 30000000,\ + 50000000,\ + 5000000,\ + 5000000,\ + 5000000,\ + 5000000,\ + 5000000,\ + 5000000},\ +/* aUserInjResponseSpread */\ + {7500u,\ + 8000u,\ + 8500u,\ + 9000u,\ + 9500u,\ + 10000u,\ + 10500u,\ + 11000u,\ + 11500u,\ + 12000u,\ + 12500u,\ + 13000u,\ + 13500u,\ + 14000u,\ + 14500u,\ + 15000u,\ + 15500u},\ +/* aUserInjResponseTable */\ + {2700u,\ + 2550u,\ + 2400u,\ + 2250u,\ + 2100u,\ + 1950u,\ + 1800u,\ + 1650u,\ + 1300u,\ + 1100u,\ + 940u,\ + 840u,\ + 770u,\ + 710u,\ + 670u,\ + 640u,\ + 630u},\ + {500u,\ + 750u,\ + 1000u,\ + 1250u,\ + 1500u,\ + 1750u,\ + 2000u,\ + 2250u,\ + 2500u,\ + 2750u,\ + 3000u,\ + 3250u,\ + 3500u,\ + 3750u,\ + 4000u,\ + 4250u,\ + 4500u},\ +/* aUserCoolantSensorTable */\ + {500000,\ + 200000,\ + 140000,\ + 132000,\ + 122000,\ + 110000,\ + 100000,\ + 87000,\ + 79000,\ + 71000,\ + 60000,\ + 40000,\ + 20000,\ + 2000,\ + -6000,\ + -15000,\ + -40000},\ +/* aUserCoolantEnrichmentSpread */\ + {-40000,\ + -30000,\ + -20000,\ + -10000,\ + 0,\ + 10000,\ + 20000,\ + 30000,\ + 40000,\ + 50000,\ + 60000,\ + 70000,\ + 80000,\ + 90000,\ + 100000,\ + 110000,\ + 120000},\ +/* aUserCoolantEnrichmentTable */\ + {1080u,\ + 1080u,\ + 1080u,\ + 1080u,\ + 1080u,\ + 1080u,\ + 1080u,\ + 1080u,\ + 1040u,\ + 1020u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u},\ +/* aUserTAFRxSpread */\ + {0u,\ + 500u,\ + 1000u,\ + 1500u,\ + 2000u,\ + 2500u,\ + 3000u,\ + 3500u,\ + 4000u,\ + 4500u,\ + 5000u,\ + 5500u,\ + 6000u,\ + 6500u,\ + 7000u,\ + 7500u,\ + 8000u},\ +/* aUserTAFRySpread */\ + {0u,\ + 5625u,\ + 11250u,\ + 16875u,\ + 22500u,\ + 28125u,\ + 33750u,\ + 39375u,\ + 45000u,\ + 50625u,\ + 56250u,\ + 61875u,\ + 67500u,\ + 73125u,\ + 78750u,\ + 84375u,\ + 90000u}, \ + /* aUserMAPTAFR */\ + {{1470,1470,1470,1100,1100,1100,1100,1400,1400,1400,1400,1400,1400,1400,1400,1400,1400},\ + {1470,1470,1450,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1400},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1190,1190,1190},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1290,1290,1290},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1290,1290,1290},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1290,1290,1290},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1290,1290,1290},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1290,1290,1290},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1290,1290,1290},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1290,1290,1290},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1290,1290,1290},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1260,1190,1190,1190,1190,1190,1190},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1260,1190,1190,1190,1190,1190,1190},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1260,1190,1190,1190,1190,1190,1190},\ + {1900,1470,1470,1470,1470,1470,1470,1470,1400,1330,1260,1190,1190,1190,1190,1190,1190},\ + {1900,1470,1470,1470,1470,1470,1470,1470,1400,1330,1260,1190,1190,1190,1190,1190,1190},\ + {1900,1470,1470,1470,1470,1470,1470,1470,1400,1330,1260,1190,1190,1190,1190,1190,1190}},\ +/* aUserTimingxSpread */\ + {0u,\ + 500u,\ + 1000u,\ + 1500u,\ + 2000u,\ + 2500u,\ + 3000u,\ + 3500u,\ + 4000u,\ + 4500u,\ + 5000u,\ + 5500u,\ + 6000u,\ + 6500u,\ + 7000u,\ + 7500u,\ + 8000u},\ +/* aUserTimingySpread */\ + {25000u,\ + 30000u,\ + 35000u,\ + 40000u,\ + 45000u,\ + 50000u,\ + 55000u,\ + 60000u,\ + 65000u,\ + 70000u,\ + 75000u,\ + 80000u,\ + 85000u,\ + 90000u,\ + 95000u,\ + 100000u,\ + 105000u},\ +/* aUserTimingMap */\ + {{130,130,130,130,120,60,0,0,0,0,0,0,0,0,0,0,0},\ + {110,110,110,110,120,80,80,80,80,80,80,70,70,70,70,70,70},\ + {160,160,130,120,80,110,100,90,90,90,90,80,80,80,80,80,80},\ + {240,220,180,170,160,150,140,130,120,120,120,120,120,120,120,120,120},\ + {260,240,260,250,240,210,180,180,180,180,190,200,200,200,210,220,220},\ + {280,340,360,280,260,245,230,230,230,230,230,230,225,225,230,230,230},\ + {280,340,360,330,280,260,250,230,230,230,230,230,225,225,230,230,230},\ + {280,340,360,330,280,260,250,230,230,230,230,230,225,225,230,230,230},\ + {280,340,360,330,280,260,250,230,230,230,230,230,225,225,230,230,230},\ + {280,340,360,330,280,260,250,230,230,230,230,230,225,225,230,230,230},\ + {280,340,360,330,280,260,250,230,230,230,230,230,225,225,230,230,230},\ + {280,340,360,330,280,260,250,230,230,230,230,230,225,225,230,230,230},\ + {280,240,360,330,280,260,250,230,230,230,230,230,225,225,230,230,230},\ + {220,260,360,360,340,320,280,270,260,250,250,250,250,250,260,250,250},\ + {140,260,360,360,340,320,280,270,260,250,250,250,250,250,260,250,250},\ + {140,260,360,360,340,320,280,270,260,250,250,250,250,250,260,260,270},\ + {90,90,90,90,90,90,90,90,90,90,90,80,80,80,80,80,80}},\ +/* aUserVExSpread */\ + {0u,\ + 500u,\ + 1000u,\ + 1500u,\ + 2000u,\ + 2500u,\ + 3000u,\ + 3500u,\ + 4000u,\ + 4500u,\ + 5000u,\ + 5500u,\ + 6000u,\ + 6500u,\ + 7000u,\ + 7500u,\ + 8000u},\ +/* aUserVEySpread */\ + {25000u,\ + 30000u,\ + 35000u,\ + 40000u,\ + 45000u,\ + 50000u,\ + 55000u,\ + 60000u,\ + 65000u,\ + 70000u,\ + 75000u,\ + 80000u,\ + 85000u,\ + 90000u,\ + 95000u,\ + 100000u,\ + 105000u},\ +/* aUserMAPVE */\ + {{600,600,600,600,600,600,600,700,800,800,800,800,800,800,800,800,800},\ + {550,570,590,610,630,650,700,700,700,700,700,700,700,700,700,700,700},\ + {580,610,630,650,670,690,700,700,700,700,700,650,650,650,650,650,650},\ + {610,630,650,670,690,700,700,700,670,670,670,670,670,670,670,670,670},\ + {640,660,680,690,700,710,710,710,710,710,710,710,710,720,720,720,720},\ + {670,680,690,700,710,720,720,720,720,720,720,720,720,720,720,720,720},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600}},\ +/* aUserCoolantStartEnrichmentSpread */\ + {-40000,\ + -30000,\ + -20000,\ + -10000,\ + 0,\ + 10000,\ + 20000,\ + 30000,\ + 40000,\ + 50000,\ + 60000,\ + 70000,\ + 80000,\ + 90000,\ + 100000,\ + 110000,\ + 120000},\ +/* aUserCoolantStartEnrichmentTable */\ + {4000u,\ + 3500u,\ + 3000u,\ + 2500u,\ + 2000u,\ + 1800u,\ + 1600u,\ + 1400u,\ + 1200u,\ + 1150u,\ + 1100u,\ + 1050u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u},\ +/* aUserCoolantPostStartEnrichmentSpread */\ + {-40000,\ + -30000,\ + -20000,\ + -10000,\ + 0,\ + 10000,\ + 20000,\ + 30000,\ + 40000,\ + 50000,\ + 60000,\ + 70000,\ + 80000,\ + 90000,\ + 100000,\ + 110000,\ + 120000},\ +/* aUserCoolantPostStartEnrichmentTable */\ + {1200u,\ + 1200u,\ + 1200u,\ + 1200u,\ + 1150u,\ + 1130u,\ + 1110u,\ + 1100u,\ + 1100u,\ + 1100u,\ + 1100u,\ + 1100u,\ + 1100u,\ + 1100u,\ + 1100u,\ + 1100u,\ + 1100u},\ +/* aUserCrankingAirflowSpread */\ + {150u,\ + 160u,\ + 170u,\ + 180u,\ + 190u,\ + 200u,\ + 210u,\ + 220u,\ + 230u,\ + 240u,\ + 250u,\ + 260u,\ + 270u,\ + 280u,\ + 290u,\ + 300u,\ + 400u},\ +/* aUserCrankingAirflowTable */\ + {2400u,\ + 2500u,\ + 2600u,\ + 2700u,\ + 2800u,\ + 2900u,\ + 3000u,\ + 3100u,\ + 3200u,\ + 3300u,\ + 3400u,\ + 3500u,\ + 3600u,\ + 3700u,\ + 3800u,\ + 3900u,\ + 4000u},\ +/* aUserDwellSpread */\ + {7500u,\ + 8000u,\ + 8500u,\ + 9000u,\ + 9500u,\ + 10000u,\ + 10500u,\ + 11000u,\ + 11500u,\ + 12000u,\ + 12500u,\ + 13000u,\ + 13500u,\ + 14000u,\ + 14500u,\ + 15000u,\ + 15500u},\ +/* aUserDwellTable */\ + {5000u,\ + 4800u,\ + 4600u,\ + 4400u,\ + 4200u,\ + 4000u,\ + 3800u,\ + 3600u,\ + 3500u,\ + 3400u,\ + 3300u,\ + 3200u,\ + 3100u,\ + 3000u,\ + 3000u,\ + 3000u,\ + 3000u},\ +/* aUserAirTempCorrectionSpread */\ + {-40000,\ + -30000,\ + -20000,\ + -10000,\ + 0,\ + 10000,\ + 20000,\ + 30000,\ + 40000,\ + 50000,\ + 60000,\ + 70000,\ + 80000,\ + 90000,\ + 100000,\ + 110000,\ + 120000},\ +/* aUserAirTempCorrectionTable */\ + {1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u},\ +/* aUserTPSMovementCorrectionSpread */\ + {0x7ffc0000,\ + 0x7ffc8000,\ + 0x7ffd0000,\ + 0x7ffd8000,\ + 0x7ffe0000,\ + 0x7ffe8000,\ + 0x7fff0000,\ + 0x7fff8000,\ + 0x80008000,\ + 0x80010000,\ + 0x80018000,\ + 0x80020000,\ + 0x80028000,\ + 0x80030000,\ + 0x80038000,\ + 0x80040000,\ + 0x80048000},\ +/* aUserTPSMovementCorrectionTable */\ + {1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1020u,\ + 1040u,\ + 1060u,\ + 1080u,\ + 1100u},\ +/* aUserInjectionPhasingSpread */\ + {0u,\ + 500u,\ + 1000u,\ + 1500u,\ + 2000u,\ + 2500u,\ + 3000u,\ + 3500u,\ + 4000u,\ + 4500u,\ + 5000u,\ + 6500u,\ + 7000u,\ + 7500u,\ + 8000u,\ + 8500u,\ + 9000u},\ +/* aUserInjectionPhasingTable */\ +{0u,\ + 100u,\ + 200u,\ + 300u,\ + 400u,\ + 500u,\ + 600u,\ + 700u,\ + 800u,\ + 900u,\ + 1000u,\ + 1100u,\ + 1200u,\ + 1300u,\ + 1400u,\ + 1500u,\ + 1600u},\ +/* aUserCTSTimingCorrectionSpread */\ + {-40000,\ + -30000,\ + -20000,\ + -10000,\ + 0,\ + 10000,\ + 20000,\ + 30000,\ + 40000,\ + 50000,\ + 60000,\ + 70000,\ + 80000,\ + 90000,\ + 100000,\ + 110000,\ + 120000},\ +/* aUserCTSTimingCorrectionTable */\ + {31u,\ + 25u,\ + 22u,\ + 18u,\ + 15u,\ + 14u,\ + 13u,\ + 12u,\ + 11u,\ + 10u,\ + 10u,\ + 10u,\ + 10u,\ + 10u,\ + 10u,\ + 10u,\ + 10u},\ +/* aUserATSTimingCorrectionSpread */\ +{-40000,\ + -30000,\ + -20000,\ + -10000,\ + 0,\ + 10000,\ + 20000,\ + 30000,\ + 40000,\ + 50000,\ + 60000,\ + 70000,\ + 80000,\ + 90000,\ + 100000,\ + 110000,\ + 120000},\ +/* aUserATSTimingCorrectionTable */\ + {31u,\ + 25u,\ + 22u,\ + 18u,\ + 15u,\ + 14u,\ + 13u,\ + 12u,\ + 11u,\ + 10u,\ + 10u,\ + 10u,\ + 10u,\ + 10u,\ + 10u,\ + 10u,\ + 10u},\ +/* aUserISCSpeedTargetSpread */\ +{-40000,\ + -30000,\ + -20000,\ + -10000,\ + 0,\ + 10000,\ + 20000,\ + 30000,\ + 40000,\ + 50000,\ + 60000,\ + 70000,\ + 80000,\ + 90000,\ + 100000,\ + 110000,\ + 120000},\ +/* aUserISCSpeedTargetTable */\ +{1000u,\ + 900u,\ + 800u,\ + 750u,\ + 700u,\ + 680u,\ + 660u,\ + 640u,\ + 620u,\ + 600u,\ + 590u,\ + 580u,\ + 570u,\ + 560u,\ + 550u,\ + 545u,\ + 540u},\ +/* aUserStepperCloseTable */\ + {5,\ + 9,\ + 10,\ + 6},\ +/* aUserStepperOpenTable */\ + {6,\ + 10,\ + 9,\ + 5},\ +/* u32UserStepperHomeSteps */\ + 24,\ +/* aUserPrimaryTriggerTable */\ + {0x0,\ + 0x444,\ + 0x888,\ + 0xCCC,\ + 0x1110,\ + 0x1555,\ + 0x1999,\ + 0x1DDD,\ + 0x2222,\ + 0x2666,\ + 0x2AAA,\ + 0x2EEE,\ + 0x3333,\ + 0x3777,\ + 0x3BBB,\ + 0x4000,\ + 0x4444,\ + 0x4888,\ + 0x4CCC,\ + 0x5111,\ + 0x5555,\ + 0x5999,\ + 0x5DDD,\ + 0x6222,\ + 0x6666,\ + 0x6AAA,\ + 0x6EEE,\ + 0x7333,\ + 0x7777,\ + 0x7BBB,\ + 0x8000,\ + 0x8444,\ + 0x8888,\ + 0x8CCC,\ + 0x9111,\ + 0x9555,\ + 0x9999,\ + 0x9DDD,\ + 0xA222,\ + 0xA666,\ + 0xAAAA,\ + 0xAEEE,\ + 0xBBBC,\ + 0xC000,\ + 0xC444,\ + 0xC888,\ + 0xCCCC,\ + 0xD111,\ + 0xD555,\ + 0xD999,\ + 0xDDDD,\ + 0xE222,\ + 0xE666,\ + 0xEAAA,\ + 0xEEEE,\ + 0xF333,\ + 0xF777,\ + 0xFBBB,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0}, \ +/* aUserSecondaryTriggerTable */\ +{0x0,\ + 0x444,\ + 0x888,\ + 0xCCC,\ + 0x1111,\ + 0x1555,\ + 0x1999,\ + 0x1DDD,\ + 0x2AAA,\ + 0x2EEE,\ + 0x3333,\ + 0x3777,\ + 0x3BBB,\ + 0x4000,\ + 0x4444,\ + 0x4888,\ + 0x4CCC,\ + 0x5111,\ + 0x5555,\ + 0x5999,\ + 0x5DDD,\ + 0x6222,\ + 0x6666,\ + 0x6AAA,\ + 0x6EEE,\ + 0x7333,\ + 0x7777,\ + 0x7BBB,\ + 0x8000,\ + 0x8444,\ + 0x8888,\ + 0x8CCC,\ + 0x9111,\ + 0x9555,\ + 0x9999,\ + 0x9DDD,\ + 0xA222,\ + 0xA666,\ + 0xAAAA,\ + 0xAEEE},\ + {0x0, 0x4000, 0x8000, 0xc000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},\ +/* u8UserPrimaryEdgeSetup */\ + 0x1,\ + /* u8UserSecondaryEdgeSetup */\ + 0x1,\ +/* u8UserPrimaryVREnable */\ + 0,\ +/* u8UserSecondaryVREnable */\ + 0,\ +/* u8UserFirstEdgeRisingPrimary */\ + 0,\ +/* u8UserFirstEdgeRisingSecondary */\ + 0,\ +/* au32InjectionSequence */\ + {0x0202, 0x0202, 0x0202, 0x0602},\ +/* au32IgnitionSequence */\ + {0x0000, 0x0202, 0xffff, 0xffff},\ +/* enSimpleCamSyncSource */\ + EH_IO_Invalid,\ +/* boCamSyncHighLate */\ + 1,\ +/* u32CamSyncSampleToothCount */\ + 15,\ +/* u16ManifoldVolumeCC */\ + 2000,\ +/* u8CylCount */\ + 4, \ +/* u16InjFlowRate */\ + 3000, \ +/* aUserBackupAirflowxSpread */\ +{0,\ +500,\ +1000,\ +1500,\ +2000,\ +2500,\ +3000,\ +3500,\ +4000,\ +4500,\ +5000},\ +/* aUserBackupAirflowySpread */\ + {0x0,\ + 0xB32,\ + 0x1664,\ + 0x2196,\ + 0x2CC8,\ + 0x37FB,\ + 0x432D,\ + 0x5991,\ + 0x865A,\ + 0xDFEC,\ + 0x15F90},\ +/* aUserBackupAirflowMap */\ +{{0x3C14DC, 0x4417A3, 0x4417A3, 0x4417A3, 0x4417A3, 0x4417A3, 0x4417A3, 0x4417A3, 0x4417A3, 0x4417A3, 0x4417A3},\ +{0x5B8D80, 0x7704C0, 0x8C30AC, 0xC84588, 0xF05370, 0x1186158, 0x1186158, 0x1186158, 0x1186158, 0x1186158, 0x1186158},\ +{0x6ACFC0, 0x8F6EC0, 0xBBAEE0, 0xFD4BC0, 0x1312D00, 0x16E3600, 0x1AB3F00, 0x1F78A40, 0x2349340, 0x243D580, 0x2625A00},\ +{0x6ACFC0, 0x989680, 0xB28720, 0xDBBA00, 0x112A880, 0x14FB180, 0x1BD8E80, 0x2255100, 0x2BDE780, 0x3567E00, 0x3993FD8},\ +{0x7270E0, 0x989680, 0xCAF120, 0xE975A0, 0x11D56E0, 0x1681B80, 0x1D905C0, 0x2CD29C0, 0x3938700, 0x4B1A130, 0x4D9AF18},\ +{0x7270E0, 0x989680, 0xCAF120, 0xF73140, 0x1406F40, 0x19BFCC0, 0x243D580, 0x3938700, 0x4B1A130, 0x59A5380, 0x68E7780},\ +{0x7270E0, 0x989680, 0xCAF120, 0xF73140, 0x132B3A0, 0x1BA8140, 0x2AEA540, 0x3C14DC0, 0x529CAE8, 0x6BA55F8, 0x7D2B750},\ +{0x7270E0, 0x989680, 0xCAF120, 0xF73140, 0x132B3A0, 0x1F4ADD4, 0x2AEA540, 0x3EF1480, 0x55D4A80, 0x6F94740, 0x8F0D180},\ +{0x7270E0, 0x989680, 0xCAF120, 0xF73140, 0x132B3A0, 0x1F4ADD4, 0x2AEA540, 0x40D9900, 0x59A5380, 0x754D4C0, 0xA21FE80},\ +{0x7270E0, 0x989680, 0xCAF120, 0xF73140, 0x132B3A0, 0x1F4ADD4, 0x2AEA540, 0x42C1D80, 0x5D75C80, 0x8583B00, 0xBEBC200},\ +{0x7270E0, 0x989680, 0xCAF120, 0xF73140, 0x132B3A0, 0x1F4ADD4, 0x2AEA540, 0x42C1D80, 0x623A7C0, 0x9896800, 0xDB58580}},\ +/* u8ManifoldTimeConstantTrim */\ +0x1f,\ +/* u8EnableBackupAirflowTransients */\ +0x00,\ +/* aUserPrimerSpread */\ + {-40000,\ + -30000,\ + -20000,\ + -10000,\ + 0,\ + 10000,\ + 20000,\ + 30000,\ + 40000,\ + 50000,\ + 60000},\ +/* aUserPrimerTable */\ + {400000u,\ + 400000u,\ + 300000u,\ + 250000u,\ + 200000u,\ + 150000u,\ + 100000u,\ + 70000u,\ + 30000u,\ + 25000u,\ + 25000u},\ +/* aUserInjShortOpeningSpread */\ + {0,\ + 200,\ + 400,\ + 600,\ + 800,\ + 1000,\ + 1200,\ + 1400,\ + 1600,\ + 1800,\ + 2000}, \ +/* aUserInjShortOpeningTable */\ + {870u,\ + 870u,\ + 870u,\ + 890u,\ + 930u,\ + 1030u,\ + 1200u,\ + 1400u,\ + 1600u,\ + 1800u,\ + 2000u},\ +/* u32STTNegLimit */\ + 800, \ +/* u32STTPosLimit */\ + 1150, \ +/* u32CLStepClosed */\ + 5,\ +/* u32CLIncClosed */\ + 1,\ +/* u32CLStepOpen */\ + 7,\ +/* u32CLIncOpen */\ + 2,\ +/* u16TimingMainOffset */\ + 20000,\ +/* u32AFMTransientControlRPMLimit */\ + 3000,\ +/* u8WastedSparkEnable */\ + 1,\ +/* u16AFRReinstate */\ + 1500,\ +/* u16AFRCutoff */\ + 1700,\ +/* u32TPSClosedLower */\ + 1300,\ +/* u32TPSClosedUpper */\ + 1500,\ +/* u32ISCESTTrimPos */\ + 7000,\ +/* u32ISCESTTrimNeg */\ + 7000,\ +/* u32CLO2ESTTrimPos */\ + 2000,\ +/* u32CLO2ESTTrimNeg */\ + 2000,\ +/* u16CylinderCC */\ + 500,\ +/* u8EnableAFMPrimaryInputOpen */\ + 0,\ +/* u32SpeedDensityAFMTPSLim */\ + 90000,\ +/* au16SeqRPMLimit */\ + {4200,\ + 4400,\ + 4600,\ + 5800,\ + 4400,\ + 4500,\ + 4600,\ + 4700},\ +/* u16SeqRPMLimitHyst */\ + 200,\ +/* u16HighVacuumEnableKpa */\ + 23000,\ +/* u16HighVacuumDisableKpa */\ + 33000,\ +/* u16OverrunCutEnableRPM */\ + 300,\ +/* u16OverrunCutDisableRPM */\ + 600,\ +/* u16RPMRunThreshold */\ + 350,\ +/* u8SeqFuelAssign */\ + 6,\ +/* u16ESTFilterClosed */\ + 10,\ +/* u16ESTFilterOpen */\ + 80,\ +/* u16ESTCLGain */\ + 80,\ +/* u8EnableAFMPrimaryInputClosed */\ + 0,\ +/* s16SequenceFuelOffset */\ + 1,\ +/* s16SequenceFuelOffset */\ + 1,\ +/* s16SequenceFuelOffset */\ + 1,\ +/* s16SequenceFuelOffset */\ + 1,\ +/* s16SequenceFuelGain */\ + 1000,\ +/* s16SequenceFuelGain */\ + 1000,\ +/* s16SequenceFuelGain */\ + 1000,\ +/* s16SequenceFuelGain */\ + 1000,\ +/* boTPSCANPrimary */\ + 0,\ +/* boPPSCANPrimary */\ + 0,\ +/* boCTSCANPrimary */\ + 0,\ +/* boATSCANPrimary */\ + 0,\ +/* boMAPCANPrimary */\ + 0,\ +/* au32PrioCANID */\ + 1217,\ +/* au32PrioCANID */\ + 401,\ +/* au32PrioCANID */\ + 1001,\ +/* au32PrioCANID */\ + 2024,\ +/* au8SensorCANDataOffset */\ + {16,16,16,16,16,16,16,16},\ +/* au8SensorCANDataByteCount */\ + {2,2,2,2,2,2,2,2},\ +/* u32SyncPhaseRepeats */\ + 1,\ +/* s32MapSensorGain */\ + 19100,\ +/* s32MapSensorOffset */\ + 10400,\ +/* u8InjDivide */\ + 2,\ +/* u8CLO2Leftenable */\ + 0,\ +/* u8CLO2RightEnable */\ + 0,\ +/* u8ReturnlessEnable */\ + 0,\ +/* u16ReturnlessPressureKPa */\ + 450,\ +/* u8CrankingAirflowEnable */\ + 0,\ +/* u8StepperIACEnable */\ + 0,\ +/* u16IACStepsOpenHot */\ + 10,\ +/* u16IACStepsOpenCold */\ + 80,\ +/* u16IdleEntryOffset */\ + 800,\ +/* s32RadFanOnTemp */\ + 80000,\ +/* s32RadFanOffTemp */\ + 60000,\ +/* enFuelPumpRelay */\ + EH_IO_Invalid,\ +/* enESTBypass */\ + EH_IO_Invalid,\ +/* aUserAirSensorSpread */\ + {203u,\ + 299u,\ + 391u,\ + 606u,\ + 802u,\ + 1014u,\ + 1407u,\ + 1774u,\ + 2110u,\ + 2432u,\ + 2946u,\ + 3565u,\ + 4067u,\ + 4658u,\ + 4782u,\ + 4856u,\ + 4924u},\ +/* aUserAirSensorTable */\ + {500000,\ + 200000,\ + 140000,\ + 132000,\ + 122000,\ + 110000,\ + 100000,\ + 87000,\ + 79000,\ + 71000,\ + 60000,\ + 40000,\ + 20000,\ + 2000,\ + -6000,\ + -15000,\ + -40000},\ + /* aFuelIOResource */\ + {EH_IO_TMR2, EH_IO_TMR3, EH_IO_TMR4, EH_IO_TMR5},\ + /* aESTIOResource */\ + {EH_IO_TMR9, EH_IO_TMR8, EH_IO_TMR7, EH_IO_TMR6},\ + /* aIACIOResource */\ + {EH_IO_Invalid, EH_IO_Invalid, EH_IO_Invalid, EH_IO_Invalid},\ + /* boOBDISCADV */\ + 0,\ + /* u8TriggerType */\ + 0,\ + /* u8SyncType */\ + 0,\ + /* u8TriggerPullStrength */\ + 0,\ + /* u8SyncPullStrength */\ + 0,\ + /* u16MinLinearFuelPulse */\ + 0,\ + /* u16CTSADResource */\ + EH_IO_GPSE1,\ + /* u16MAPADResource */\ + EH_IO_GPSE5,\ + /* u16ATSADResource */\ + EH_IO_Invalid,\ + /* u16AFMADResource */\ + EH_IO_Invalid,\ + /* u16TPSADResource */\ + EH_IO_GPSE4,\ +/* aUserTipInCorrectionSpread */\ + {0,\ + 250,\ + 500,\ + 1000,\ + 1250,\ + 1500,\ + 1750,\ + 2000,\ + 2250,\ + 2500,\ + 2750,\ + 3000,\ + 3250,\ + 3500,\ + 3750,\ + 4000,\ + 4250},\ +/* aUserTipInCorrectionTable */\ + {1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u},\ +/* Logic Block Var */\ + {0u,\ + 0u,\ + 0u,\ + 0u,\ + 0u,\ + 0u,\ + 0u,\ + 0u},\ +/* Logic Block Operand */\ + {1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u},\ +/* Logic Block Chain Output */\ + {0u,\ + 0u,\ + 0u,\ + 0u,\ + 0u,\ + 0u,\ + 0u,\ + 0u},\ +/* Thermofan Relay */\ + EH_IO_Invalid,\ +/* EST IO Mux Resource */\ + {EH_IO_Invalid,\ + EH_IO_Invalid,\ + EH_IO_Invalid,\ + EH_IO_Invalid},\ +/* UEGO CAN Primary */\ + 1,\ +/* PWM 2D 1 Axis Source X */\ + 0,\ +/* PWM 2D 2 Axis Source X */\ + 1,\ +/* PWM 2D 3 Axis Source X */\ + 2,\ +/* PWM 2D 4 Axis Source X */\ + 3,\ +/* PWM 2D 5 Axis Source X */\ + 4,\ +/* PWM 2D 6 Axis Source X */\ + 0,\ +/* PWM 2D 7 Axis Source X */\ + 1,\ +/* PWM 2D 8 Axis Source X */\ + 2,\ +/* PWM 3D 1 Axis Source X */\ + 3,\ +/* PWM 3D 2 Axis Source X */\ + 4,\ +/* PWM 3D 3 Axis Source X */\ + 0,\ +/* PWM 3D 4 Axis Source X */\ + 1,\ +/* PWM 3D 1 Axis Source Y */\ + 2,\ +/* PWM 3D 2 Axis Source Y */\ + 3,\ +/* PWM 3D 3 Axis Source Y */\ + 4,\ +/* PWM 3D 4 Axis Source Y */\ + 0,\ +/* PWM 2D 1 IO Resource */\ + 0,\ +/* PWM 2D 2 IO Resource */\ + 0,\ +/* PWM 2D 3 IO Resource */\ + 0,\ +/* PWM 2D 4 IO Resource */\ + 0,\ +/* PWM 2D 5 IO Resource */\ + 0,\ +/* PWM 2D 6 IO Resource */\ + 0,\ +/* PWM 2D 7 IO Resource */\ + 0,\ +/* PWM 2D 8 IO Resource */\ + 0,\ +/* PWM 3D 1 IO Resource */\ + 0,\ +/* PWM 3D 2 IO Resource */\ + 0,\ +/* PWM 3D 3 IO Resource */\ + 0,\ +/* PWM 3D 4 IO Resource */\ + 0,\ +/* PWM 2D 1 Table_XAXIS */\ + {0,\ + 250,\ + 500,\ + 750,\ + 1000,\ + 1250,\ + 1500,\ + 1750,\ + 2000,\ + 2250,\ + 2500,\ + 2750,\ + 3000,\ + 3250,\ + 3500,\ + 3750,\ + 4000},\ +/* PWM 2D 2 Table_XAXIS */\ + {0,\ + 5000,\ + 10000,\ + 15000,\ + 20000,\ + 25000,\ + 30000,\ + 35000,\ + 40000,\ + 45000,\ + 50000,\ + 55000,\ + 60000,\ + 65000,\ + 70000,\ + 75000,\ + 90000},\ +/* PWM 2D 3 Table_XAXIS */\ + {0,\ + 10000,\ + 20000,\ + 30000,\ + 40000,\ + 50000,\ + 60000,\ + 70000,\ + 80000,\ + 90000,\ + 100000,\ + 110000,\ + 120000,\ + 130000,\ + 140000,\ + 150000,\ + 160000},\ +/* PWM 2D 4 Table_XAXIS */\ + {0,\ + 100,\ + 200,\ + 300,\ + 400,\ + 500,\ + 600,\ + 700,\ + 800,\ + 900,\ + 1000,\ + 1100,\ + 1200,\ + 1300,\ + 1400,\ + 1500,\ + 1600},\ +/* PWM 2D 5 Table_XAXIS */\ + {0,\ + 0x100,\ + 0x200,\ + 0x300,\ + 0x400,\ + 0x500,\ + 0x600,\ + 0x700,\ + 0x800,\ + 0x900,\ + 0xa00,\ + 0xb00,\ + 0xc00,\ + 0xd00,\ + 0xe00,\ + 0xf00,\ + 0xffff},\ +/* PWM 2D 6 Table_XAXIS */\ + {0,\ + 0x100,\ + 0x200,\ + 0x300,\ + 0x400,\ + 0x500,\ + 0x600,\ + 0x700,\ + 0x800,\ + 0x900,\ + 0xa00,\ + 0xb00,\ + 0xc00,\ + 0xd00,\ + 0xe00,\ + 0xf00,\ + 0xfff},\ +/* PWM 2D 7 Table_XAXIS */\ + {0,\ + 0x10,\ + 0x20,\ + 0x30,\ + 0x40,\ + 0x50,\ + 0x60,\ + 0x70,\ + 0x80,\ + 0x90,\ + 0xa0,\ + 0xb0,\ + 0xc0,\ + 0xd0,\ + 0xe0,\ + 0xf0,\ + 0xff},\ +/* PWM 2D 8 Table_XAXIS */\ + {0,\ + 0x100,\ + 0x200,\ + 0x300,\ + 0x400,\ + 0x500,\ + 0x600,\ + 0x700,\ + 0x800,\ + 0x900,\ + 0xa00,\ + 0xb00,\ + 0xc00,\ + 0xd00,\ + 0xe00,\ + 0xf00,\ + 0xfff},\ +/* PWM 2D 1 Table */\ + {0,\ + 50,\ + 100,\ + 150,\ + 200,\ + 250,\ + 300,\ + 350,\ + 400,\ + 450,\ + 500,\ + 550,\ + 600,\ + 650,\ + 700,\ + 750,\ + 800},\ +/* PWM 2D 2 Table */\ + {0,\ + 51,\ + 100,\ + 150,\ + 200,\ + 250,\ + 300,\ + 350,\ + 400,\ + 450,\ + 500,\ + 550,\ + 600,\ + 650,\ + 700,\ + 750,\ + 800},\ +/* PWM 2D 3 Table */\ + {0,\ + 52,\ + 100,\ + 150,\ + 200,\ + 250,\ + 300,\ + 350,\ + 400,\ + 450,\ + 500,\ + 550,\ + 600,\ + 650,\ + 700,\ + 750,\ + 800},\ +/* PWM 2D 4 Table */\ + {0,\ + 53,\ + 100,\ + 150,\ + 200,\ + 250,\ + 300,\ + 350,\ + 400,\ + 450,\ + 500,\ + 550,\ + 600,\ + 650,\ + 700,\ + 750,\ + 800},\ +/* PWM 2D 5 Table */\ + {0,\ + 54,\ + 100,\ + 150,\ + 200,\ + 250,\ + 300,\ + 350,\ + 400,\ + 450,\ + 500,\ + 550,\ + 600,\ + 650,\ + 700,\ + 750,\ + 800},\ +/* PWM 2D 6 Table */\ + {0,\ + 55,\ + 100,\ + 150,\ + 200,\ + 250,\ + 300,\ + 350,\ + 400,\ + 450,\ + 500,\ + 550,\ + 600,\ + 650,\ + 700,\ + 750,\ + 800},\ +/* PWM 2D 7 Table */\ + {0,\ + 56,\ + 100,\ + 150,\ + 200,\ + 250,\ + 300,\ + 350,\ + 400,\ + 450,\ + 500,\ + 550,\ + 600,\ + 650,\ + 700,\ + 750,\ + 800},\ +/* PWM 2D 8 Table */\ + {0,\ + 57,\ + 100,\ + 150,\ + 200,\ + 250,\ + 300,\ + 350,\ + 400,\ + 450,\ + 500,\ + 550,\ + 600,\ + 650,\ + 700,\ + 750,\ + 800},\ +/* PWM 3D 1 Map_XAXIS */\ + {0,\ + 1000,\ + 2000,\ + 3000,\ + 4000,\ + 5000,\ + 6000,\ + 7000,\ + 8000,\ + 9000,\ + 10000,\ + 11000,\ + 12000,\ + 13000,\ + 14000,\ + 15000,\ + 16000},\ +/* PWM 3D 2 Map_XAXIS */\ + {0,\ + 1000,\ + 2000,\ + 3000,\ + 4000,\ + 5000,\ + 6000,\ + 7000,\ + 8000,\ + 9000,\ + 10000,\ + 11000,\ + 12000,\ + 13000,\ + 14000,\ + 15000,\ + 16000},\ +/* PWM 3D 3 Map_XAXIS */\ + {0,\ + 0x107,\ + 0x207,\ + 0x307,\ + 0x407,\ + 0x507,\ + 0x607,\ + 0x707,\ + 0x807,\ + 0x907,\ + 0xa07,\ + 0xb07,\ + 0xc07,\ + 0xd07,\ + 0xe07,\ + 0xf07,\ + 0xfff},\ +/* PWM 3D 4 Map_XAXIS */\ + {0,\ + 0x10,\ + 0x20,\ + 0x30,\ + 0x40,\ + 0x50,\ + 0x60,\ + 0x70,\ + 0x80,\ + 0x90,\ + 0xa0,\ + 0xb0,\ + 0xc0,\ + 0xd0,\ + 0xe0,\ + 0xf0,\ + 0xff},\ +/* PWM 3D 5 Map_YAXIS */\ + {0,\ + 0x101,\ + 0x201,\ + 0x301,\ + 0x401,\ + 0x501,\ + 0x601,\ + 0x701,\ + 0x801,\ + 0x901,\ + 0xa01,\ + 0xb01,\ + 0xc01,\ + 0xd01,\ + 0xe01,\ + 0xf01,\ + 0xffff},\ +/* PWM 3D 6 Map_YAXIS */\ + {0,\ + 0x1040,\ + 0x2040,\ + 0x3040,\ + 0x4040,\ + 0x5040,\ + 0x6040,\ + 0x7040,\ + 0x8040,\ + 0x9040,\ + 0xa040,\ + 0xb040,\ + 0xc040,\ + 0xd040,\ + 0xe040,\ + 0xf040,\ + 0xffff},\ +/* PWM 3D 7 Map_YAXIS */\ + {0,\ + 0x108,\ + 0x208,\ + 0x308,\ + 0x408,\ + 0x508,\ + 0x608,\ + 0x708,\ + 0x808,\ + 0x908,\ + 0xa08,\ + 0xb08,\ + 0xc08,\ + 0xd08,\ + 0xe08,\ + 0xf08,\ + 0xfff},\ +/* PWM 3D 8 Map_YAXIS */\ + {0,\ + 0x100,\ + 0x200,\ + 0x300,\ + 0x400,\ + 0x500,\ + 0x600,\ + 0x700,\ + 0x800,\ + 0x900,\ + 0xa00,\ + 0xb00,\ + 0xc00,\ + 0xd00,\ + 0xe00,\ + 0xf00,\ + 0xfff},\ +/* PWM 3D Map 1 */\ +{\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,110,120,130,140,150,160},\ + {100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + {100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + {100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,110,120,130,140,150,160},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ +},\ +/* PWM 3D Map 2 */\ +{\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,110,120,130,140,150,160},\ + {100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + {100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + {100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,110,120,130,140,150,160},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ +},\ +/* PWM 3D Map 3 */\ +{\ + {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,110,120,130,140,150,160},\ + {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,110,120,130,140,150,160},\ + {100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + {100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + {100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,110,120,130,140,150,160},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ +},\ +/* PWM 3D Map 4 */\ +{\ + {100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + {100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + {100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + {100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + {100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + {100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + {100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + {100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ +},\ +/* Fuel Pressure Solenoid Resource */\ + EH_IO_TMR1,\ +/* VCT AB Pullup Enable */\ + 1,\ +/* VCT CD Pullup Enable */\ + 1,\ +/* aVVTInputResource */\ + {EH_IO_TMR18, EH_IO_Invalid, EH_IO_Invalid, EH_IO_Invalid},\ +/* aVVTInputType */\ + {1, 0, 0, 0},\ +/* u16FRPADResource */\ + EH_IO_Invalid,\ +/* aUserFuelFlowRateSpread */\ + {0, 1500, 3000, 4500, 6000, 7500, 9000, 10500, 12000, 13500, 15000, 16500, 18000, 19500, 21000, 22500, 24000},\ +/* aUserFuelFlowRateTable */\ + {0, 2995, 4234, 5187, 5990, 6696, 7335, 7923, 8548, 8985, 9471, 9932, 10376, 10800, 11207, 11601, 11981},\ +/* u8VariableFuelPressureEnable */\ + 0,\ +/* s32FuelPressureSensorGain */\ + 30000,\ +/* s32FuelPressureSensorOffset */\ + -760,\ +/* u16FuelPressurePGain */\ + 300,\ +/* u16FuelPressureIGain */\ + 100,\ +/* u8FuelPrimeEnable */\ + 0,\ + /* u16CRC16 */\ + 0x1234,\ + &au32Offsets\ +} + +#pragma GCC diagnostic pop diff --git a/source/Client/UNITS.c b/source/Client/UNITS.c new file mode 100644 index 0000000..e8e6f86 --- /dev/null +++ b/source/Client/UNITS.c @@ -0,0 +1,28 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Units File */ +/* DESCRIPTION: This code module SI typedefs for variables with */ +/* various resolutions */ +/* */ +/* FILE NAME: units.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#ifdef BUILD_KERNEL_APP + +#include +#include "sys.h" +#include "declarations.h" +#include "types.h" + +#endif //BUILD_KERNEL_APP + + + + diff --git a/source/Client/UNITS.h b/source/Client/UNITS.h new file mode 100644 index 0000000..f069020 --- /dev/null +++ b/source/Client/UNITS.h @@ -0,0 +1,71 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: Units Header File */ +/* DESCRIPTION: This code module SI typedefs for variables with */ +/* various resolutions */ +/* */ +/* FILE NAME: units.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#ifndef UNITS_H +#define UNITS_H + +#include +#include +#include +#include + + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +typedef uint16 GPM6_ttLambda; +typedef uint32 GPM6_ttVolts; +typedef uint32 GPM6_ttMilliVolts; +typedef uint32 GPM6_ttMicroVolts; +typedef uint32 GPM6_ttOhms; +typedef uint32 GPM6_ttAmps; +typedef sint32 GPM6_ttMilliAmps; +typedef sint32 GPM6_ttMicroAmps; +typedef uint32 GPM6_ttWatts; +typedef uint32 GPM6_ttMilliWatts; +typedef uint32 GPM6_ttMicroWatts; +typedef uint32 GPM6_ttKiloPa; +typedef uint32 GPM6_ttPa; +typedef uint32 GPM6_ttTheta; +typedef sint32 GPM6_ttThetaDT; +typedef uint32 GPM6_ttMTheta; +typedef sint32 GPM6_ttTempC; +typedef uint32 GPM6_ttPulseUs; +typedef uint32 GPM6_ttG; +typedef uint32 GPM6_ttNg; +typedef uint32 GPM6_ttUg; +typedef uint32 GPM6_ttMg; +typedef uint32 GPM6_ttCc; +typedef uint32 GPM6_ttMcc; +typedef uint32 GPM6_ttUcc; +typedef uint32 GPM6_ttHertz; +/*CR1_124*/ + +#define GPM6_ttLambdaMAXVAL USHRT_MAX +#define GPM6_ttVoltsMAXVAL UINT_MAX +#define GPM6_ttMilliVoltsMAXVAL UINT_MAX +#define GPM6_ttMicroVoltsMAXVAL UINT_MAX +#define GPM6_ttOhmsMAXVAL UINT_MAX +#define GPM6_ttAmpsMAXVAL UINT_MAX +#define GPM6_ttMilliAmpsMAXVAL INT_MAX +#define GPM6_ttMicroAmpsMAXVAL INT_MAX +#define GPM6_ttWattsMAXVAL UINT_MAX +#define GPM6_ttMilliWattsMAXVAL UINT_MAX +#define GPM6_ttMicroWattsMAXVAL UINT_MAX +#define GPM6_ttPaMAXVAL UINT_MAX +#define GPM6_ttThetaMAXVAL UINT_MAX +#define GPM6_ttTempCMAXVAL SINT_MAX + +#endif // UNITS_H + diff --git a/source/Client/USER.c b/source/Client/USER.c new file mode 100644 index 0000000..2dd0c13 --- /dev/null +++ b/source/Client/USER.c @@ -0,0 +1,111 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: User */ +/* DESCRIPTION: This code module initialises the required user */ +/* application task lists and the service call function */ +/* FILE NAME: USER.c */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#define _USER_C + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include + +#ifdef BUILD_USER + +#include "user.h" + +/* LOCAL MACRO DEFINITIONS ****************************************************/ +#define USER_nUserModuleCount sizeof(USER_rastUserModuleFunctions ) / sizeof(SYSAPI_tstUserModuleFunctions )/*CR1_75*/ + +/* LOCAL CONSTANT DEFINITIONS (STATIC) ****************************************/ +const SYSAPI_tstUserModuleFunctions USER_rastUserModuleFunctions[USER_enUserCount] = USER_nUserModuleFunctions; + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +bool USER_vStart(SYSAPI_tstSVCDataStruct* pstSVCDataStructArg) +{ + SYSAPI_tpfUserTaskFunction pfUserTask; + TASKAPI_tenPriority enPriority; + TASKAPI_tenRateMs enRateMs; + uint32 u32ModuleIDX; + bool boRetVal = false; + +#ifdef BUILD_USER_APP + memset((void*)USER_nVarsRAMBase, 0, USER_nVarsRAMSize);/*CR1_77*/ +#endif + + pstSVCDataStruct = pstSVCDataStructArg; + + /* Add all of the client start tasks */ + for (u32ModuleIDX = 0; u32ModuleIDX < USER_nUserModuleCount; u32ModuleIDX++) + { + pfUserTask = USER_rastUserModuleFunctions[u32ModuleIDX].pfStart; + if ((NULL!= pfUserTask) && (SYSAPI_enOK == pstSVCDataStruct->enSVCResult)) + { + enPriority = USER_rastUserModuleFunctions[u32ModuleIDX].enPriority; + enRateMs = USER_rastUserModuleFunctions[u32ModuleIDX].enRateMs; + USER_vSVC(SYSAPI_enSetClientStartTask, (void*)&pfUserTask, (void*)&enPriority, (void*)&enRateMs); + } + } + + /* Add all of the client cyclic tasks */ + for (u32ModuleIDX = 0; u32ModuleIDX < USER_nUserModuleCount; u32ModuleIDX++) + { + pfUserTask = USER_rastUserModuleFunctions[u32ModuleIDX].pfRun; + if ((NULL!= pfUserTask) && (SYSAPI_enOK == pstSVCDataStruct->enSVCResult)) + { + enPriority = USER_rastUserModuleFunctions[u32ModuleIDX].enPriority; + enRateMs = USER_rastUserModuleFunctions[u32ModuleIDX].enRateMs; + USER_vSVC(SYSAPI_enSetClientCyclicTask, (void*)&pfUserTask, (void*)&enPriority, (void*)&enRateMs); + } + } + + /* Add all of the terminate cyclic tasks */ + for (u32ModuleIDX = 0; u32ModuleIDX < USER_nUserModuleCount; u32ModuleIDX++) + { + pfUserTask = USER_rastUserModuleFunctions[u32ModuleIDX].pfRun; + if ((NULL!= pfUserTask) && (SYSAPI_enOK == pstSVCDataStruct->enSVCResult)) + { + enPriority = USER_rastUserModuleFunctions[u32ModuleIDX].enPriority; + enRateMs = USER_rastUserModuleFunctions[u32ModuleIDX].enRateMs; + USER_vSVC(SYSAPI_enSetClientTerminateTask, (void*)&pfUserTask, (void*)&enPriority, (void*)&enRateMs); + } + } + + if (SYSAPI_enOK == pstSVCDataStruct->enSVCResult) + { + boRetVal = true; + } + + return boRetVal; +} + +void USER_vRun(uint32 * const pu32Arg ) +{ + +} + +void USER_vTerminate(uint32* const pu32Arg ) +{ + +} + +void USER_vSVC(SYSAPI_tenSVCID enSVCID, void* pvArg1, void* pvArg2, void* pvArg3) +{ + pstSVCDataStruct->enSVCID = enSVCID; + pstSVCDataStruct->pvArg1 = pvArg1; + pstSVCDataStruct->pvArg2 = pvArg2; + pstSVCDataStruct->pvArg3 = pvArg3; + __asm("SVC 0x00"); +} + +#endif //BUILD_USER diff --git a/source/Client/USER.h b/source/Client/USER.h new file mode 100644 index 0000000..fa8f369 --- /dev/null +++ b/source/Client/USER.h @@ -0,0 +1,135 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: User Header File */ +/* DESCRIPTION: This code module initialises the required user */ +/* application task lists and the service call function */ +/* FILE NAME: USER.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#ifndef USER_H +#define USER_H + +#include /*CR1_76*/ +#include "AFM.h" +#include "BVM.h" +#include "CAM.h" +#include "CTS.h" +#include "ATS.h" +#include "DIAG.h" +#include "declarations.h" +#include "EST.h" +#include "FILM.h" +#include "FUEL.h" +#include "GENDATA.h" +#include "MAP.h" +#include "IAC.h" +#include "LSU4X.h" +#include "LSUH.h" +#include "RELAYS.h" +#include "SYSAPI.h" +#include "SENSORS.h" +#include "TPS.h" +#include "types.h" +#include "torque.h" +#include "USERCAL.h" +#include "sys.h" +#include "SYSAPI.h" + + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define USER_nUserModuleFunctions \ +{ \ + {NULL, NULL, NULL, NULL, TASKAPI_enTaskPrLowest, TASKAPI_enTask1ms}, \ + {&GENDATA_vStart, &GENDATA_vRun, &GENDATA_vTerminate, NULL, TASKAPI_enTaskPrLowest, TASKAPI_enTask1ms}, \ + {&MAP_vStart, &MAP_vRun, &MAP_vTerminate, &MAP_vCallBack, TASKAPI_enTaskPrLowest, TASKAPI_enTask1ms}, \ + {&AFM_vStart, &AFM_vRun, &AFM_vTerminate, &AFM_vCallBack, TASKAPI_enTaskPrLowest, TASKAPI_enTask1ms}, \ + {&TPS_vStart, &TPS_vRun, &TPS_vTerminate, &TPS_vCallBack, TASKAPI_enTaskPrLowest, TASKAPI_enTask1ms}, \ + {&BVM_vStart, &BVM_vRun, &BVM_vTerminate, &BVM_vCallBack, TASKAPI_enTaskPrLowest, TASKAPI_enTask1ms}, \ + {&CAM_vStart, &CAM_vRun, &CAM_vTerminate, &CAM_vCallBack, TASKAPI_enTaskPrLowest, TASKAPI_enTask10ms}, \ + {&FUEL_vStart, &FUEL_vRun, &FUEL_vTerminate, &FUEL_vCallBack, TASKAPI_enTaskPrLowest, TASKAPI_enTask1ms}, \ + {&CTS_vStart, &CTS_vRun, &CTS_vTerminate, &CTS_vCallBack, TASKAPI_enTaskPrLowest, TASKAPI_enTask1ms}, \ + {&ATS_vStart, &ATS_vRun, &ATS_vTerminate, &ATS_vCallBack, TASKAPI_enTaskPrLowest, TASKAPI_enTask1ms}, \ + {&EST_vStart, &EST_vRun, &EST_vTerminate, &EST_vCallBack, TASKAPI_enTaskPrLowest, TASKAPI_enTask1ms}, \ + {&IAC_vStart, &IAC_vRun, &IAC_vTerminate, &IAC_vCallBack, TASKAPI_enTaskPrLowest, TASKAPI_enTask25ms}, \ + {&USERDIAG_vStart, &USERDIAG_vRun, &USERDIAG_vTerminate, &USERDIAG_vCallBack, TASKAPI_enTaskPrLowest, TASKAPI_enTask1ms}, \ + {&SENSORS_vStart, &SENSORS_vRun, &SENSORS_vTerminate, &SENSORS_vCallBack, TASKAPI_enTaskPrLowest, TASKAPI_enTask1ms}, \ + {&FILM_vStart, &FILM_vRun, &FILM_vTerminate, &FILM_vCallBack, TASKAPI_enTaskPrLowest, TASKAPI_enTask10ms}, \ + {&RELAYS_vStart, &RELAYS_vRun, &RELAYS_vTerminate, &RELAYS_vCallBack, TASKAPI_enTaskPrLowest, TASKAPI_enTask2ms}, \ + {&TORQUE_vStart, &TORQUE_vRun, &TORQUE_vTerminate, NULL, TASKAPI_enTaskPrLowest, TASKAPI_enTask5ms}, \ + {&LSU4X_vStart, &LSU4X_vRun, &LSU4X_vTerminate, NULL, TASKAPI_enTaskPrLowest, TASKAPI_enTask1ms}, \ + {&LSUH_vStart, &LSUH_vRun, &LSUH_vTerminate, NULL, TASKAPI_enTaskPrLowest, TASKAPI_enTask1ms}, \ + {&USERCAL_vStart, &USERCAL_vRun, &USERCAL_vTerminate, NULL, TASKAPI_enTaskPrLowest, TASKAPI_enTask5ms}, \ +} + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _USER_C + #define EXTERN +#else + #define EXTERN extern +#endif + +#define USER_xEnterCritical()/*CR1_16*/ +#define USER_xExitCritical()/*CR1_16*/ + +#ifdef BUILD_ALLOW_CRITICAL + #undef USER_xEnterCritical + #undef USER_xExitCritical + #define USER_xEnterCritical CPU_xEnterCritical + #define USER_xExitCritical CPU_xExitCritical +#endif + +#define USER_nVarsRAMBase 0x20000000u +#define USER_nVarsRAMSize 0x2000u + + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +/******************************************************************************* +* Description : Type to enumerate the user application modules +*******************************************************************************/ +typedef enum +{ + USER_enUSER, + USER_enGENDATA, + USER_enMAP, + USER_enAFM, + USER_enTPS, + USER_enBVM, + USER_enCAM, + USER_enFUEL, + USER_enCTS, + USER_enATS, + USER_enEST, + USER_enIAC, + USER_enDIAG, + USER_enSENSORS, + USER_enFILM, + USER_enRELAYS, + USER_enTORQUE, + USER_enLSU4X, + USER_enLSUH, + USER_enUSERCAL, + USER_enUserCount +} USER_tenUserModules;/*CR1_126*/ + + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +EXTERN SYSAPI_tstSVCDataStruct* pstSVCDataStruct; + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +bool USER_vStart(SYSAPI_tstSVCDataStruct*); +void USER_vRun( uint32 * const pu32Arg );/*CR1_1*/ +void USER_vTerminate( uint32 * const pu32Arg );/*CR1_1*/ +void USER_vSVC(SYSAPI_tenSVCID enSVCID, void* pvArg1, void* pvArg2, void* pvArg3);/*CR1_1*/ + +#endif // USER_H + diff --git a/source/Client/USERCAL.c b/source/Client/USERCAL.c new file mode 100644 index 0000000..f76f6ca --- /dev/null +++ b/source/Client/USERCAL.c @@ -0,0 +1,120 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: USERCAL */ +/* DESCRIPTION: This code module initialises the user calibration */ +/* RAM mirror from the EEPROM or ROM image */ +/* */ +/* FILE NAME: USERCAL.c */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _USERCAL_C + +#include + +#ifdef BUILD_USER + +#include "USERCAL.h" + + +/* LOCAL CONSTANT DEFINITIONS (STATIC) ****************************************/ +const USERCAL_tstCalibration USERCAL_rstROMCAL = USERCAL_nROMCAL; +extern const uint32 au32Offsets[]; + + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +bool USERCAL_boPartitionOK; +uint16 USERCAL_u16ConfigCRC16; +//ASAM mode=readvalue name="USERCAL_ConfigCRC" type=uint16 offset=0 min=0 max=65535 m=1 b=0 units="dl" format=5.3 help="Working Calibration CRC" + + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +void USERCAL_vStart(puint32 const pu32Arg) +{ + puint8 pu8RAMData = (puint8)&USERCAL_stRAMCAL; + uint16 u16UserCalDataCount = sizeof(USERCAL_stRAMCAL); + bool boRetVal; + bool boCheckCRC16 = TRUE; + bool boNVMToWorking = FALSE; + + USERCAL_u16ConfigCRC16 = ~0; + + USER_vSVC(SYSAPI_enCheckPartition, (void*)NULL, + (void*)NULL, (void*)NULL); + + USERCAL_boPartitionOK = (SYSAPI_enOK == pstSVCDataStruct->enSVCResult); + + if (TRUE == USERCAL_boPartitionOK) + { + USER_vSVC(SYSAPI_enSetupWorkingPage, (void*)&pu8RAMData, + (void*)&u16UserCalDataCount, (void*)NULL); + + boRetVal = (SYSAPI_enOK == pstSVCDataStruct->enSVCResult); + + if (TRUE == boRetVal) + { + boNVMToWorking = TRUE; + USER_vSVC(SYSAPI_enNVMWorkingCopy, (void*)&boNVMToWorking, + (void*)&boCheckCRC16, (void*)NULL); + + boNVMToWorking = (SYSAPI_enOK == pstSVCDataStruct->enSVCResult); + } + } + + if (TRUE != boNVMToWorking) + /* If NVM to working page failed then boot ROM image */ + { + memcpy((void*)&USERCAL_stRAMCAL, (void*)&USERCAL_rstROMCAL, + sizeof(USERCAL_tstCalibration)); + + + USER_vSVC(SYSAPI_enSetupWorkingPage, (void*)&pu8RAMData, + (void*)&u16UserCalDataCount, (void*)NULL); + +#ifdef BUILD_KERNEL_APP + /* Only when KERNEL_APP testing */ + if (TRUE == USERCAL_boPartitionOK) + { + boNVMToWorking = FALSE; + USER_vSVC(SYSAPI_enNVMWorkingCopy, (void*)&boNVMToWorking, + (void*)&boCheckCRC16, (void*)NULL); + } +#endif + } +} + +void USERCAL_vRun(puint32 const pu32Arg) +{ + static uint32 u32UserConfigCRCCount = 0; + static uint16 u16ConfigCRC = ~0; + uint32 u32Len; + uint32 u32ConfigByteCount; + + u32ConfigByteCount = au32Offsets[(sizeof(au32Offsets) / sizeof(uint32*)) - 1]; + + if (u32UserConfigCRCCount < u32ConfigByteCount) + { + if (USERCAL_nCRCCheckChunkSize < (u32ConfigByteCount - u32UserConfigCRCCount)) + { + u16ConfigCRC = USERMATH_U16GetCRC(u16ConfigCRC, (puint8)((uint32)&USERCAL_stRAMCAL + u32UserConfigCRCCount), USERCAL_nCRCCheckChunkSize); + u32UserConfigCRCCount += USERCAL_nCRCCheckChunkSize; + } + else + { + u32Len = u32ConfigByteCount - u32UserConfigCRCCount; + USERCAL_u16ConfigCRC16 = USERMATH_U16GetCRC(u16ConfigCRC, (puint8)((uint32)&USERCAL_stRAMCAL + u32UserConfigCRCCount), u32Len); + u16ConfigCRC = ~0; + u32UserConfigCRCCount = 0; + } + } +} + +void USERCAL_vTerminate(puint32 const pu32Arg) +{ + +} + +#endif //BUILD_USER diff --git a/source/Client/USERCAL.h b/source/Client/USERCAL.h new file mode 100644 index 0000000..eb1c182 --- /dev/null +++ b/source/Client/USERCAL.h @@ -0,0 +1,1235 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: USERCAL Header File */ +/* DESCRIPTION: This code module initialises the user calibration */ +/* RAM mirror from the EEPROM or ROM image */ +/* */ +/* FILE NAME: USERCAL.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef USERCAL_H +#define USERCAL_H + +#include +#include +#include +#include +#include +#include +#include "SYSAPI.h" +#include "UNITS.h" +#include "user.h" + + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define USERCAL_nFlexRAMBASE 0x14000000 +#define USERCAL_nCRCCheckChunkSize 64 + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-braces" + +#define TESTCAL_off +#define C18CAL_off +#define KTM_SC_CAL_off +#define L98CAL_off +#define M15A_CAL_off +#define GOLF_MK6_CAL +#define TEST_60_M2_off +#define FIESTA_36_M1_off +#define TEENSY_ADAPT_BASEoff + +#ifdef TESTCAL +#include "TEST_CAL.h" +#endif + +#ifdef C18CAL +#include "C18_CAL.h" +#endif + +#ifdef L98CAL +#include "L98_CAL.h" +#endif + +#ifdef KTM_SC_CAL +#include "KTM_CAL_SCA.h" +#endif + +#ifdef M15A_CAL +#include "Suzuki_M15A.h" +#endif + +#ifdef GOLF_MK6_CAL +#include "Golf_Mk6.h" +#endif + +#ifdef TEST_60_M2 +#include "Test_60_M2.h" +#endif + +#ifdef FIESTA_36_M1 +#include "FIESTA_36_M1.h" +#endif + +#ifdef TEENSY_ADAPT_BASE +#include "teensy_adapt_base.h" +#endif //TEENSY_ADAPT_BASE + +#pragma GCC diagnostic pop + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _USERCAL_C + #define EXTERN +#else + #define EXTERN extern +#endif + + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +/******************************************************************************* +* Description : Type to the user calibration +*******************************************************************************/ + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wattributes" + +typedef struct +/* The usercal struct MUST be single and packed with CRC16 last two bytes + for the Kernel CRC16 NVM store and restore to function */ + /* CAVEAT!!! Make first element uint32 for %4 alignment!!! */ +{ + /* 0 */ + GPM6_ttVolts userCalADRefH; + GPM6_ttVolts userCalVRef445; + GPM6_ttVolts userCalVNernstTarget; + GPM6_ttOhms userCalRNernstReady; + GPM6_ttOhms userCalRHeaterThreshold; + uint32 au32UserCalPumpCurrentPFactor[1]; + uint32 au32UserCalPumpCurrentMFactor[1]; + sint32 ai32UserCalPumpCurrentOffset[1]; + GPM6_ttMicroAmps aUserCalPumpSpread[17]; + GPM6_ttLambda aUserCalPumpLambda[17]; + /* 1 */ + uint8 au8UserCalPumpSensorTrim[1]; + uint32 aUserStoichFuelCal; + uint8 au8UserCalPumpDeadband[1]; + uint16 au16UserCalFreeAirPoints[19]; + GPM6_ttAmps aUserHeaterAlarmCurrent[1]; + uint8 u8WarmUpDelay; + uint8 u8DisplayMode; + uint8 u8BackLightEnable; + GPM6_ttVolts userCalTPSCalMin; + GPM6_ttVolts userCalTPSCalMax; + /* 2 */ + GPM6_ttVolts aUserCURVEAfmTFSpread[17]; + GPM6_ttUg aUserCURVEAfmTFTable[17]; + GPM6_ttVolts aUserInjResponseSpread[17]; + uint16 aUserInjResponseTable[17]; + uint32 aUserCoolantSensorSpread[17]; + GPM6_ttTempC aUserCoolantSensorTable[17]; + GPM6_ttTempC aUserCoolantEnrichmentSpread[17]; + sint32 aUserCoolantEnrichmentTable[17]; + uint32 aUserTAFRxSpread[17]; + GPM6_ttMTheta aUserTAFRySpread[17]; + /* 3 */ + uint16 aUserMAPTAFR[17][17]; + uint32 aUserTimingxSpread[17]; + GPM6_ttMTheta aUserTimingySpread[17]; + uint16 aUserTimingMap[17][17]; + uint32 aUserVExSpread[17]; + GPM6_ttKiloPa aUserVEySpread[17]; + uint16 aUserMAPVE[17][17]; + GPM6_ttTempC aUserCoolantStartEnrichmentSpread[17]; + sint32 aUserCoolantStartEnrichmentTable[17]; + GPM6_ttTempC aUserCoolantPostStartEnrichmentSpread[17]; + /* 4 */ + sint32 aUserCoolantPostStartEnrichmentTable[17]; + uint32 aUserCrankingAirflowSpread[17]; + uint16 aUserCrankingAirflowTable[17]; + uint32 aUserDwellSpread[17]; + uint16 aUserDwellTable[17]; + GPM6_ttTempC aUserAirTempCorrectionSpread[17]; + uint16 aUserAirTempCorrectionTable[17]; + uint32 aUserTPSMovementCorrectionSpread[17]; + uint16 aUserTPSMovementCorrectionTable[17]; + uint32 aUserInjectionPhasingSpread[17]; + /* 5 */ + uint16 aUserInjectionPhasingTable[17]; + GPM6_ttTempC aUserCTSTimingCorrectionSpread[17]; + uint16 aUserCTSTimingCorrectionTable[17]; + GPM6_ttTempC aUserATSTimingCorrectionSpread[17]; + uint16 aUserATSTimingCorrectionTable[17]; + GPM6_ttTempC aUserISCSpeedTargetSpread[17]; + uint16 aUserISCSpeedTargetTable[17]; + uint8 aUserStepperCloseTable[4]; + uint8 aUserStepperOpenTable[4]; + uint32 u32UserStepperHomeSteps; + /* 6 */ + uint16 aUserPrimaryTriggerTable[80]; + uint16 aUserSecondaryTriggerTable[40]; + uint16 aUserSyncPointsTable[36]; + uint8 u8UserPrimaryEdgeSetup; + uint8 u8UserSecondaryEdgeSetup; + uint8 u8UserPrimaryVREnable; + uint8 u8UserSecondaryVREnable; + uint8 u8UserFirstEdgeRisingPrimary; + uint8 u8UserFirstEdgeRisingSecondary; + uint32 au32InjectionSequence[4]; + /* 7 */ + uint32 au32IgnitionSequence[4]; + IOAPI_tenEHIOResource enSimpleCamSyncSource; + bool boCamSyncHighLate; + uint32 u32CamSyncSampleToothCount; + uint16 u16ManifoldVolumeCC; + uint8 u8CylCount; + uint16 u16InjFlowRate; + uint32 aUserBackupAirflowxSpread[11]; + uint32 aUserBackupAirflowySpread[11]; + uint32 aUserBackupAirflowMap[11][11]; + /* 8 */ + uint8 u8ManifoldTimeConstantTrim; + uint8 u8EnableBackupAirflowTransients; + sint32 aUserPrimerSpread[11]; + uint32 aUserPrimerTable[11]; + uint32 aUserInjShortOpeningSpread[11]; + uint32 aUserInjShortOpeningTable[11]; + uint32 u32STTNegLimit; + uint32 u32STTPosLimit; + uint32 u32CLStepClosed; + uint32 u32CLIncClosed; + /* 9 */ + uint32 u32CLStepOpen; + uint32 u32CLIncOpen; + uint16 u16TimingMainOffset; + uint32 u32AFMTransientControlRPMLimit; + uint8 u8WastedSparkEnable; + uint16 u16AFRReinstate; + uint16 u16AFRCutoff; + uint32 u32TPSClosedLower; + uint32 u32TPSClosedUpper; + uint32 u32ISCESTTrimPos; + /* 10 */ + uint32 u32ISCESTTrimNeg; + uint32 u32CLO2ESTTrimPos; + uint32 u32CLO2ESTTrimNeg; + uint16 u16CylinderCC; + uint8 u8EnableAFMPrimaryInputOpen; + uint32 u32SpeedDensityAFMTPSLim; + uint16 au16SeqRPMLimit[8]; + uint16 u16SeqRPMLimitHyst; + uint16 u16HighVacuumEnableKpa; + uint16 u16HighVacuumDisableKpa; + /* 11 */ + uint16 u16OverrunCutEnableRPM; + uint16 u16OverrunCutDisableRPM; + uint16 u16RPMRunThreshold; + uint8 u8SeqFuelAssign; + uint16 u16ESTFilterClosed; + uint16 u16ESTFilterOpen; + uint16 u16ESTCLGain; + uint8 u8EnableAFMPrimaryInputClosed; + sint16 s16SequenceFuelOffset[4]; + uint16 u16SequenceFuelGain[4]; + /* 12 */ + bool boTPSCANPrimary; + bool boPPSCANPrimary; + bool boCTSCANPrimary; + bool boATSCANPrimary; + bool boMAPCANPrimary; + uint32 au32PrioCANID[4]; + uint8 au8SensorCANDataOffset[8]; + uint8 au8SensorCANDataByteCount[8]; + uint32 u32SyncPhaseRepeats; + sint32 s32MapSensorGain; + /* 13 */ + sint32 s32MapSensorOffset; + uint8 u8InjDivide; + uint8 u8CLO2Leftenable; + uint8 u8CLO2RightEnable; + uint8 u8ReturnlessEnable; + uint16 u16ReturnlessPressureKPa; + uint8 u8CrankingAirflowEnable; + uint8 u8StepperIACEnable; + uint16 u16IACStepsOpenHot; + uint16 u16IACStepsOpenCold; + /* 14 */ + uint16 u16IdleEntryOffset; + GPM6_ttTempC s32RadFanOnTemp; + GPM6_ttTempC s32RadFanOffTemp; + IOAPI_tenEHIOResource enFuelPumpRelay; + IOAPI_tenEHIOResource enESTBypass; + uint32 aUserAirSensorSpread[17]; + GPM6_ttTempC aUserAirSensorTable[17]; + uint16 aFuelIOResource[4]; + uint16 aESTIOResource[4]; + uint16 aIACIOResource[4]; + bool boOBDISCADV; + uint8 u8TriggerType; + uint8 u8SyncType; + uint8 u8TriggerPullStrength; + uint8 u8SyncPullStrength; + uint16 u16MinLinearFuelPulse; + uint16 u16CTSADResource; + uint16 u16MAPADResource; + uint16 u16ATSADResource; + uint16 u16AFMADResource; + uint16 u16TPSADResource; + uint32 aUserTipInCorrectionSpread[17]; + uint16 aUserTipInCorrectionTable[17]; + uint32 aLogicBlockVar[8]; + uint32 aLogicBlockOperand[8]; + uint16 aLogicBlockChainOutput[8]; + IOAPI_tenEHIOResource enThermoFanRelay; + uint16 aESTIOMuxResource[4]; + bool boUEGOCANPrimary; + uint16 aPWM2DAxesSourceXIDX[8]; + uint16 aPWM3DAxesSourceXIDX[4]; + uint16 aPWM3DAxesSourceYIDX[4]; + uint16 aPWM2DIOOutputResource[8]; + uint16 aPWM3DIOOutputResource[4]; + sint32 aUserPWM2D_1SpreadX[17]; + sint32 aUserPWM2D_2SpreadX[17]; + sint32 aUserPWM2D_3SpreadX[17]; + sint32 aUserPWM2D_4SpreadX[17]; + sint32 aUserPWM2D_5SpreadX[17]; + sint32 aUserPWM2D_6SpreadX[17]; + sint32 aUserPWM2D_7SpreadX[17]; + sint32 aUserPWM2D_8SpreadX[17]; + uint16 aUserPWM2D_1Data[17]; + uint16 aUserPWM2D_2Data[17]; + uint16 aUserPWM2D_3Data[17]; + uint16 aUserPWM2D_4Data[17]; + uint16 aUserPWM2D_5Data[17]; + uint16 aUserPWM2D_6Data[17]; + uint16 aUserPWM2D_7Data[17]; + uint16 aUserPWM2D_8Data[17]; + sint32 aUserPWM3D_1SpreadX[17]; + sint32 aUserPWM3D_2SpreadX[17]; + sint32 aUserPWM3D_3SpreadX[17]; + sint32 aUserPWM3D_4SpreadX[17]; + sint32 aUserPWM3D_1SpreadY[17]; + sint32 aUserPWM3D_2SpreadY[17]; + sint32 aUserPWM3D_3SpreadY[17]; + sint32 aUserPWM3D_4SpreadY[17]; + uint16 aUserPWM3D_1Data[17][17]; + uint16 aUserPWM3D_2Data[17][17]; + uint16 aUserPWM3D_3Data[17][17]; + uint16 aUserPWM3D_4Data[17][17]; + uint16 u16FuelPressureSolenoidResource; + uint8 u8VCTABPullupEnable; + uint8 u8VCTCDPullupEnable; + uint16 aVVTInputResource[4]; + uint8 aVVTInputType[4]; + uint16 u16FRSADResource; + uint32 aUserFuelFlowRateSpread[17]; + uint16 aUserFuelFlowRateTable[17]; + uint8 u8VariableFuelPressureEnable; + sint32 s32FuelPressureSensorGain; + sint32 s32FuelPressureSensorOffset; + uint16 u16FuelPressurePGain; + uint16 u16FuelPressureIGain; + uint8 u8FuelPrimeEnable; + uint16 aUserTimingMapStage1[17][17]; + uint32 aUserTorquePedalTransferSpread[17]; + uint16 aUserTorquePedalTransferTable[17]; + sint32 aUserPressureValveFeedForwardSpread[17]; + uint16 aUserPressureValveFeedForwardTable[17]; + uint16 u16AFMMaxCycleDeltaUgPos; + uint16 u16AFMMaxCycleDeltaUgNeg; + uint16 aUserPWM2DPeriod[8]; + uint16 aUserPWM3DPeriod[4]; + uint8 u8FuelPumpPrimerTime; + uint8 u8DBSlaveConfig; + uint8 u8DBSlaveOptions; + uint16 u16AFRADResource; + uint16 u16PPSMADResource; + uint16 u16PPSSADResource; + uint16 au16AuxInputResource[4]; + uint16 au16AuxInputFunction[4]; + sint32 s32AFRADInputGain; + sint32 s32AFRADInputOffset; + uint16 u16AFRFuelTypeGain; + uint32 aUserFuelCutsSpread[17]; + uint16 aUserFuelCutsTable[17]; + uint16 au16AuxInputLowThres[4]; + uint16 au16AuxInputHighThres[4]; + uint16 u16FuelPressureControlOffset; + uint16 u16FuelPressureControlStartOffset; + uint32 aUserTimingSecondary1xSpread[17]; + GPM6_ttMTheta aUserTimingSecondary1ySpread[17]; + uint16 u16ISCColdISCMin; + uint16 u16ISCColdISCMax; + uint16 u16ISCHotISCMin; + uint16 u16ISCHotISCMax; + uint16 u16GDIValveMin; + uint16 u16GDIValveMax; + uint16 u16GDIValveFF; + uint32 aUserPedalTransferSpread[17]; + uint16 aUserPedalTransferTable[17]; + uint16 u16PressureControlThreshold; + uint16 u16ThrottlePressureControlCal; + uint16 u16PressureControlHyst; + uint8 u8BoostChargeMAPEnable; + uint16 u16BoostChargeTPSLimit; + uint16 u16ISCEntryRamp; + uint16 u16ISCPostStartRamp; + uint32 u32AirflowFMELimitLow; + uint32 u32AirflowFMELimitHigh; + uint16 u16TorqueReductionMaxDuration; + uint16 u16StallSaverRPMThreshold; + uint32 aUserETCScaleSpread[17]; + uint16 aUserETCScaleTable[17]; + uint16 u16TorqueReductionMaxFuelCut; + uint16 u16ShiftCountLimit; + uint16 au16BoostTarget[6]; + uint16 u16GDIPressureMin; + uint16 u16GDIPressureMax; + uint32 u32GDIMAPMin; + uint32 u32GDIMAPMax; + uint16 u16ESTPosRateMax; + uint16 u16ESTNegRateMax; + uint16 u16PressureControlDPos; + uint16 u16PressureControlDNeg; + uint16 u16ShiftCountPressureControlLimit; + uint16 u16ShiftPressureControl; + uint16 aPWM3DSlowIOOutputResource[4]; + uint16 aPWM3DSlowPeriod[4]; + uint16 u16SensorHystLimitRPM; + GPM6_ttVolts userCalPPSCalMin; + GPM6_ttVolts userCalPPSCalMax; + uint32 aUserPseudoMAPxSpread[17]; + uint32 aUserPseudoMAPySpread[17]; + uint32 aUserPseudoMAPMap[17][17]; + uint8 u8PseudoMAPEnable; + uint16 u16VSSPerRPM[8]; + uint16 u16VSSCANCal; + uint16 u16ETCOverrideKeys; + uint16 u16ETCOverride; + uint16 u16DiagType; + uint16 u16CRC16; + uint8* offsets; +} BUILD_PACKING USERCAL_tstCalibration; + + +/* GLOBAL VARIABLE DECLARATIONS ***********************************************/ +/* NOTE MUST ALWAYS INCLUDE CAL STRUCT ELEMENTS ONE FOR ONE AND IN ORDER */ +EXTERN USERCAL_tstCalibration BUILD_PACKING USERCAL_stRAMCAL; +// +// +#pragma GCC diagnostic pop// +// +// 0 +//ASAM mode=writevalue name="AD RefH Voltage" parent="USERCAL_stRAMCAL" type=uint32 offset=0 min=0 max=5 m=0.001 b=0 units="V" format=4.3 help="AD Converter Reference High Voltage HTML=001.HTML" +//ASAM mode=writevalue name="User Cal VRef 445" parent="USERCAL_stRAMCAL" type=uint32 offset=4 min=0 max=5 m=0.001 b=0 units="TBC" format=4.3 help="TBC HTML=002.HTML" +//ASAM mode=writevalue name="Cal VNernst Target" parent="USERCAL_stRAMCAL" type=uint32 offset=8 min=0 max=5 m=0.001 b=0 units="TBC" format=4.3 help="TBC HTML=003.HTML" +//ASAM mode=writevalue name="Cal RNernst Ready" parent="USERCAL_stRAMCAL" type=uint32 offset=12 min=0 max=5 m=0.001 b=0 units="TBC" format=4.3 help="TBC HTML=004.HTML" +//ASAM mode=writevalue name="Uego Heater Rth" parent="USERCAL_stRAMCAL" type=uint32 offset=16 min=0 max=10 m=0.001 b=0 units="Ohms" format=4.3 help="Uego Heater Resistance Threshold HTML=005.HTML" +//ASAM mode=writevalue name="Uego1 Current P Cal" parent="USERCAL_stRAMCAL" type=uint32 offset=20 min=0 max=5000000 m=1 b=0 units="dl" format=6.0 help="Uego1 Current P Calibration (dimensionless) HTML=006.HTML" +//ASAM mode=writevalue name="Uego1 Current M Cal" parent="USERCAL_stRAMCAL" type=uint32 offset=24 min=0 max=5000000 m=1 b=0 units="dl" format=6.0 help="Uego1 Current M Calibration (dimensionless) HTML=007.HTML" +//ASAM mode=writevalue name="Uego1 Offset Cal" parent="USERCAL_stRAMCAL" type=sint32 offset=28 min=-5000000 max=5000000 m=1 b=0 units="dl" format=6.0 help="Uego1 Offset Calibration (dimensionless) HTML=008.HTML" +//ASAM mode=writeaxis_pts name="Uego Pump Current Table_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=32 min=-5000000 max=5000000 m=0.000001 b=0 units="mA" format=7.6 help="Uego Pump Current X Axis HTML=009.HTML" xcount=17 xindexvar="Pump Current 1" +//ASAM mode=writecurve name="Uego Pump Current Table" parent="USERCAL_stRAMCAL" type=uint16 offset=100 min=0 max=5 m=0.001 b=0 units="dl" format=4.3 help="Uego Pump Current Curve HTML=010.HTML" xcount=17 xindexvar="Pump Current 1" +// 1 +//ASAM mode=writevalue name="Uego1 Sensor Trim" parent="USERCAL_stRAMCAL" type=uint8 offset=134 min=0 max=255 m=1 b=0 units="dl" format=3.0 help="Uego1 Sensor Trim HTML=011.HTML" +//ASAM mode=writevalue name="Uego1 Stoich Cal" parent="USERCAL_stRAMCAL" type=uint32 offset=135 min=0 max=2000 m=1 b=0 units="dl" format=3.0 help="Uego1 Stoich Cal HTML=012.HTML" +//ASAM mode=writevalue name="User Cal Pump Deadband" parent="USERCAL_stRAMCAL" type=uint8 offset=139 min=0 max=2000 m=1 b=0 units="dl" format=3.0 help="TBC HTML=013.HTML" +//ASAM mode=writevalue name="User Cal Free Air Points" parent="USERCAL_stRAMCAL" type=uint16 offset=140 min=0 max=2000 m=1 b=0 units="dl" format=3.0 help="TBC HTML=014.HTML" +//ASAM mode=writevalue name="UserHeaterAlarmCurrent" parent="USERCAL_stRAMCAL" type=uint32 offset=168 min=0 max=2000 m=1 b=0 units="dl" format=3.0 help="TBC HTML=015.HTML" +//ASAM mode=writevalue name="Warm Up Delay" parent="USERCAL_stRAMCAL" type=uint8 offset=172 min=0 max=2000 m=1 b=0 units="dl" format=3.0 help="TBC HTML=016.HTML" +//ASAM mode=writevalue name="Display Mode" parent="USERCAL_stRAMCAL" type=uint8 offset=173 min=0 max=2000 m=1 b=0 units="dl" format=3.0 help="TBC HTML=017.HTML" +//ASAM mode=writevalue name="Back Light Enable" parent="USERCAL_stRAMCAL" type=uint8 offset=174 min=0 max=2000 units="ENUMERATION OFF=0 ON=1" format=3.0 help="TBC HTML=018.HTML" +//ASAM mode=writevalue name="TPS Cal Min" parent="USERCAL_stRAMCAL" type=uint32 offset=178 min=0 max=5 m=0.001 b=0 units="V" format=3.2 help="TPS voltage at min throttle position or neutral ETC position HTML=019.HTML" +//ASAM mode=writevalue name="TPS Cal Max" parent="USERCAL_stRAMCAL" type=uint32 offset=189 min=0 max=5 m=0.001 b=0 units="V" format=3.2 help="TPS voltage at maximum throttle position HTML=020.HTML" +// 2 +//ASAM mode=writeaxis_pts name="AfmTF Table_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=193 min=0 max=300000 m=0.001 b=0 units="V" format=7.6 help="Air Flow Meter calibration curve x-axis points array HTML=021.HTML" xcount=17 xindexvar="AFM Sensor Voltage" +//ASAM mode=writecurve name="AfmTF Table" parent="USERCAL_stRAMCAL" type=uint32 offset=261 min=0 max=400 m=0.000001 b=0 units="g/s" format=4.3 help=Air Flow Meter calibration curve data points array HTML=022.HTML" xcount=17 xindexvar="AFM Sensor Voltage" +//ASAM mode=writeaxis_pts name="Inj Response Table_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=329 min=0 max=20000 m=0.001 b=0 units="V" format=4.3 help="Injector response curve x-axis points array HTML=023.HTML" xcount=17 xindexvar="Battery Voltage" +//ASAM mode=writecurve name="Inj Response Table" parent="USERCAL_stRAMCAL" type=uint16 offset=397 min=0 max=3 m=0.001 b=0 units="ms" format=4.3 help="Injector response curve data points array HTML=024.HTML" xcount=17 xindexvar="Battery Voltage" +//ASAM mode=writeaxis_pts name="Coolant Sensor Table_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=431 min=0 max=5 m=1 b=0 units="V" format=7.0 help="Coolant sensor calibration curve x-axis points array HTML=025.HTML" xcount=17 xindexvar="CTS Sensor Voltage" +//ASAM mode=writecurve name="Coolant Sensor Table" parent="USERCAL_stRAMCAL" type=sint32 offset=499 min=-40 max=200 m=0.001 b=0 units="degrees C" format=4.3 help="Coolant sensor calibration curve data points array HTML=026.HTML" xcount=17 xindexvar="CTS Sensor Voltage" +//ASAM mode=writeaxis_pts name="CTS Enrichment Table_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=567 min=0 max=200 m=0.001 b=0 units="degrees C" format=4.3 help="CTS Enrichment X Axis HTML=027.HTML" xcount=17 xindexvar="Coolant Temperature" +//ASAM mode=writecurve name="CTS Enrichment Table" parent="USERCAL_stRAMCAL" type=sint32 offset=635 min=-1 max=3 m=0.001 b=0 units="%" format=4.3 help="CTS Enrichment Curve HTML=028.HTML" xcount=17 xindexvar="Coolant Temperature" +//ASAM mode=writeaxis_pts name="TAFR Map_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=703 min=0 max=8000 m=1 b=0 units="RPM" format=4.0 help="VE MAP Y Axis HTML=029.HTML" xcount=17 xindexvar="Engine Speed Raw" +//ASAM mode=writeaxis_pts name="TAFR Map_YAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=771 min=0 max=110000 m=0.001 b=0 units="kPa" format=3.1 help="VE MAP X Axis HTML=030.HTML" xcount=17 xindexvar="MAP kPa" +// 3 +//ASAM mode=writemap name="TAFR Map" parent="USERCAL_stRAMCAL" type=uint16 offset=839 min=0 max=20 m=0.01 b=0 units="dl" format=4.3 help="TAFR Map HTML=031.HTML" xcount=17 xindexvar="Engine Speed Raw" ycount=17 yindexvar="Throttle Angle" +//ASAM mode=writeaxis_pts name="Timing Map_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=1417 min=0 max=8000 m=1 b=0 units="RPM" format=4.0 help="VE MAP Y Axis HTML=032.HTML" xcount=17 xindexvar="Engine Speed Raw" +//ASAM mode=writeaxis_pts name="Timing Map_YAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=1485 min=0 max=110000 m=0.001 b=0 units="kPa" format=3.1 help="VE MAP X Axis HTML=033.HTML" xcount=17 xindexvar="MAP kPa" +//ASAM mode=writemap name="Timing Map" parent="USERCAL_stRAMCAL" type=uint16 offset=1553 min=0 max=50 m=0.1 b=0 units="Degrees" format=3.1 help="Timing Map HTML=034.HTML" xcount=17 xindexvar="Engine Speed Raw" ycount=17 yindexvar="MAP kPa" +//ASAM mode=writeaxis_pts name="VE Map_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=2131 min=0 max=8000 m=1 b=0 units="RPM" format=4.0 help="VE MAP Y Axis HTML=035.HTML" xcount=17 xindexvar="Engine Speed Raw" +//ASAM mode=writeaxis_pts name="VE Map_YAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=2199 min=0 max=110000 m=0.001 b=0 units="kPa" format=3.1 help="VE MAP X Axis HTML=036.HTML" xcount=17 xindexvar="MAP kPa" +//ASAM mode=writemap name="VE Map" parent="USERCAL_stRAMCAL" type=uint16 offset=2267 min=50 max=150 m=0.1 b=0 units="%" format=4.1 help="VE Map HTML=037.HTML" xcount=17 xindexvar="Engine Speed Raw" ycount=17 yindexvar="MAP kPa" +//ASAM mode=writeaxis_pts name="CTS Start Enrichment Table_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=2845 min=0 max=200 m=0.001 b=0 units="degrees C" format=4.3 help="CTS Start Enrichment X Axis HTML=038.HTML" xcount=17 xindexvar="Coolant Temperature" +//ASAM mode=writecurve name="CTS Start Enrichment Table" parent="USERCAL_stRAMCAL" type=sint32 offset=2913 min=0 max=4 m=0.001 b=0 units="%" format=4.3 help="CTS Start Enrichment Curve HTML=039.HTML" xcount=17 xindexvar="Coolant Temperature" +//ASAM mode=writeaxis_pts name="CTS Post Start Enrichment Table_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=2981 min=0 max=200 m=0.001 b=0 units="degrees C" format=4.3 help="CTS Post Start Enrichment X Axis HTML=040.HTML" xcount=17 xindexvar="Coolant Temperature" +// 4 +//ASAM mode=writecurve name="CTS Post Start Enrichment Table" parent="USERCAL_stRAMCAL" type=sint32 offset=3049 min=0 max=4 m=0.001 b=0 units="%" format=4.3 help="CTS Post Start Enrichment Curve HTML=041.HTML" xcount=17 xindexvar="Coolant Temperature" +//ASAM mode=writeaxis_pts name="Cranking Airflow Table_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=3117 min=0 max=8000 m=1 b=0 units="RPM" format=4.3 help="Cranking Airflow X Axis HTML=042.HTML" xcount=17 xindexvar="Engine Speed Raw" +//ASAM mode=writecurve name="Cranking Airflow Table" parent="USERCAL_stRAMCAL" type=uint16 offset=3185 min=0 max=65.535 m=0.001 b=0 units="g/s" format=4.3 help="Cranking Airflow Curve HTML=043.HTML" xcount=17 xindexvar="Engine Speed Raw" +//ASAM mode=writeaxis_pts name="Dwell Table_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=3219 min=0 max=20000 m=0.001 b=0 units="V" format=4.3 help="Dwell X Axis HTML=044.HTML" xcount=17 xindexvar="Battery Voltage" +//ASAM mode=writecurve name="Dwell Table" parent="USERCAL_stRAMCAL" type=uint16 offset=3287 min=0 max=10 m=0.001 b=0 units="ms" format=4.3 help="Dwell Curve HTML=045.HTML" xcount=17 xindexvar="Battery Voltage" +//ASAM mode=writeaxis_pts name="ATS Fuel Correction Table_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=3321 min=0 max=20 m=0.001 b=0 units="V" format=4.3 help="ATS Fuel Correction X Axis HTML=046.HTML" xcount=17 xindexvar="Air Temperature" +//ASAM mode=writecurve name="ATS Fuel Correction Table" parent="USERCAL_stRAMCAL" type=uint16 offset=3389 min=0 max=2 m=0.001 b=0 units="%" format=4.3 help="ATS Fuel Correction Curve HTML=047.HTML" xcount=17 xindexvar="Air Temperature" +//ASAM mode=writeaxis_pts name="TPS Movement Correction Table_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=3423 min=-450 max=450 m=0.001 b=0 units="Degrees/s" format=4.3 help="TPS Movement Correction X Axis HTML=048.HTML" xcount=17 xindexvar="TPS Movement Rate" +//ASAM mode=writecurve name="TPS Movement Correction Table" parent="USERCAL_stRAMCAL" type=uint16 offset=3491 min=0 max=2 m=0.001 b=0 units="%" format=6.3 help="TPS Movement Correction Curve HTML=049.HTML" xcount=17 xindexvar="TPS Movement Rate" +//ASAM mode=writeaxis_pts name="Injection Phasing Table_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=3525 min=0 max=20000 m=0.001 b=0 units="RPM" format=4.3 help="Injection Phasing X Axis HTML=050.HTML" xcount=17 xindexvar="Engine Speed Raw" +// 5 +//ASAM mode=writecurve name="Injection Phasing Table" parent="USERCAL_stRAMCAL" type=uint16 offset=3593 min=0 max=20 m=0.001 b=0 units="ms" format=4.3 help="Injection Phasing Curve HTML=281.HTML" xcount=17 xindexvar="Engine Speed Raw" +//ASAM mode=writeaxis_pts name="CTS Timing Correction Table_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=3627 min=0 max=200 m=0.001 b=0 units="degrees C" format=4.3 help="CTS Timing Correction X Axis HTML=051.HTML" xcount=17 xindexvar="Coolant Temperature" +//ASAM mode=writecurve name="CTS Timing Correction Table" parent="USERCAL_stRAMCAL" type=sint16 offset=3695 min=-10 max=10 m=0.1 b=0 units="Degrees" format=4.3 help="CTS Timing Correction Curve HTML=052.HTML" xcount=17 xindexvar="Coolant Temperature" +//ASAM mode=writeaxis_pts name="ATS Timing Correction Table_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=3729 min=0 max=200 m=0.001 b=0 units="degrees C" format=4.3 help="ATS Timing Correction X Axis HTML=053.HTML" xcount=17 xindexvar="Air Temperature" +//ASAM mode=writecurve name="ATS Timing Correction Table" parent="USERCAL_stRAMCAL" type=sint16 offset=3797 min=-10 max=10 m=0.1 b=0 units="Degrees" format=4.3 help="ATS Timing Correction Curve HTML=054.HTML" xcount=17 xindexvar="Air Temperature" +//ASAM mode=writeaxis_pts name="ISC Target Table_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=3831 min=0 max=200 m=0.001 b=0 units="degrees C" format=4.3 help="ISC Target X Axis HTML=055.HTML" xcount=17 xindexvar="Coolant Temperature" +//ASAM mode=writecurve name="ISC Target Table" parent="USERCAL_stRAMCAL" type=uint16 offset=3899 min=0 max=2000 m=1 b=0 units="RPM" format=4.3 help="ISC Target Curve HTML=056.HTML" xcount=17 xindexvar="Coolant Temperature" +//ASAM mode=writevalue name="User Stepper Close Table" parent="USERCAL_stRAMCAL" type=uint32 offset=3933 min=0 max=2000 m=1 b=0 units="dl" format=3.0 help="TBC HTML=057.HTML" +//ASAM mode=writevalue name="User Stepper Open Table" parent="USERCAL_stRAMCAL" type=uint32 offset=3937 min=0 max=2000 m=1 b=0 units="dl" format=3.0 help="TBC HTML=058.HTML" +//ASAM mode=writevalue name="User Stepper Home Steps" parent="USERCAL_stRAMCAL" type=uint32 offset=3941 min=0 max=2000 m=1 b=0 units="dl" format=3.0 help="TBC HTML=059.HTML" +// 6 +//ASAM mode=writeblob name="Primary Trigger Table" parent="USERCAL_stRAMCAL" type=uint16 offset=3945 min=1 max=65535 m=1 b=0 units="dl" format=5.0 pointcount=80 help="Primary Trigger Tooth Setup HTML=060.HTML" +//ASAM mode=writeblob name="Secondary Trigger Table" parent="USERCAL_stRAMCAL" type=uint16 offset=4105 min=1 max=65535 m=1 b=0 units="dl" format=5.0 pointcount=40 help="Secondary Trigger Tooth Setup HTML=061.HTML" +//ASAM mode=writeblob name="Sync Points Table" parent="USERCAL_stRAMCAL" type=uint16 offset=4185 min=1 max=65535 m=1 b=0 units="dl" format=5.0 pointcount=36 help="Syncronisation Points Setup HTML=062.HTML" +//ASAM mode=writevalue name="Primary Edge Setup" parent="USERCAL_stRAMCAL" type=uint8 offset=4257 min=0 max=255 units="ENUMERATION RISING=0 FALLING=1 ANY=2" format=5.0 help="Primary Edge Setup HTML=063.HTML" +//ASAM mode=writevalue name="Secondary Edge Setup" parent="USERCAL_stRAMCAL" type=uint8 offset=4258 min=0 max=255 units="ENUMERATION RISING=0 FALLING=1 ANY=2" format=5.0 help="Secondary Edge Setup HTML=064.HTML" +//ASAM mode=writevalue name="Primary VR Enable" parent="USERCAL_stRAMCAL" type=uint8 offset=4259 min=0 max=255 units="ENUMERATION OFF=0 ON=1" format=5.0 help="Primary VR Circuit Enabl HTML=065.HTMLe" +//ASAM mode=writevalue name="Secondary VR Enable" parent="USERCAL_stRAMCAL" type=uint8 offset=4260 min=0 max=255 units="ENUMERATION OFF=0 ON=1" format=5.0 help="Secondary VR Circuit Enable HTML=066.HTML" +//ASAM mode=writevalue name="First Edge Rising Primary" parent="USERCAL_stRAMCAL" type=uint8 offset=4261 min=0 max=255 units="ENUMERATION FALSE=0 TRUE=1" format=3.0 help="First Edge Rising Primary HTML=067.HTML" +//ASAM mode=writevalue name="First Edge Rising Secondary" parent="USERCAL_stRAMCAL" type=uint8 offset=4262 min=0 max=255 units="ENUMERATION FALSE=0 TRUE=1" format=3.0 help="First Edge Rising Secondary HTML=068.HTML" +//ASAM mode=writevalue name="Injection Sequence AE" parent="USERCAL_stRAMCAL" type=uint32 offset=4263 min=0 max=65535 units="ENUMERATION BATCH_POS1st=4 BATCH_POS2nd=261 BATCH_POS3rd=518 BATCH_POS4th=775 SEQ_POS3rd=65280 SEQ_POS4th=65282 SEQ_POS1st=65284 SEQ_POS2nd=65286 SEQ_UNUSED=65535" format=3.0 help="TBC HTML=069.HTML" +//ASAM mode=writevalue name="Injection Sequence BF" parent="USERCAL_stRAMCAL" type=uint32 offset=4267 min=0 max=65535 units="ENUMERATION BATCH_POS1st=4 BATCH_POS2nd=261 BATCH_POS3rd=518 BATCH_POS4th=775 SEQ_POS3rd=65280 SEQ_POS4th=65282 SEQ_POS1st=65284 SEQ_POS2nd=65286 SEQ_UNUSED=65535" format=3.0 help="TBC HTML=070.HTML" +//ASAM mode=writevalue name="Injection Sequence CG" parent="USERCAL_stRAMCAL" type=uint32 offset=4271 min=0 max=65535 units="ENUMERATION BATCH_POS1st=4 BATCH_POS2nd=261 BATCH_POS3rd=518 BATCH_POS4th=775 SEQ_POS3rd=65280 SEQ_POS4th=65282 SEQ_POS1st=65284 SEQ_POS2nd=65286 SEQ_UNUSED=65535" format=3.0 help="TBC HTML=071.HTML" +//ASAM mode=writevalue name="Injection Sequence DH" parent="USERCAL_stRAMCAL" type=uint32 offset=4275 min=0 max=65535 units="ENUMERATION BATCH_POS1st=4 BATCH_POS2nd=261 BATCH_POS3rd=518 BATCH_POS4th=775 SEQ_POS3rd=65280 SEQ_POS4th=65282 SEQ_POS1st=65284 SEQ_POS2nd=65286 SEQ_UNUSED=65535" format=3.0 help="TBC HTML=072.HTML" + +// 7 +//ASAM mode=writevalue name="Ignition Sequence AE" parent="USERCAL_stRAMCAL" type=uint32 offset=4279 min=0 max=65535 units="ENUMERATION WASTED_POS1st=4 WASTED_POS2nd=261 WASTED_POS3rd=518 WASTED_POS4th=775 SEQ_POS1st=65280 SEQ_POS2nd=65282 SEQ_POS3rd=65284 SEQ_POS4th=65286 SEQ_UNUSED=65535" format=3.0 help="TBC HTML=073.HTML" +//ASAM mode=writevalue name="Ignition Sequence BF" parent="USERCAL_stRAMCAL" type=uint32 offset=4283 min=0 max=65535 units="ENUMERATION WASTED_POS1st=4 WASTED_POS2nd=261 WASTED_POS3rd=518 WASTED_POS4th=775 SEQ_POS1st=65280 SEQ_POS2nd=65282 SEQ_POS3rd=65284 SEQ_POS4th=65286 SEQ_UNUSED=65535" format=3.0 help="TBC HTML=074.HTML" +//ASAM mode=writevalue name="Ignition Sequence CG" parent="USERCAL_stRAMCAL" type=uint32 offset=4287 min=0 max=65535 units="ENUMERATION WASTED_POS1st=4 WASTED_POS2nd=261 WASTED_POS3rd=518 WASTED_POS4th=775 SEQ_POS1st=65280 SEQ_POS2nd=65282 SEQ_POS3rd=65284 SEQ_POS4th=65286 SEQ_UNUSED=65535" format=3.0 help="TBC HTML=075.HTML" +//ASAM mode=writevalue name="Ignition Sequence DH" parent="USERCAL_stRAMCAL" type=uint32 offset=4291 min=0 max=65535 units="ENUMERATION WASTED_POS1st=4 WASTED_POS2nd=261 WASTED_POS3rd=518 WASTED_POS4th=775 SEQ_POS1st=65280 SEQ_POS2nd=65282 SEQ_POS3rd=65284 SEQ_POS4th=65286 SEQ_UNUSED=65535" format=3.0 help="TBC HTML=076.HTML" +//ASAM mode=writevalue name="Simple Cam Sync Source" parent="USERCAL_stRAMCAL" type=uint8 offset=4295 min=0 max=2000 m=1 b=0 units="dl" format=3.0 help="TBC HTML=077.HTML" +//ASAM mode=writevalue name="Cam Sync High Late" parent="USERCAL_stRAMCAL" type=uint8 offset=4296 min=0 max=2000 units="ENUMERATION FALSE=0 TRUE=1" format=3.0 help="TBC HTML=078.HTML" +//ASAM mode=writevalue name="Cam Sync Sample Tooth Count" parent="USERCAL_stRAMCAL" type=uint32 offset=4297 min=0 max=2000 m=1 b=0 units="dl" format=3.0 help="TBC HTML=079.HTML" +//ASAM mode=writevalue name="Manifold Volume" parent="USERCAL_stRAMCAL" type=uint16 offset=4301 min=0 max=65535 m=1 b=0 units="cc" format=5.0 help="Manifold Volume CC HTML=080.HTML" +//ASAM mode=writevalue name="Cyl Count" parent="USERCAL_stRAMCAL" type=uint8 offset=4303 min=0 max=2000 m=1 b=0 units="dl" format=3.0 help="TBC HTML=081.HTML" +//ASAM mode=writevalue name="Injector Flow Rate" parent="USERCAL_stRAMCAL" type=uint16 offset=4304 min=0 max=20000 m=1 b=0 units="dl" format=3.0 help="TBC HTML=082.HTML" +//ASAM mode=writeaxis_pts name="Airflow Map_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=4306 min=0 max=8000 m=1 b=0 units="RPM" format=4.0 help="Airflow MAP Y Axis HTML=083.HTML" xcount=11 xindexvar="Engine Speed Raw" +//ASAM mode=writeaxis_pts name="Airflow Map_YAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=4350 min=0 max=90000 m=0.001 b=0 units="Degrees" format=3.1 help="Airflow MAP X Axis HTML=084.HTML" xcount=11 xindexvar="Throttle Angle" +//ASAM mode=writemap name="Airflow Map" parent="USERCAL_stRAMCAL" type=uint32 offset=4394 min=0 max=150 m=0.000001 b=0 units="g/s" format=9.6 help="Airflow Map HTML=085.HTML" xcount=11 xindexvar="Engine Speed Raw" ycount=11 yindexvar="Throttle Angle" +// 8 +//ASAM mode=writevalue name="Manifold Time Constant Cal" parent="USERCAL_stRAMCAL" type=uint8 offset=4878 min=0 max=255 m=1 b=0 units="dl" format=3.0 help="Manifold Time Constant Cal HTML=086.HTML" +//ASAM mode=writevalue name="Airflow Transient Enable" parent="USERCAL_stRAMCAL" type=uint8 offset=4879 min=0 max=1 units="ENUMERATION OFF=0 ON=1" format=1.0 help="Airflow Transients Enable HTML=087.HTML" +//ASAM mode=writeaxis_pts name="Injector Start Primer Table_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=4880 min=0 max=2 m=0.001 b=0 units="ms" format=4.3 help="Injector Short Opening X Axis HTML=088.HTML" xcount=11 xindexvar="Fuel Injector Predicted ms" +//ASAM mode=writecurve name="Injector Start Primer Table" parent="USERCAL_stRAMCAL" type=uint32 offset=4924 min=0 max=2 m=1 b=0 units="ms" format=4.3 help="Injector Short Opening Curve HTML=089.HTML" xcount=11 xindexvar="Fuel Injector Predicted ms" +//ASAM mode=writeaxis_pts name="Injector Short Opening Table_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=4968 min=0 max=2 m=0.001 b=0 units="ms" format=4.3 help="Injector Short Opening X Axis HTML=090.HTML" xcount=11 xindexvar="Fuel Injector Predicted ms" +//ASAM mode=writecurve name="Injector Short Opening Table" parent="USERCAL_stRAMCAL" type=uint32 offset=5012 min=0 max=2 m=0.001 b=0 units="ms" format=4.3 help="Injector Short Opening Curve HTML=091.HTML" xcount=11 xindexvar="Fuel Injector Predicted ms" +//ASAM mode=writevalue name="STT Neg Limit" parent="USERCAL_stRAMCAL" type=uint32 offset=5056 min=0 max=2000 m=1 b=0 units="dl" format=3.0 help="TBC HTML=092.HTML" +//ASAM mode=writevalue name="STT Pos Limit" parent="USERCAL_stRAMCAL" type=uint32 offset=5060 min=0 max=2000 m=1 b=0 units="dl" format=3.0 help="TBC HTML=093.HTML" +//ASAM mode=writevalue name="CLO2 Step Closed" parent="USERCAL_stRAMCAL" type=uint32 offset=5064 min=0 max=10 m=0.1 b=0 units="%" format=3.1 help="TBC HTML=094.HTML" +//ASAM mode=writevalue name="CLO2 Inc Closed" parent="USERCAL_stRAMCAL" type=uint32 offset=5068 min=0 max=10 m=0.1 b=0 units="%" format=3.1 help="TBC HTML=095.HTML" +// 9 +//ASAM mode=writevalue name="CLO2 Step Open" parent="USERCAL_stRAMCAL" type=uint32 offset=5072 min=0 max=10 m=0.1 b=0 units="%" format=3.1 help="TBC HTML=096.HTML" +//ASAM mode=writevalue name="CLO2 Inc Open" parent="USERCAL_stRAMCAL" type=uint32 offset=5076 min=0 max=10 m=0.1 b=0 units="%" format=3.1 help="TBC HTML=097.HTML" +//ASAM mode=writevalue name="Timing Main Offset" parent="USERCAL_stRAMCAL" type=uint16 offset=5080 min=0 max=360 m=0.001 b=0 units="Degrees" format=1.0 help="TBC HTML=098.HTML" +//ASAM mode=writevalue name="AFM Transient Control RPM Limit" parent="USERCAL_stRAMCAL" type=uint32 offset=5082 min=0 max=8000 m=1 b=0 units="RPM" format=1.0 help="TBC HTML=099.HTML" +//ASAM mode=writevalue name="Wasted Spark Enable" parent="USERCAL_stRAMCAL" type=uint8 offset=5086 min=0 max=1 units="ENUMERATION OFF=0 ON=1" format=1.0 help="TBC HTML=100.HTML" +//ASAM mode=writevalue name="AFR Reinstate" parent="USERCAL_stRAMCAL" type=uint16 offset=5087 min=0 max=1 m=0.001 b=0 units="dl" format=1.0 help="TBC HTML=101.HTML" +//ASAM mode=writevalue name="AFR Cutoff" parent="USERCAL_stRAMCAL" type=uint16 offset=5089 min=0 max=1 m=0.001 b=0 units="Degrees" format=1.0 help="TBC HTML=102.HTML" +//ASAM mode=writevalue name="TPS Closed Lower" parent="USERCAL_stRAMCAL" type=uint32 offset=5091 min=0 max=90 m=0.001 b=0 units="Degrees" format=1.0 help="TBC HTML=103.HTML" +//ASAM mode=writevalue name="TPS Closed Upper" parent="USERCAL_stRAMCAL" type=uint32 offset=5095 min=0 max=90 m=0.001 b=0 units="Degrees" format=1.0 help="TBC HTML=104.HTML" +//ASAM mode=writevalue name="ISC EST Trim Pos" parent="USERCAL_stRAMCAL" type=uint32 offset=5099 min=0 max=15 m=0.001 b=0 units="Degrees" format=5.3 help="ISC EST Trim Positive Max HTML=105.HTML" +// 10 +//ASAM mode=writevalue name="ISC EST Trim Neg" parent="USERCAL_stRAMCAL" type=uint32 offset=5103 min=0 max=15 m=0.001 b=0 units="Degrees" format=5.3 help="ISC EST Trim Negative Max HTML=106.HTML" +//ASAM mode=writevalue name="CLO2 EST Trim Pos" parent="USERCAL_stRAMCAL" type=uint32 offset=5107 min=0 max=5 m=0.001 b=0 units="Degrees" format=5.3 help="Closed Loop Fuel EST Trim Positive Max HTML=107.HTML" +//ASAM mode=writevalue name="CLO2 EST Trim Neg" parent="USERCAL_stRAMCAL" type=uint32 offset=5111 min=0 max=5 m=0.001 b=0 units="Degrees" format=5.3 help="Closed Loop Fuel EST Trim Negative Max HTML=108.HTML" +//ASAM mode=writevalue name="Cylinder CC" parent="USERCAL_stRAMCAL" type=uint16 offset=5115 min=0 max=1 m=1 b=0 units="dl" format=1.0 help="Cylinder Capacity HTML=109.HTML" +//ASAM mode=writevalue name="AFM Primary Input Enable Open" parent="USERCAL_stRAMCAL" type=uint8 offset=5117 min=0 max=1 units="ENUMERATION OFF=0 ON=1" format=1.0 help="AFM Primary Input Enable Open HTML=110.HTML" +//ASAM mode=writevalue name="Speed Density AFM TPS Limit" parent="USERCAL_stRAMCAL" type=uint32 offset=5118 min=0 max=90 m=.001 b=0 units="degrees" format=5.3 help="TBC HTML=111.HTML" +//ASAM mode=writevalue name="Seq RPM Limit AE" parent="USERCAL_stRAMCAL" type=uint16 offset=5122 min=0 max=10000 m=1 b=0 units="dl" format=1.0 help="TBC HTML=112.HTML" +//ASAM mode=writevalue name="Seq RPM Limit BF" parent="USERCAL_stRAMCAL" type=uint16 offset=5124 suboffset=2 min=0 max=10000 m=1 b=0 units="dl" format=1.0 help="TBC HTML=113.HTML" +//ASAM mode=writevalue name="Seq RPM Limit CG" parent="USERCAL_stRAMCAL" type=uint16 offset=5126 suboffset=4 min=0 max=10000 m=1 b=0 units="dl" format=1.0 help="TBC HTML=114.HTML" +//ASAM mode=writevalue name="Seq RPM Limit DH" parent="USERCAL_stRAMCAL" type=uint16 offset=5128 suboffset=6 min=0 max=10000 m=1 b=0 units="dl" format=1.0 help="TBC HTML=115.HTML" +//ASAM mode=writevalue name="SeqRPMLimit5" parent="USERCAL_stRAMCAL" type=uint16 offset=5130 suboffset=8 min=0 max=1 m=10000 b=0 units="dl" format=1.0 help="TBC HTML=116.HTML" +//ASAM mode=writevalue name="SeqRPMLimit6" parent="USERCAL_stRAMCAL" type=uint16 offset=5132 suboffset=10 min=0 max=1 m=10000 b=0 units="dl" format=1.0 help="TBC HTML=117.HTML" +//ASAM mode=writevalue name="SeqRPMLimit7" parent="USERCAL_stRAMCAL" type=uint16 offset=5134 suboffset=12 min=0 max=1 m=10000 b=0 units="dl" format=1.0 help="TBC HTML=118.HTML" +//ASAM mode=writevalue name="SeqRPMLimit8" parent="USERCAL_stRAMCAL" type=uint16 offset=5136 suboffset=14 min=0 max=1 m=10000 b=0 units="dl" format=1.0 help="TBC HTML=119.HTML" +//ASAM mode=writevalue name="Seq RPM Limit Hyst" parent="USERCAL_stRAMCAL" type=uint16 offset=5138 min=0 max=500 m=1 b=0 units="dl" format=1.0 help="TBC HTML=120.HTML" +//ASAM mode=writevalue name="HighVacuumEnableKpa" parent="USERCAL_stRAMCAL" type=uint16 offset=5140 min=0 max=101.3 m=0.001 b=0 units="dl" format=1.0 help="TBC HTML=121.HTML" +//ASAM mode=writevalue name="HighVacuumDisableKpa" parent="USERCAL_stRAMCAL" type=uint16 offset=5142 min=0 max=101.3 m=0.001 b=0 units="dl" format=1.0 help="TBC HTML=123.HTML" +// 11 +//ASAM mode=writevalue name="OverrunCutEnableRPM" parent="USERCAL_stRAMCAL" type=uint16 offset=5144 min=0 max=2000 m=1 b=0 units="dl" format=1.0 help="TBC HTML=124.HTML" +//ASAM mode=writevalue name="OverrunCutDisableRPM" parent="USERCAL_stRAMCAL" type=uint16 offset=5146 min=0 max=2000 m=1 b=0 units="dl" format=1.0 help="TBC HTML=125.HTML" +//ASAM mode=writevalue name="RPMRunThreshold" parent="USERCAL_stRAMCAL" type=uint16 offset=5148 min=0 max=1 m=1 b=0 units="dl" format=1.0 help="TBC HTML=126.HTML" +//ASAM mode=writevalue name="CLO2 Sequence Assignment" parent="USERCAL_stRAMCAL" type=uint8 offset=5150 min=0 max=255 units="ENUMERATION CYL1stL-CYL2ndL-CYL3rdL-CYL4thL=0 CYL1stR-CYL2ndL-CYL3rdL-CYL4thL=1 CYL1stL-CYL2ndR-CYL3rdL-CYL4thL=2 CYL1stR-CYL2ndR-CYL3rdL-CYL4thL=3 CYL1stL-CYL2ndL-CYL3rdR-CYL4thL=4 CYL1stR-CYL2ndL-CYL3rdR-CYL4thL=5 CYL1stL-CYL2ndR-CYL3rdR-CYL4thL=6 CYL1stR-CYL2ndR-CYL3rdR-CYL4thL=7 CYL1stL-CYL2ndL-CYL3rdL-CYL4thR=8 CYL1stR-CYL2ndL-CYL3rdL-CYL4thR=9 CYL1stL-CYL2ndR-CYL3rdL-CYL4thR=10 CYL1stR-CYL2ndR-CYL3rdL-CYL4thR=11 CYL1stL-CYL2ndL-CYL3rdR-CYL4thR=12 CYL1stR-CYL2ndL-CYL3rdR-CYL4thR=13 CYL1stL-CYL2ndR-CYL3rdR-CYL4thR=14 CYL1stR-CYL2ndR-CYL3rdR-CYL4thR=15" format=1.0 help="CLO2 Sequence Assignment HTML=126.HTML" +//ASAM mode=writevalue name="EST Filter Closed" parent="USERCAL_stRAMCAL" type=uint16 offset=5151 min=0 max=255 m=1 b=0 units="dl" format=1.0 help="EST Filter Closed HTML=127.HTML" +//ASAM mode=writevalue name="EST Filter Open" parent="USERCAL_stRAMCAL" type=uint16 offset=5153 min=0 max=255 m=1 b=0 units="dl" format=1.0 help="EST Filter Open HTML=128.HTML" +//ASAM mode=writevalue name="EST CL Gain" parent="USERCAL_stRAMCAL" type=uint16 offset=5155 min=0 max=255 m=1 b=0 units="dl" format=1.0 help="EST CL Gain HTML=129.HTML" +//ASAM mode=writevalue name="AFM Primary Input Enable Closed" parent="USERCAL_stRAMCAL" type=uint8 offset=5157 min=0 max=1 units="ENUMERATION OFF=0 ON=1" format=1.0 help="AFM Primary Input Enable Closed HTML=130.HTML" +//ASAM mode=writevalue name="Sequence 1 Fuel Offset" parent="USERCAL_stRAMCAL" type=sint16 offset=5158 min=-1 max=1 m=.001 b=0 units="ms" format=4.3 help="Sequence 1 Fuel Offset HTML=131.HTML" +//ASAM mode=writevalue name="Sequence 2 Fuel Offset" parent="USERCAL_stRAMCAL" type=sint16 offset=5160 min=-1 max=1 m=.001 b=0 units="ms" format=4.3 help="Sequence 2 Fuel Offset HTML=132.HTML" +//ASAM mode=writevalue name="Sequence 3 Fuel Offset" parent="USERCAL_stRAMCAL" type=sint16 offset=5162 min=-1 max=1 m=.001 b=0 units="ms" format=4.3 help="Sequence 3 Fuel Offset HTML=133.HTML" +//ASAM mode=writevalue name="Sequence 4 Fuel Offset" parent="USERCAL_stRAMCAL" type=sint16 offset=5164 min=-1 max=1 m=.001 b=0 units="ms" format=4.3 help="Sequence 4 Fuel Offset HTML=134.HTML" +//ASAM mode=writevalue name="Sequence 1 Fuel Gain" parent="USERCAL_stRAMCAL" type=uint16 offset=5166 min=0 max=2 m=.001 b=0 units="dl" format=4.3 help="Sequence 1 Fuel Gain HTML=135.HTML" +//ASAM mode=writevalue name="Sequence 2 Fuel Gain" parent="USERCAL_stRAMCAL" type=uint16 offset=5168 min=0 max=2 m=.001 b=0 units="dl" format=4.3 help="Sequence 2 Fuel Gain HTML=136.HTML" +//ASAM mode=writevalue name="Sequence 3 Fuel Gain" parent="USERCAL_stRAMCAL" type=uint16 offset=5170 min=0 max=2 m=.001 b=0 units="dl" format=4.3 help="Sequence 3 Fuel Gain HTML=137.HTML" +//ASAM mode=writevalue name="Sequence 4 Fuel Gain" parent="USERCAL_stRAMCAL" type=uint16 offset=5172 min=0 max=2 m=.001 b=0 units="dl" format=4.3 help="Sequence 4 Fuel Gain HTML=138.HTML" +// 12 +//ASAM mode=writevalue name="TPS CAN Primary" parent="USERCAL_stRAMCAL" type=uint8 offset=5174 min=0 max=2 m=1 b=0 units="dl" format=1.0 help="TPS CAN Enable HTML=139.HTML" +//ASAM mode=writevalue name="PPS CAN Primary" parent="USERCAL_stRAMCAL" type=uint8 offset=5175 min=0 max=2 m=1 b=0 units="dl" format=1.0 help="PPS CAN Enable HTML=140.HTML" +//ASAM mode=writevalue name="CTS CAN Primary" parent="USERCAL_stRAMCAL" type=uint8 offset=5176 min=0 max=2 m=1 b=0 units="dl" format=1.0 help="CTS CAN Enable HTML=141.HTML" +//ASAM mode=writevalue name="ATS CAN Primary" parent="USERCAL_stRAMCAL" type=uint8 offset=5177 min=0 max=2 m=1 b=0 units="dl" format=1.0 help="ATS CAN Enable HTML=142.HTML" +//ASAM mode=writevalue name="MAP CAN Primary" parent="USERCAL_stRAMCAL" type=uint8 offset=5178 min=0 max=2 m=1 b=0 units="dl" format=1.0 help="MAP CAN Enable HTML=143.HTML" +//ASAM mode=writevalue name="Priority CAN ID 1" parent="USERCAL_stRAMCAL" type=uint32 offset=5179 min=1 max=4095 m=1 b=0 units="dl" format=4.0 help="Priority CAN ID 1 HTML=144.HTML" +//ASAM mode=writevalue name="Sensor CAN Data Offset" parent="USERCAL_stRAMCAL" type=uint8 offset=5195 min=1 max=255 m=1 b=0 units="dl" format=4.0 help="Priority CAN ID 1 HTML=145.HTML" +//ASAM mode=writevalue name="Sensor CAN Data ByteCount" parent="USERCAL_stRAMCAL" type=uint8 offset=5203 min=1 max=255 m=1 b=0 units="dl" format=4.0 help="Priority CAN ID 1 HTML=146.HTML" +//ASAM mode=writevalue name="Sync Phase Repeats" parent="USERCAL_stRAMCAL" type=uint32 offset=5211 min=1 max=4095 units="ENUMERATION BATCH=1 SEQUENTIAL=2" format=4.0 help="Sync Phase Repeats HTML=147.HTML" +//ASAM mode=writevalue name="Map Sensor Gain" parent="USERCAL_stRAMCAL" type=sint32 offset=5215 min=1 max=4095 m=1 b=0 units="dl" format=4.0 help="Sync Phase Repeats HTML=148.HTML" +// 13 +//ASAM mode=writevalue name="Map Sensor Offset" parent="USERCAL_stRAMCAL" type=sint32 offset=5219 min=1 max=4095 m=1 b=0 units="dl" format=4.0 help="Sync Phase Repeats HTML=149.HTML" +//ASAM mode=writevalue name="Inj Divide" parent="USERCAL_stRAMCAL" type=uint8 offset=5223 min=1 max=4 units="ENUMERATION TBI=4 BATCH=2 SEQUENTIAL=1" format=4.0 help="Sync Phase Repeats HTML=150.HTML" +//ASAM mode=writevalue name="CLO2 LeftEnable" parent="USERCAL_stRAMCAL" type=uint8 offset=5224 min=0 max=1 units="ENUMERATION OFF=0 ON=1" format=4.0 help="Sync Phase Repeats HTML=151.HTML" +//ASAM mode=writevalue name="CLO2 RightEnable" parent="USERCAL_stRAMCAL" type=uint8 offset=5225 min=0 max=1 units="ENUMERATION OFF=0 ON=1" format=4.0 help="Sync Phase Repeats HTML=152.HTML" +//ASAM mode=writevalue name="Returnless Enable" parent="USERCAL_stRAMCAL" type=uint8 offset=5226 min=0 max=1 units="ENUMERATION OFF=0 ON=1" format=4.0 help="Sync Phase Repeats HTML=153.HTML" +//ASAM mode=writevalue name="Returnless Pressure kPa" parent="USERCAL_stRAMCAL" type=uint16 offset=5227 min=1 max=500 m=1 b=0 units="kPa" format=4.0 help="Sync Phase Repeats HTML=154.HTML" +//ASAM mode=writevalue name="Cranking Airflow Enable" parent="USERCAL_stRAMCAL" type=uint8 offset=5229 min=0 max=1 units="ENUMERATION OFF=0 ON=1" format=4.0 help="Sync Phase Repeats HTML=155.HTML" +//ASAM mode=writevalue name="Stepper IAC Enable" parent="USERCAL_stRAMCAL" type=uint8 offset=5230 min=0 max=1 units="ENUMERATION OFF=0 ON=1" format=4.0 help="Sync Phase Repeats HTML=156.HTML" +//ASAM mode=writevalue name="IAC Steps Open Hot" parent="USERCAL_stRAMCAL" type=uint16 offset=5231 min=0 max=255 m=1 b=0 units="dl" format=4.0 help="Sync Phase Repeats HTML=157.HTML" +//ASAM mode=writevalue name="IAC Steps Open Cold" parent="USERCAL_stRAMCAL" type=uint16 offset=5233 min=0 max=255 m=1 b=0 units="dl" format=4.0 help="Sync Phase Repeats HTML=158.HTML" +// 14 +//ASAM mode=writevalue name="Idle Entry RPM Offset" parent="USERCAL_stRAMCAL" type=uint16 offset=5235 min=1 max=1000 m=1 b=0 units="RPM" format=4.0 help="Idle Entry RPM Offset HTML=159.HTML" +//ASAM mode=writevalue name="Rad Fan On Temp" parent="USERCAL_stRAMCAL" type=sint32 offset=5237 min=-40 max=200 m=0.001 b=1 units="degC" format=4.0 help="Rad Fan On Temp HTML=160.HTML" +//ASAM mode=writevalue name="Rad Fan Off Temp" parent="USERCAL_stRAMCAL" type=sint32 offset=5241 min=-40 max=200 m=0.001 b=1 units="degC" format=4.0 help="Rad Fan Off Temp HTML=161.HTML" +//ASAM mode=writevalue name="Fuel Pump Relay" parent="USERCAL_stRAMCAL" type=uint8 offset=5245 min=1 max=100 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=4.0 help="Fuel Pump Relay HTML=162.HTML" +//ASAM mode=writevalue name="EST Bypass" parent="USERCAL_stRAMCAL" type=uint8 offset=5246 min=1 max=1000 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=4.0 help="EST Bypass HTML=163.HTML" +//ASAM mode=writeaxis_pts name="Air Sensor Table_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=5247 min=0 max=5 m=1 b=0 units="V" format=7.0 help="Air Sensor X Axis HTML=164.HTML" xcount=17 xindexvar="ATS Sensor Voltage" +//ASAM mode=writecurve name="Air Sensor Table" parent="USERCAL_stRAMCAL" type=sint32 offset=5315 min=-40 max=200 m=0.001 b=0 units="degrees C" format=4.3 help="Air Sensor Curve HTML=165.HTML" xcount=17 xindexvar="ATS Sensor Voltage" +//ASAM mode=writevalue name="Fuel 1 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5383 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="Fuel Sequence 1 IO Resource HTML=166.HTML" +//ASAM mode=writevalue name="Fuel 2 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5385 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="Fuel Sequence 2 IO Resource HTML=167.HTML" +//ASAM mode=writevalue name="Fuel 3 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5387 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="Fuel Sequence 3 IO Resource HTML=168.HTML" +// 15 +//ASAM mode=writevalue name="Fuel 4 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5389 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="Fuel Sequence 4 IO Resource HTML=169.HTML" +//ASAM mode=writevalue name="EST 1 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5391 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="EST Sequence 1 IO Resource HTML=170.HTML" +//ASAM mode=writevalue name="EST 2 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5393 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="EST Sequence 2 IO Resource HTML=171.HTML" +//ASAM mode=writevalue name="EST 3 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5395 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="EST Sequence 3 IO Resource HTML=172.HTML" +//ASAM mode=writevalue name="EST 4 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5397 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="EST Sequence 4 IO Resource HTML=173.HTML" +//ASAM mode=writevalue name="IAC 1 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5399 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="IAC 1 IO Resource HTML=174.HTML" +//ASAM mode=writevalue name="IAC 2 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5401 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="IAC 2 IO Resource HTML=175.HTML" +//ASAM mode=writevalue name="IAC 3 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5403 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="IAC 3 IO Resource HTML=176.HTML" +//ASAM mode=writevalue name="IAC 4 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5405 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="IAC 4 IO Resource HTML=177.HTML" +//ASAM mode=writevalue name="OBD ISC Advance Enable" parent="USERCAL_stRAMCAL" type=uint8 offset=5407 min=0 max=1 units="ENUMERATION OFF=0 ON=1" format=1.0 help="IAC Enable OBD Idle Advance HTML=178.HTML" + +//ASAM mode=writevalue name="Trigger Type" parent="USERCAL_stRAMCAL" type=uint8 offset=5408 min=0 max=255 units="ENUMERATION AUTO=0 M15A=1 EA888=2 2NEFE=3" format=1.0 help="Trigger Type HTML=178.HTML" +//ASAM mode=writevalue name="Sync Type" parent="USERCAL_stRAMCAL" type=uint8 offset=5409 min=0 max=255 units="ENUMERATION AUTO=0 M15A=1 EA888=2" format=1.0 help="Sync Type HTML=179.HTML" +//ASAM mode=writevalue name="Trigger Pull Strength" parent="USERCAL_stRAMCAL" type=uint8 offset=5410 min=0 max=2 units="ENUMERATION WEAK=0 MEDIUM=1 STRONG=2" format=1.0 help="Trigger Pull Strength HTML=180.HTML" +//ASAM mode=writevalue name="Sync Pull Strength" parent="USERCAL_stRAMCAL" type=uint8 offset=5411 min=0 max=2 units="ENUMERATION WEAK=0 MEDIUM=1 STRONG=2" format=1.0 help="Sync Pull Strength HTML=181.HTML" +//ASAM mode=writevalue name="Min Linear Fuel Pulse" parent="USERCAL_stRAMCAL" type=uint16 offset=5412 min=0 max=2 m=0.001 b=0 units="ms" format=1.0 help="Min Linear Fuel Pulse HTML=182.HTML" + +//ASAM mode=writevalue name="CTS AD Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5414 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_I_ADD1=8 EH_I_ADD2=9 EH_I_CMP1=10 EH_I_CMP2=11 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_UNUSED=125" format=3.0 help="CTS AD Resource HTML=183.HTML" +//ASAM mode=writevalue name="MAP AD Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5416 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_I_ADD1=8 EH_I_ADD2=9 EH_I_CMP1=10 EH_I_CMP2=11 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_UNUSED=125" format=3.0 help="MAP AD Resource HTML=184.HTML" +//ASAM mode=writevalue name="ATS AD Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5418 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_I_ADD1=8 EH_I_ADD2=9 EH_I_CMP1=10 EH_I_CMP2=11 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_UNUSED=125" format=3.0 help="ATS AD Resource HTML=185.HTML" +//ASAM mode=writevalue name="AFM AD Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5420 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_I_ADD1=8 EH_I_ADD2=9 EH_I_CMP1=10 EH_I_CMP2=11 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_UNUSED=125" format=3.0 help="AFM AD Resource HTML=186.HTML" +//ASAM mode=writevalue name="TPS AD Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5422 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_I_ADD1=8 EH_I_ADD2=9 EH_I_CMP1=10 EH_I_CMP2=11 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_UNUSED=125" format=3.0 help="TPS AD Resource HTML=187.HTML" + +//ASAM mode=writeaxis_pts name="Tip In Correction Table_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=5424 min=0 max=8000 m=1 b=0 units="RPM" format=4.3 help="Tip In Correction X Axis HTML=188.HTML" xcount=17 xindexvar="Engine Speed Raw" +//ASAM mode=writecurve name="Tip In Correction Table" parent="USERCAL_stRAMCAL" type=uint16 offset=5492 min=0 max=2 m=0.001 b=0 units="%" format=6.3 help="Tip In Correction Curve" HTML=189.HTML xcount=17 xindexvar="Engine Speed Raw" + +//ASAM mode=writevalue name="Logic Block Var A" parent="USERCAL_stRAMCAL" type=uint32 offset=5526 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Variable 1 HTML=190.HTML" +//ASAM mode=writevalue name="Logic Block Var B" parent="USERCAL_stRAMCAL" type=uint32 offset=5530 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Variable 2 HTML=191.HTML" +//ASAM mode=writevalue name="Logic Block Var C" parent="USERCAL_stRAMCAL" type=uint32 offset=5534 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Variable 3 HTML=192.HTML" +//ASAM mode=writevalue name="Logic Block Var D" parent="USERCAL_stRAMCAL" type=uint32 offset=5538 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Variable 4 HTML=193.HTML" +//ASAM mode=writevalue name="Logic Block Var E" parent="USERCAL_stRAMCAL" type=uint32 offset=5542 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Variable 5 HTML=194.HTML" +//ASAM mode=writevalue name="Logic Block Var F" parent="USERCAL_stRAMCAL" type=uint32 offset=5546 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Variable 6 HTML=195.HTML" +//ASAM mode=writevalue name="Logic Block Var G" parent="USERCAL_stRAMCAL" type=uint32 offset=5550 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Variable 7 HTML=196.HTML" +//ASAM mode=writevalue name="Logic Block Var H" parent="USERCAL_stRAMCAL" type=uint32 offset=5554 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Variable 8 HTML=197.HTML" + +//ASAM mode=writevalue name="Logic Block Operand A" parent="USERCAL_stRAMCAL" type=uint32 offset=5558 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Operand 1 HTML=198.HTML" +//ASAM mode=writevalue name="Logic Block Operand B" parent="USERCAL_stRAMCAL" type=uint32 offset=5562 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Operand 2 HTML=199.HTML" +//ASAM mode=writevalue name="Logic Block Operand C" parent="USERCAL_stRAMCAL" type=uint32 offset=5566 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Operand 3 HTML=200.HTML" +//ASAM mode=writevalue name="Logic Block Operand D" parent="USERCAL_stRAMCAL" type=uint32 offset=5570 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Operand 4 HTML=201.HTML" +//ASAM mode=writevalue name="Logic Block Operand E" parent="USERCAL_stRAMCAL" type=uint32 offset=5574 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Operand 5 HTML=202.HTML" +//ASAM mode=writevalue name="Logic Block Operand F" parent="USERCAL_stRAMCAL" type=uint32 offset=5578 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Operand 6 HTML=203.HTML" +//ASAM mode=writevalue name="Logic Block Operand G" parent="USERCAL_stRAMCAL" type=uint32 offset=5582 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Operand 7 HTML=204.HTML" +//ASAM mode=writevalue name="Logic Block Operand H" parent="USERCAL_stRAMCAL" type=uint32 offset=5586 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Operand 8 HTML=205.HTML" + +//ASAM mode=writevalue name="Logic Block Chain Output A" parent="USERCAL_stRAMCAL" type=uint16 offset=5590 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Chain Output 1 HTML=206.HTML" +//ASAM mode=writevalue name="Logic Block Chain Output B" parent="USERCAL_stRAMCAL" type=uint16 offset=5592 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Chain Output 2 HTML=207.HTML" +//ASAM mode=writevalue name="Logic Block Chain Output C" parent="USERCAL_stRAMCAL" type=uint16 offset=5594 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Chain Output 3 HTML=208.HTML" +//ASAM mode=writevalue name="Logic Block Chain Output D" parent="USERCAL_stRAMCAL" type=uint16 offset=5596 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Chain Output 4 HTML=209.HTML" +//ASAM mode=writevalue name="Logic Block Chain Output E" parent="USERCAL_stRAMCAL" type=uint16 offset=5598 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Chain Output 5 HTML=210.HTML" +//ASAM mode=writevalue name="Logic Block Chain Output F" parent="USERCAL_stRAMCAL" type=uint16 offset=5600 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Chain Output 6 HTML=211.HTML" +//ASAM mode=writevalue name="Logic Block Chain Output G" parent="USERCAL_stRAMCAL" type=uint16 offset=5602 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Chain Output 7 HTML=212.HTML" +//ASAM mode=writevalue name="Logic Block Chain Output H" parent="USERCAL_stRAMCAL" type=uint16 offset=5604 min=0 max=4294967296 m=1 b=0 units="dl" format=3.0 help="Logic Block Chain Output 8 HTML=213.HTML" + +//ASAM mode=writevalue name="Thermofan Relay" parent="USERCAL_stRAMCAL" type=uint8 offset=5606 min=1 max=100 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=4.0 help="Thermofan Relay HTML=214.HTML" + +//ASAM mode=writevalue name="EST 1 IO Mux Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5607 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="EST Sequence 1 IO Mux Resource HTML=215.HTML" +//ASAM mode=writevalue name="EST 2 IO Mux Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5609 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="EST Sequence 2 IO Mux Resource HTML=216.HTML" +//ASAM mode=writevalue name="EST 3 IO Mux Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5611 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="EST Sequence 3 IO Mux Resource HTML=217.HTML" +//ASAM mode=writevalue name="EST 4 IO Mux Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5613 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="EST Sequence 4 IO Mux Resource HTML=218.HTML" +//ASAM mode=writevalue name="UEGO CAN Primary" parent="USERCAL_stRAMCAL" type=uint8 offset=5615 min=0 max=2 m=1 b=0 units="dl" format=1.0 help="UEGO CAN Enable HTML=219.HTML" + +//ASAM mode=writevalue name="PWM 2D 1 Axis Source X" parent="USERCAL_stRAMCAL" type=uint16 offset=5616 min=0 max=255 units="ENUMERATION RPM=0 TPS=1 MAP=2 CTS=3 ATS=4 BOOST-CONTROL=5 NONE=255" format=3.0 help="PWM 2D 1 Axis Source X HTML=220.HTML" +//ASAM mode=writevalue name="PWM 2D 2 Axis Source X" parent="USERCAL_stRAMCAL" type=uint16 offset=5618 min=0 max=255 units="ENUMERATION RPM=0 TPS=1 MAP=2 CTS=3 ATS=4 BOOST-CONTROL=5 NONE=255" format=3.0 help="PWM 2D 2 Axis Source X HTML=221.HTML" +//ASAM mode=writevalue name="PWM 2D 3 Axis Source X" parent="USERCAL_stRAMCAL" type=uint16 offset=5620 min=0 max=255 units="ENUMERATION RPM=0 TPS=1 MAP=2 CTS=3 ATS=4 BOOST-CONTROL=5 NONE=255" format=3.0 help="PWM 2D 3 Axis Source X HTML=222.HTML" +//ASAM mode=writevalue name="PWM 2D 4 Axis Source X" parent="USERCAL_stRAMCAL" type=uint16 offset=5622 min=0 max=255 units="ENUMERATION RPM=0 TPS=1 MAP=2 CTS=3 ATS=4 BOOST-CONTROL=5 NONE=255" format=3.0 help="PWM 2D 4 Axis Source X HTML=223.HTML" +//ASAM mode=writevalue name="PWM 2D 5 Axis Source X" parent="USERCAL_stRAMCAL" type=uint16 offset=5624 min=0 max=255 units="ENUMERATION RPM=0 TPS=1 MAP=2 CTS=3 ATS=4 BOOST-CONTROL=5 NONE=255" format=3.0 help="PWM 2D 5 Axis Source X HTML=224.HTML" +//ASAM mode=writevalue name="PWM 2D 6 Axis Source X" parent="USERCAL_stRAMCAL" type=uint16 offset=5626 min=0 max=255 units="ENUMERATION RPM=0 TPS=1 MAP=2 CTS=3 ATS=4 BOOST-CONTROL=5 NONE=255" format=3.0 help="PWM 2D 6 Axis Source X HTML=225.HTML" +//ASAM mode=writevalue name="PWM 2D 7 Axis Source X" parent="USERCAL_stRAMCAL" type=uint16 offset=5628 min=0 max=255 units="ENUMERATION RPM=0 TPS=1 MAP=2 CTS=3 ATS=4 BOOST-CONTROL=5 NONE=255" format=3.0 help="PWM 2D 7 Axis Source X HTML=226.HTML" +//ASAM mode=writevalue name="PWM 2D 8 Axis Source X" parent="USERCAL_stRAMCAL" type=uint16 offset=5630 min=0 max=255 units="ENUMERATION RPM=0 TPS=1 MAP=2 CTS=3 ATS=4 BOOST-CONTROL=5 NONE=255" format=3.0 help="PWM 2D 8 Axis Source X HTML=227.HTML" + +//ASAM mode=writevalue name="PWM 3D 1 Axis Source X" parent="USERCAL_stRAMCAL" type=uint16 offset=5632 min=0 max=255 units="ENUMERATION RPM=0 TPS=1 MAP=2 CTS=3 ATS=4 BOOST-CONTROL=5 NONE=255" format=3.0 help="PWM 3D 1 Axis Source X HTML=228.HTML" +//ASAM mode=writevalue name="PWM 3D 2 Axis Source X" parent="USERCAL_stRAMCAL" type=uint16 offset=5634 min=0 max=255 units="ENUMERATION RPM=0 TPS=1 MAP=2 CTS=3 ATS=4 BOOST-CONTROL=5 NONE=255" format=3.0 help="PWM 3D 2 Axis Source X HTML=229.HTML" +//ASAM mode=writevalue name="PWM 3D 3 Axis Source X" parent="USERCAL_stRAMCAL" type=uint16 offset=5636 min=0 max=255 units="ENUMERATION RPM=0 TPS=1 MAP=2 CTS=3 ATS=4 BOOST-CONTROL=5 NONE=255" format=3.0 help="PWM 3D 3 Axis Source X HTML=230.HTML" +//ASAM mode=writevalue name="PWM 3D 4 Axis Source X" parent="USERCAL_stRAMCAL" type=uint16 offset=5638 min=0 max=255 units="ENUMERATION RPM=0 TPS=1 MAP=2 CTS=3 ATS=4 BOOST-CONTROL=5 NONE=255" format=3.0 help="PWM 3D 4 Axis Source X HTML=231.HTML" + +//ASAM mode=writevalue name="PWM 3D 1 Axis Source Y" parent="USERCAL_stRAMCAL" type=uint16 offset=5640 min=0 max=255 units="ENUMERATION RPM=0 TPS=1 MAP=2 CTS=3 ATS=4 BOOST-CONTROL=5 NONE=255" format=3.0 help="PWM 3D 1 Axis Source Y HTML=232.HTML" +//ASAM mode=writevalue name="PWM 3D 2 Axis Source Y" parent="USERCAL_stRAMCAL" type=uint16 offset=5642 min=0 max=255 units="ENUMERATION RPM=0 TPS=1 MAP=2 CTS=3 ATS=4 BOOST-CONTROL=5 NONE=255" format=3.0 help="PWM 3D 2 Axis Source Y HTML=233.HTML" +//ASAM mode=writevalue name="PWM 3D 3 Axis Source Y" parent="USERCAL_stRAMCAL" type=uint16 offset=5644 min=0 max=255 units="ENUMERATION RPM=0 TPS=1 MAP=2 CTS=3 ATS=4 BOOST-CONTROL=5 NONE=255" format=3.0 help="PWM 3D 3 Axis Source Y HTML=234.HTML" +//ASAM mode=writevalue name="PWM 3D 4 Axis Source Y" parent="USERCAL_stRAMCAL" type=uint16 offset=5646 min=0 max=255 units="ENUMERATION RPM=0 TPS=1 MAP=2 CTS=3 ATS=4 BOOST-CONTROL=5 NONE=255" format=3.0 help="PWM 3D 4 Axis Source Y HTML=235.HTML" + +//ASAM mode=writevalue name="PWM 2D 1 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5648 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="PWM 2D 1 IO Resource HTML=236.HTML" +//ASAM mode=writevalue name="PWM 2D 2 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5650 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="PWM 2D 2 IO Resource HTML=237.HTML" +//ASAM mode=writevalue name="PWM 2D 3 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5652 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="PWM 2D 3 IO Resource HTML=238.HTML" +//ASAM mode=writevalue name="PWM 2D 4 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5654 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="PWM 2D 4 IO Resource HTML=239.HTML" +//ASAM mode=writevalue name="PWM 2D 5 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5656 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="PWM 2D 5 IO Resource HTML=240.HTML" +//ASAM mode=writevalue name="PWM 2D 6 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5658 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="PWM 2D 6 IO Resource HTML=241.HTML" +//ASAM mode=writevalue name="PWM 2D 7 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5660 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="PWM 2D 7 IO Resource HTML=242.HTML" +//ASAM mode=writevalue name="PWM 2D 8 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5662 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="PWM 2D 8 IO Resourc HTML=243.HTML" + +//ASAM mode=writevalue name="PWM 3D 1 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5664 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="PWM 3D 1 IO Resource HTML=244.HTML" +//ASAM mode=writevalue name="PWM 3D 2 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5666 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="PWM 3D 2 IO Resource HTML=245.HTML" +//ASAM mode=writevalue name="PWM 3D 3 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5668 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="PWM 3D 3 IO Resource HTML=246.HTML" +//ASAM mode=writevalue name="PWM 3D 4 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=5670 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="PWM 3D 4 IO Resource HTML=247.HTML" + +//ASAM mode=writeaxis_pts name="PWM 2D Table 1_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=5672 min=0 max=65535 m=1 b=0 units="%" format=4.3 help="PWM 2D 1 X Axis HTML=248.HTML" xcount=17 xindexvar="Generic Source IDX1" +//ASAM mode=writeaxis_pts name="PWM 2D Table 2_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=5740 min=0 max=65535 m=1 b=0 units="%" format=4.3 help="PWM 2D 2 X Axis HTML=249.HTML" xcount=17 xindexvar="Generic Source IDX2" +//ASAM mode=writeaxis_pts name="PWM 2D Table 3_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=5808 min=0 max=65535 m=1 b=0 units="%" format=4.3 help="PWM 2D 3 X Axis HTML=250.HTML" xcount=17 xindexvar="Generic Source IDX3" +//ASAM mode=writeaxis_pts name="PWM 2D Table 4_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=5876 min=0 max=65535 m=1 b=0 units="%" format=4.3 help="PWM 2D 4 X Axis HTML=251.HTML" xcount=17 xindexvar="Generic Source IDX4" +//ASAM mode=writeaxis_pts name="PWM 2D Table 5_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=5944 min=0 max=65535 m=1 b=0 units="%" format=4.3 help="PWM 2D 5 X Axis HTML=252.HTML" xcount=17 xindexvar="Generic Source IDX5" +//ASAM mode=writeaxis_pts name="PWM 2D Table 6_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=6012 min=0 max=65535 m=1 b=0 units="%" format=4.3 help="PWM 2D 6 X Axis HTML=253.HTML" xcount=17 xindexvar="Generic Source IDX6" +//ASAM mode=writeaxis_pts name="PWM 2D Table 7_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=6080 min=0 max=65535 m=1 b=0 units="%" format=4.3 help="PWM 2D 7 X Axis HTML=254.HTML" xcount=17 xindexvar="Generic Source IDX7" +//ASAM mode=writeaxis_pts name="PWM 2D Table 8_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=6148 min=0 max=65535 m=1 b=0 units="%" format=4.3 help="PWM 2D 8 X Axis HTML=255.HTML" xcount=17 xindexvar="Generic Source IDX8" + +//ASAM mode=writecurve name="PWM 2D Table 1" parent="USERCAL_stRAMCAL" type=uint16 offset=6216 min=0 max=100 m=0.00152 b=0 units="%" format=4.3 help="PWM 2D Curve 1 HTML=256.HTML" xcount=17 xindexvar="Generic Source IDX1" +//ASAM mode=writecurve name="PWM 2D Table 2" parent="USERCAL_stRAMCAL" type=uint16 offset=6250 min=0 max=100 m=0.00152 b=0 units="%" format=4.3 help="PWM 2D Curve 2 HTML=257.HTML" xcount=17 xindexvar="Generic Source IDX2" +//ASAM mode=writecurve name="PWM 2D Table 3" parent="USERCAL_stRAMCAL" type=uint16 offset=6284 min=0 max=100 m=0.00152 b=0 units="%" format=4.3 help="PWM 2D Curve 3 HTML=258.HTML" xcount=17 xindexvar="Generic Source IDX3" +//ASAM mode=writecurve name="PWM 2D Table 4" parent="USERCAL_stRAMCAL" type=uint16 offset=6318 min=0 max=100 m=0.00152 b=0 units="%" format=4.3 help="PWM 2D Curve 4 HTML=259.HTML" xcount=17 xindexvar="Generic Source IDX4" +//ASAM mode=writecurve name="PWM 2D Table 5" parent="USERCAL_stRAMCAL" type=uint16 offset=6352 min=0 max=100 m=0.00152 b=0 units="%" format=4.3 help="PWM 2D Curve 5 HTML=260.HTML" xcount=17 xindexvar="Generic Source IDX5" +//ASAM mode=writecurve name="PWM 2D Table 6" parent="USERCAL_stRAMCAL" type=uint16 offset=6386 min=0 max=100 m=0.00152 b=0 units="%" format=4.3 help="PWM 2D Curve 6 HTML=261.HTML" xcount=17 xindexvar="Generic Source IDX6" +//ASAM mode=writecurve name="PWM 2D Table 7" parent="USERCAL_stRAMCAL" type=uint16 offset=6420 min=0 max=100 m=0.00152 b=0 units="%" format=4.3 help="PWM 2D Curve 7 HTML=262.HTML" xcount=17 xindexvar="Generic Source IDX7" +//ASAM mode=writecurve name="PWM 2D Table 8" parent="USERCAL_stRAMCAL" type=uint16 offset=6454 min=0 max=100 m=0.00152 b=0 units="%" format=4.3 help="PWM 2D Curve 8 HTML=263.HTML" xcount=17 xindexvar="Generic Source IDX8" + +//ASAM mode=writeaxis_pts name="PWM 3D Map 1_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=6488 min=0 max=65535 m=1 b=0 units="%" format=4.3 help="PWM 3D 1 X Axis HTML=264.HTML" xcount=17 xindexvar="Generic Source IDX9" +//ASAM mode=writeaxis_pts name="PWM 3D Map 2_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=6556 min=0 max=65535 m=1 b=0 units="%" format=4.3 help="PWM 3D 2 X Axis HTML=265.HTML" xcount=17 xindexvar="Generic Source IDX10" +//ASAM mode=writeaxis_pts name="PWM 3D Map 3_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=6624 min=0 max=65535 m=1 b=0 units="%" format=4.3 help="PWM 3D 3 X Axis HTML=266.HTML" xcount=17 xindexvar="Generic Source IDX11" +//ASAM mode=writeaxis_pts name="PWM 3D Map 4_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=6692 min=0 max=65535 m=1 b=0 units="%" format=4.3 help="PWM 3D 4 X Axis HTML=267.HTML" xcount=17 xindexvar="Generic Source IDX12" +//ASAM mode=writeaxis_pts name="PWM 3D Map 1_YAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=6760 min=0 max=65535 m=1 b=0 units="%" format=4.3 help="PWM 3D 1 Y Axis HTML=268.HTML" xcount=17 xindexvar="Generic Source IDX13" +//ASAM mode=writeaxis_pts name="PWM 3D Map 2_YAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=6828 min=0 max=65535 m=1 b=0 units="%" format=4.3 help="PWM 3D 2 Y Axis HTML=269.HTML" xcount=17 xindexvar="Generic Source IDX14" +//ASAM mode=writeaxis_pts name="PWM 3D Map 3_YAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=6896 min=0 max=65535 m=1 b=0 units="%" format=4.3 help="PWM 3D 3 Y Axis HTML=270.HTML" xcount=17 xindexvar="Generic Source IDX15" +//ASAM mode=writeaxis_pts name="PWM 3D Map 4_YAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=6964 min=0 max=65535 m=1 b=0 units="%" format=4.3 help="PWM 3D 4 Y Axis HTML=271.HTMl" xcount=17 xindexvar="Generic Source IDX16" + +//ASAM mode=writemap name="PWM 3D Map 1" parent="USERCAL_stRAMCAL" type=uint16 offset=7032 min=0 max=100 m=0.00152 b=0 units="%" format=4.3 help="PWM 3D Map 1 HTML=272.HTML" xcount=17 xindexvar="Generic Source IDX9" ycount=17 yindexvar="Generic Source IDX13" +//ASAM mode=writemap name="PWM 3D Map 2" parent="USERCAL_stRAMCAL" type=uint16 offset=7610 min=0 max=100 m=0.00152 b=0 units="%" format=4.3 help="PWM 3D Map 2 HTML=273.HTML" xcount=17 xindexvar="Generic Source IDX10" ycount=17 yindexvar="Generic Source IDX14" +//ASAM mode=writemap name="PWM 3D Map 3" parent="USERCAL_stRAMCAL" type=uint16 offset=8188 min=0 max=100 m=0.00152 b=0 units="%" format=4.3 help="PWM 3D Map 3 HTML=274.HTML" xcount=17 xindexvar="Generic Source IDX11" ycount=17 yindexvar="Generic Source IDX15" +//ASAM mode=writemap name="PWM 3D Map 4" parent="USERCAL_stRAMCAL" type=uint16 offset=8766 min=0 max=100 m=0.00152 b=0 units="%" format=4.3 help="PWM 3D Map 4 HTML=275.HTML" xcount=17 xindexvar="Generic Source IDX12" ycount=17 yindexvar="Generic Source IDX16" + +//ASAM mode=writevalue name="Fuel Pressure Solenoid Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=9344 min=0 max=255 m=1 b=0 units="ENUMERATION EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42" format=3.0 help="Fuel Pressure Solenoid IO Resource HTML=276.HTML" +//ASAM mode=writevalue name="VCT AB Input Pullup Enable" parent="USERCAL_stRAMCAL" type=uint8 offset=9346 min=0 max=1 m=1 b=0 units="bool" format=1.0 help="VCT AB Input Pullup Enable HTML=277.HTML" +//ASAM mode=writevalue name="VCT CD Input Pullup Enable" parent="USERCAL_stRAMCAL" type=uint8 offset=9347 min=0 max=1 m=1 b=0 units="bool" format=1.0 help="VCT AB Input Pullup Enable HTML=278.HTML" + +//ASAM mode=writevalue name="VVT Input 1 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=9348 min=0 max=255 units="ENUMERATION EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_UNUSED=125" format=3.0 help="VVT Input 1 IO Resource HTML=279.HTML" +//ASAM mode=writevalue name="VVT Input 2 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=9350 min=0 max=255 units="ENUMERATION EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_UNUSED=125" format=3.0 help="VVT Input 2 IO Resource HTML=280.HTML" +//ASAM mode=writevalue name="VVT Input 3 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=9352 min=0 max=255 units="ENUMERATION EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_UNUSED=125" format=3.0 help="VVT Input 3 IO Resource HTML=281.HTML" +//ASAM mode=writevalue name="VVT Input 4 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=9354 min=0 max=255 units="ENUMERATION EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_UNUSED=125" format=3.0 help="VVT Input 4 IO Resource HTML=282.HTML" + +//ASAM mode=writevalue name="VVT Input 1 Type" parent="USERCAL_stRAMCAL" type=uint8 offset=9356 min=0 max=255 m=1 b=0 units="dl" format=3.0 help="VVT Input 1 Type HTML=283.HTML" +//ASAM mode=writevalue name="VVT Input 2 Type" parent="USERCAL_stRAMCAL" type=uint8 offset=9357 min=0 max=255 m=1 b=0 units="dl" format=3.0 help="VVT Input 2 Type HTML=284.HTML" +//ASAM mode=writevalue name="VVT Input 3 Type" parent="USERCAL_stRAMCAL" type=uint8 offset=9358 min=0 max=255 m=1 b=0 units="dl" format=3.0 help="VVT Input 3 Type HTML=285.HTML" +//ASAM mode=writevalue name="VVT Input 4 Type" parent="USERCAL_stRAMCAL" type=uint8 offset=9359 min=0 max=255 m=1 b=0 units="dl" format=3.0 help="VVT Input 4 Type HTML=286.HTML" + +//ASAM mode=writevalue name="Fuel Pressure AD Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=9360 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_I_ADD1=8 EH_I_ADD2=9 EH_I_CMP1=10 EH_I_CMP2=11 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_UNUSED=125" format=3.0 help="Fuel Pressure AD Resource HTML=287.HTML" + +//ASAM mode=writeaxis_pts name="Fuel Flow Table_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=9362 min=0 max=20000 m=1 b=0 units="kPa" format=4.3 help="Fuel Flow curve x-axis points array HTML=288.HTML" xcount=17 xindexvar="Fuel Rail kPa" +//ASAM mode=writecurve name="Fuel Flow Table" parent="USERCAL_stRAMCAL" type=uint16 offset=9430 min=0 max=20000 m=1 b=0 units="mg/s" format=4.0 help="Fuel Flow curve data points array HTML=289.HTML" xcount=17 xindexvar="Fuel Rail kPa" + +//ASAM mode=writevalue name="Fuel Pressure Enable" parent="USERCAL_stRAMCAL" type=uint8 offset=9464 min=1 max=1 m=1 b=0 units="dl" format=4.0 help="Variable Fuel Pressure Enable HTML=290.HTML" +//ASAM mode=writevalue name="Fuel Pressure Sensor Gain" parent="USERCAL_stRAMCAL" type=sint32 offset=9465 min=1 max=4095 m=1 b=0 units="dl" format=4.0 help="Fuel Pressure Sensor Gain HTML=291.HTML" +//ASAM mode=writevalue name="Fuel Pressure Sensor Offset" parent="USERCAL_stRAMCAL" type=sint32 offset=9469 min=1 max=4095 m=1 b=0 units="dl" format=4.0 help="Fuel Pressure Sensor Offset HTML=292.HTML" + +//ASAM mode=writevalue name="Fuel Pressure P Gain" parent="USERCAL_stRAMCAL" type=uint16 offset=9473 min=0 max=65535 m=1 b=0 units="dl" format=3.0 help="TBC HTML=293.HTML" +//ASAM mode=writevalue name="Fuel Pressure I Gain" parent="USERCAL_stRAMCAL" type=uint16 offset=9475 min=0 max=65535 m=1 b=0 units="dl" format=3.0 help="TBC HTML=294.HTML" + +//ASAM mode=writevalue name="Fuel Prime Enable" parent="USERCAL_stRAMCAL" type=uint8 offset=9477 min=0 max=1 m=1 b=0 units="bool" format=1.0 help="TBC HTML=295.HTML" +//ASAM mode=writemap name="Secondary Timing Map 1" parent="USERCAL_stRAMCAL" type=uint16 offset=9478 min=0 max=50 m=0.1 b=0 units="Degrees" format=3.1 help="Timing Map Stage 1 HTML=296.HTML" xcount=17 xindexvar="Engine Speed Raw" ycount=17 yindexvar="MAP kPa" + +//ASAM mode=writeaxis_pts name="Torque Pedal Transfer Table_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=10056 min=0 max=20000 m=1 b=0 units="kPa" format=4.3 help="Pedal torque transfer curve x-axis points array HTML=297.HTML" xcount=17 xindexvar="Output Torque Estimate" +//ASAM mode=writecurve name="Torque Pedal Transfer Table" parent="USERCAL_stRAMCAL" type=uint16 offset=10124 min=0 max=20000 m=1 b=0 units="mg/s" format=4.0 help="Pedal Torque transfer data points array HTML=298.HTML" xcount=17 xindexvar="Output Torque Estimate" + +//ASAM mode=writeaxis_pts name="Pressure Valve Feedforward Table_XAXIS" parent="USERCAL_stRAMCAL" type=sint32 offset=10158 min=0 max=20000 m=1 b=0 units="kPa" format=4.3 help="Pedal torque transfer curve x-axis points array HTML=299.HTML" xcount=17 xindexvar="Output Torque Estimate" +//ASAM mode=writecurve name="Pressure Valve Feedforward Table" parent="USERCAL_stRAMCAL" type=uint16 offset=10226 min=0 max=20000 m=1 b=0 units="mg/s" format=4.0 help="Pedal Torque transfer data points array HTML=300.HTML" xcount=17 xindexvar="Output Torque Estimate" + +//ASAM mode=writevalue name="AFM Max Cycle Delta Pos" parent="USERCAL_stRAMCAL" type=uint16 offset=10260 min=0 max=65535 m=1 b=0 units="mg/cyc" format=4.0 help="Pedal Torque transfer data points array HTML=301.HTML" xcount=17 xindexvar="Output Torque Estimate" +//ASAM mode=writevalue name="AFM Max Cycle Delta Neg" parent="USERCAL_stRAMCAL" type=uint16 offset=10262 min=0 max=65535 m=1 b=0 units="mg/cyc" format=4.0 help="Pedal Torque transfer data points array HTML=302.HTML" xcount=17 xindexvar="Output Torque Estimate" + +//ASAM mode=writevalue name="PWM 2D Period 1" parent="USERCAL_stRAMCAL" type=uint16 offset=10264 min=0 max=65535 m=0.00213 b=0 units="ms" format=4.1 help="PWM 2D Period 1 HTML=303.HTML" +//ASAM mode=writevalue name="PWM 2D Period 2" parent="USERCAL_stRAMCAL" type=uint16 offset=10266 min=0 max=65535 m=0.00213 b=0 units="ms" format=4.1 help="PWM 2D Period 2 HTML=304.HTML" +//ASAM mode=writevalue name="PWM 2D Period 3" parent="USERCAL_stRAMCAL" type=uint16 offset=10268 min=0 max=65535 m=0.00213 b=0 units="ms" format=4.1 help="PWM 2D Period 3 HTML=305.HTML" +//ASAM mode=writevalue name="PWM 2D Period 4" parent="USERCAL_stRAMCAL" type=uint16 offset=10270 min=0 max=65535 m=0.00213 b=0 units="ms" format=4.1 help="PWM 2D Period 4 HTML=306.HTML" +//ASAM mode=writevalue name="PWM 2D Period 5" parent="USERCAL_stRAMCAL" type=uint16 offset=10272 min=0 max=65535 m=0.00213 b=0 units="ms" format=4.1 help="PWM 2D Period 5 HTML=307.HTML" +//ASAM mode=writevalue name="PWM 2D Period 6" parent="USERCAL_stRAMCAL" type=uint16 offset=10274 min=0 max=65535 m=0.00213 b=0 units="ms" format=4.1 help="PWM 2D Period 6 HTML=308.HTML" +//ASAM mode=writevalue name="PWM 2D Period 7" parent="USERCAL_stRAMCAL" type=uint16 offset=10276 min=0 max=65535 m=0.00213 b=0 units="ms" format=4.1 help="PWM 2D Period 7 HTML=309.HTML" +//ASAM mode=writevalue name="PWM 2D Period 8" parent="USERCAL_stRAMCAL" type=uint16 offset=10278 min=0 max=65535 m=0.00213 b=0 units="ms" format=4.1 help="PWM 2D Period 8 HTML=310.HTML" + +//ASAM mode=writevalue name="PWM 3D Period 1" parent="USERCAL_stRAMCAL" type=uint16 offset=10280 min=0 max=65535 m=0.00213 b=0 units="ms" format=4.1 help="PWM 3D Period 1 HTML=311.HTML" +//ASAM mode=writevalue name="PWM 3D Period 2" parent="USERCAL_stRAMCAL" type=uint16 offset=10282 min=0 max=65535 m=0.00213 b=0 units="ms" format=4.1 help="PWM 3D Period 2 HTML=312.HTML" +//ASAM mode=writevalue name="PWM 3D Period 3" parent="USERCAL_stRAMCAL" type=uint16 offset=10284 min=0 max=65535 m=0.00213 b=0 units="ms" format=4.1 help="PWM 3D Period 3 HTML=313.HTML" +//ASAM mode=writevalue name="PWM 3D Period 4" parent="USERCAL_stRAMCAL" type=uint16 offset=10286 min=0 max=65535 m=0.00213 b=0 units="ms" format=4.1 help="PWM 3D Period 4 HTML=314.HTML" + +//ASAM mode=writevalue name="Fuel pump primer Time" parent="USERCAL_stRAMCAL" type=uint8 offset=10288 min=0 max=65535 m=0.00213 b=0 units="ms" format=4.1 help="PWM 2D Period 1 HTML=315.HTML" +//ASAM mode=writevalue name="Daughterboard Slave Config" parent="USERCAL_stRAMCAL" type=uint8 offset=10289 min=0 max=65535 m=0.00213 b=0 units="ms" format=4.1 help="PWM 2D Period 1 HTML=316.HTML" +//ASAM mode=writevalue name="Daughterboard Slave Options" parent="USERCAL_stRAMCAL" type=uint8 offset=10290 min=0 max=65535 m=0.00213 b=0 units="ms" format=4.1 help="PWM 2D Period 1 HTML=317.HTML" + +//ASAM mode=writevalue name="AFR AD Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=10291 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_I_ADD1=8 EH_I_ADD2=9 EH_I_CMP1=10 EH_I_CMP2=11 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_UNUSED=125" format=3.0 help="AFR AD Resource HTML=318.HTML" +//ASAM mode=writevalue name="PPSM AD Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=10293 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_I_ADD1=8 EH_I_ADD2=9 EH_I_CMP1=10 EH_I_CMP2=11 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_UNUSED=125" format=3.0 help="AFR AD Resource HTML=319.HTML" +//ASAM mode=writevalue name="PPSS AD Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=10295 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_I_ADD1=8 EH_I_ADD2=9 EH_I_CMP1=10 EH_I_CMP2=11 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_UNUSED=125" format=3.0 help="AFR AD Resource HTML=320.HTML" + +//ASAM mode=writevalue name="Auxiliary Input 1 Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=10297 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_I_ADD1=8 EH_I_ADD2=9 EH_I_CMP1=10 EH_I_CMP2=11 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_UNUSED=125" format=3.0 help="Auxiliary Input 1 Resource HTML=321.HTML" +//ASAM mode=writevalue name="Auxiliary Input 2 Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=10299 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_I_ADD1=8 EH_I_ADD2=9 EH_I_CMP1=10 EH_I_CMP2=11 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_UNUSED=125" format=3.0 help="Auxiliary Input 2 Resource HTML=322.HTML" +//ASAM mode=writevalue name="Auxiliary Input 3 Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=10301 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_I_ADD1=8 EH_I_ADD2=9 EH_I_CMP1=10 EH_I_CMP2=11 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_UNUSED=125" format=3.0 help="Auxiliary Input 3 Resource HTML=323.HTML" +//ASAM mode=writevalue name="Auxiliary Input 4 Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=10303 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_I_ADD1=8 EH_I_ADD2=9 EH_I_CMP1=10 EH_I_CMP2=11 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_UNUSED=125" format=3.0 help="Auxiliary Input 4 Resource HTML=324.HTML" + +//ASAM mode=writevalue name="Auxiliary Input 1 Function" parent="USERCAL_stRAMCAL" type=uint16 offset=10305 min=0 max=255 units="ENUMERATION Off=0 Secondary_Timing_Map_(Low)=2 Secondary_Timing_Map_(High)=3 Secondary_TAFR_Map_(Low)=4 Secondary_TAFR_Map_(High)=5 Antilag_(Low)=6 Antilag_(High)=7 Drag_Mode_(Low)=8 Drag_Mode_(High)=9 Launch_(Low)=10 Launch_(High)=11" format=3.0 help="Auxiliary Input 1 Type HTML=325.HTML" +//ASAM mode=writevalue name="Auxiliary Input 2 Function" parent="USERCAL_stRAMCAL" type=uint16 offset=10307 min=0 max=255 units="ENUMERATION Off=0 Secondary_Timing_Map_(Low)=2 Secondary_Timing_Map_(High)=3 Secondary_TAFR_Map_(Low)=4 Secondary_TAFR_Map_(High)=5 Antilag_(Low)=6 Antilag_(High)=7 Drag_Mode_(Low)=8 Drag_Mode_(High)=9 Launch_(Low)=10 Launch_(High)=11" format=3.0 help="Auxiliary Input 2 Type HTML=326.HTML" +//ASAM mode=writevalue name="Auxiliary Input 3 Function" parent="USERCAL_stRAMCAL" type=uint16 offset=10309 min=0 max=255 units="ENUMERATION Off=0 Secondary_Timing_Map_(Low)=2 Secondary_Timing_Map_(High)=3 Secondary_TAFR_Map_(Low)=4 Secondary_TAFR_Map_(High)=5 Antilag_(Low)=6 Antilag_(High)=7 Drag_Mode_(Low)=8 Drag_Mode_(High)=9 Launch_(Low)=10 Launch_(High)=11" format=3.0 help="Auxiliary Input 3 Type HTML=327.HTML" +//ASAM mode=writevalue name="Auxiliary Input 4 Function" parent="USERCAL_stRAMCAL" type=uint16 offset=10311 min=0 max=255 units="ENUMERATION Off=0 Secondary_Timing_Map_(Low)=2 Secondary_Timing_Map_(High)=3 Secondary_TAFR_Map_(Low)=4 Secondary_TAFR_Map_(High)=5 Antilag_(Low)=6 Antilag_(High)=7 Drag_Mode_(Low)=8 Drag_Mode_(High)=9 Launch_(Low)=10 Launch_(High)=11" format=3.0 help="Auxiliary Input 4 Type HTML=328.HTML" + +//ASAM mode=writevalue name="AFR Input Gain" parent="USERCAL_stRAMCAL" type=sint32 offset=10313 min=1 max=4095 m=1 b=0 units="dl" format=4.0 help="Sync Phase Repeats HTML=329.HTML" +//ASAM mode=writevalue name="AFR Input Offset" parent="USERCAL_stRAMCAL" type=sint32 offset=10317 min=1 max=4095 m=1 b=0 units="dl" format=4.0 help="Sync Phase Repeats HTML=330.HTML" + +//ASAM mode=writevalue name="AFR Fuel Type Gain" parent="USERCAL_stRAMCAL" type=uint16 offset=10321 min=1 max=4095 m=1 b=0 units="dl" format=4.0 help="Sync Phase Repeats HTML=331.HTML" + +//ASAM mode=writeaxis_pts name="Fuel Cuts Table_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=10323 min=0 max=20000 m=1 b=0 units="RPM" format=4.3 help="Fuel Flow Cuts x-axis points array HTML=332.HTML" xcount=17 xindexvar="Engine Speed Raw" +//ASAM mode=writecurve name="Fuel Cuts Table" parent="USERCAL_stRAMCAL" type=uint16 offset=10391 min=0 max=20000 m=1 b=0 units="%" format=4.0 help="Fuel Flow Cuts data points array HTML=333.HTML" xcount=17 xindexvar="Engine Speed Raw" + +//ASAM mode=writevalue name="Aux 1 Threshold Low" parent="USERCAL_stRAMCAL" type=uint16 offset=10425 min=0 max=4095 m=0.001 b=0 units="V" format=4.3 help="Sync Phase Repeats HTML=334.HTML" +//ASAM mode=writevalue name="Aux 2 Threshold Low" parent="USERCAL_stRAMCAL" type=uint16 offset=10427 min=0 max=4095 m=0.001 b=0 units="V" format=4.3 help="Sync Phase Repeats HTML=335.HTML" +//ASAM mode=writevalue name="Aux 3 Threshold Low" parent="USERCAL_stRAMCAL" type=uint16 offset=10429 min=0 max=4095 m=0.001 b=0 units="V" format=4.3 help="Sync Phase Repeats HTML=336.HTML" +//ASAM mode=writevalue name="Aux 4 Threshold Low" parent="USERCAL_stRAMCAL" type=uint16 offset=10431 min=0 max=4095 m=0.001 b=0 units="V" format=4.3 help="Sync Phase Repeats HTML=337.HTML" +//ASAM mode=writevalue name="Aux 1 Threshold High" parent="USERCAL_stRAMCAL" type=uint16 offset=10433 min=0 max=4095 m=0.001 b=0 units="V" format=4.3 help="Sync Phase Repeats HTML=338.HTML" +//ASAM mode=writevalue name="Aux 2 Threshold High" parent="USERCAL_stRAMCAL" type=uint16 offset=10435 min=0 max=4095 m=0.001 b=0 units="V" format=4.3 help="Sync Phase Repeats HTML=339.HTML" +//ASAM mode=writevalue name="Aux 3 Threshold High" parent="USERCAL_stRAMCAL" type=uint16 offset=10437 min=0 max=4095 m=0.001 b=0 units="V" format=4.3 help="Sync Phase Repeats HTML=340.HTML" +//ASAM mode=writevalue name="Aux 4 Threshold High" parent="USERCAL_stRAMCAL" type=uint16 offset=10439 min=0 max=4095 m=0.001 b=0 units="V" format=4.3 help="Sync Phase Repeats HTML=341.HTML" + +//ASAM mode=writevalue name="GDI Vlv Offset" parent="USERCAL_stRAMCAL" type=uint16 offset=10441 min=0 max=4095 m=1 b=0 units="dl" format=4.0 help="Fuel Pressure Control Offset HTML=342.HTML" +//ASAM mode=writevalue name="GDI Vlv Start Offset" parent="USERCAL_stRAMCAL" type=uint16 offset=10443 min=0 max=4095 m=1 b=0 units="dl" format=4.0 help="Fuel Pressure Control Start Offset HTML=343.HTML" + +//ASAM mode=writeaxis_pts name="Secondary Timing Map 1_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=10445 min=0 max=8000 m=1 b=0 units="RPM" format=4.0 help="VE MAP Y Axis HTML=344.HTML" xcount=17 xindexvar="Engine Speed Raw" +//ASAM mode=writeaxis_pts name="Secondary Timing Map 1_YAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=10513 min=0 max=110000 m=0.001 b=0 units="kPa" format=3.1 help="VE MAP X Axis HTML=345.HTML" xcount=17 xindexvar="MAP kPa" + + +//ASAM mode=writevalue name="IAC Cold ISC Min" parent="USERCAL_stRAMCAL" type=uint16 offset=10581 min=0 max=4095 m=1 b=0 units="dl" format=4.0 help="Fuel Pressure Control Start Offset HTML=346.HTML" +//ASAM mode=writevalue name="IAC Cold ISC Max" parent="USERCAL_stRAMCAL" type=uint16 offset=10583 min=0 max=4095 m=1 b=0 units="dl" format=4.0 help="Fuel Pressure Control Start Offset HTML=347.HTML" +//ASAM mode=writevalue name="IAC Hot ISC Min" parent="USERCAL_stRAMCAL" type=uint16 offset=10585 min=0 max=4095 m=1 b=0 units="dl" format=4.0 help="Fuel Pressure Control Start Offset HTML=348.HTML" +//ASAM mode=writevalue name="IAC Hot ISC Max" parent="USERCAL_stRAMCAL" type=uint16 offset=10587 min=0 max=4095 m=1 b=0 units="dl" format=4.0 help="Fuel Pressure Control Start Offset HTML=349.HTML" +//ASAM mode=writevalue name="GDI Valve Min" parent="USERCAL_stRAMCAL" type=uint16 offset=10589 min=2000 max=12000 m=1 b=0 units="dl" format=5.0 help="Fuel Pressure Control Start Offset HTML=350.HTML" +//ASAM mode=writevalue name="GDI Valve Max" parent="USERCAL_stRAMCAL" type=uint16 offset=10591 min=7000 max=12000 m=1 b=0 units="dl" format=5.0 help="Fuel Pressure Control Start Offset HTML=351.HTML" +//ASAM mode=writevalue name="GDI Valve FF" parent="USERCAL_stRAMCAL" type=uint16 offset=10593 min=0 max=10000 m=1 b=0 units="dl" format=4.0 help="Fuel Pressure Control Start Offset HTML=352.HTML" + +//ASAM mode=writeaxis_pts name="Pedal Transfer Table_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=10595 min=0 max=5 m=0.001 b=0 units="V" format=4.3 help="ISC Target X Axis HTML=353.HTML" xcount=17 xindexvar="PPSM Voltage" +//ASAM mode=writecurve name="Pedal Transfer Table" parent="USERCAL_stRAMCAL" type=uint16 offset=10663 min=0 max=5 m=0.001 b=0 units="V" format=4.3 help="ISC Target Curve HTML=354.HTML" xcount=17 xindexvar="PPSM Voltage" + +//ASAM mode=writevalue name="Pressure Control Threshold" parent="USERCAL_stRAMCAL" type=uint16 offset=10697 min=0 max=10000 m=0.001 b=0 units="kPa" format=5.3 help="Pressure Control Threshold HTML=355.HTML" +//ASAM mode=writevalue name="Throttle Pressure Control Cal" parent="USERCAL_stRAMCAL" type=uint16 offset=10699 min=0 max=10000 m=1 b=0 units="dl" format=4.0 help="Throttle Pressure Control Cal HTML=356.HTML" +//ASAM mode=writevalue name="Pressure Control Hyst" parent="USERCAL_stRAMCAL" type=uint16 offset=10701 min=0 max=10000 m=0.001 b=0 units="kPa" format=5.3 help="Pressure Control Hyst HTML=357.HTML" + +//ASAM mode=writevalue name="Boost Charge MAP Enable" parent="USERCAL_stRAMCAL" type=uint8 offset=10703 min=0 max=1 m=1 b=0 units="bool" format=1.0 help="Pressure Control Hyst HTML=358.HTML" +//ASAM mode=writevalue name="Boost Charge TPS Limit" parent="USERCAL_stRAMCAL" type=uint16 offset=10704 min=0 max=90 m=0.001 b=0 units="Degrees" format=4.3 help="Pressure Control Hyst HTML=359.HTML" + + +//ASAM mode=writevalue name="ISC Entry Ramp" parent="USERCAL_stRAMCAL" type=uint16 offset=10706 min=0 max=1 m=1 b=0 units="RPM" format=1.0 help="Pressure Control Hyst HTML=360.HTML" +//ASAM mode=writevalue name="ISC Post Start Ramp" parent="USERCAL_stRAMCAL" type=uint16 offset=10708 min=0 max=1 m=1 b=0 units="RPM" format=1.0 help="Pressure Control Hyst HTML=361.HTML" + + +//ASAM mode=writevalue name="Airflow FME Limit Low" parent="USERCAL_stRAMCAL" type=uint32 offset=10710 min=0 max=400 m=0.000001 b=0 units="g/s" format=4.3 help=Air Flow Meter calibration curve data points array HTML=362.HTML" +//ASAM mode=writevalue name="Airflow FME Limit High" parent="USERCAL_stRAMCAL" type=uint32 offset=10714 min=0 max=400 m=0.000001 b=0 units="g/s" format=4.3 help=Air Flow Meter calibration curve data points array HTML=363.HTML" + +//ASAM mode=writevalue name="Torque Reduction Max Duration" parent="USERCAL_stRAMCAL" type=uint16 offset=10718 min=0 max=1 m=0.008 b=0 units="s" format=3.2 help="Pressure Control Hyst HTML=364.HTML" +//ASAM mode=writevalue name="Stall Saver RPM Threshold" parent="USERCAL_stRAMCAL" type=uint16 offset=10720 min=0 max=300 m=1 b=0 units="RPM" format=3.0 help="Pressure Control Hyst HTML=365.HTML" + +//ASAM mode=writeaxis_pts name="ETC Scale Table_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=10722 min=0 max=10000 m=1 b=0 units="RPM" format=4.0 help="XXXX X Axis HTML=366.HTML" xcount=17 xindexvar="Engine Speed Raw" +//ASAM mode=writecurve name="ETC Scale Table" parent="USERCAL_stRAMCAL" type=uint16 offset=10790 min=0 max=101 m=1.6 b=0 units="V" format=4.1 help="XXX Curve HTML=367.HTML" xcount=17 xindexvar="Engine Speed Raw" +//ASAM mode=writevalue name="Torque Reduction Max Fuel Cut" parent="USERCAL_stRAMCAL" type=uint16 offset=10824 min=0 max=100 m=1 b=0 units="%" format=3.2 help="Pressure Control Hyst HTML=368.HTML" +//ASAM mode=writevalue name="Shift Time Limit" parent="USERCAL_stRAMCAL" type=uint16 offset=10826 min=0 max=1 m=0.008 b=0 units="s" format=3.2 help="Pressure Control Hyst HTML=369.HTML" + +//ASAM mode=writevalue name="Boost Target 1" parent="USERCAL_stRAMCAL" type=uint16 offset=10828 min=0 max=200 m=0.01 b=0 units="kPa" format=4.2 help="Boost Gear 1 HTML=370.HTML" +//ASAM mode=writevalue name="Boost Target 2" parent="USERCAL_stRAMCAL" type=uint16 offset=10830 min=0 max=200 m=0.01 b=0 units="kPa" format=4.2 help="Boost Gear 2 HTML=371.HTML" +//ASAM mode=writevalue name="Boost Target 3" parent="USERCAL_stRAMCAL" type=uint16 offset=10832 min=0 max=200 m=0.01 b=0 units="kPa" format=4.2 help="Boost Gear 3 HTML=372.HTML" +//ASAM mode=writevalue name="Boost Target 4" parent="USERCAL_stRAMCAL" type=uint16 offset=10834 min=0 max=200 m=0.01 b=0 units="kPa" format=4.2 help="Boost Gear 4 HTML=373.HTML" +//ASAM mode=writevalue name="Boost Target 5" parent="USERCAL_stRAMCAL" type=uint16 offset=10836 min=0 max=200 m=0.01 b=0 units="kPa" format=4.2 help="Boost Gear 5 HTML=374.HTML" +//ASAM mode=writevalue name="Boost Target 6" parent="USERCAL_stRAMCAL" type=uint16 offset=10838 min=0 max=200 m=0.01 b=0 units="kPa" format=4.2 help="Boost Gear 6 HTML=375.HTML" + +//ASAM mode=writevalue name="GDI Pressure Min" parent="USERCAL_stRAMCAL" type=uint16 offset=10840 min=0 max=25 m=1 b=0 units="kPa" format=4.2 help="Boost Gear 6 HTML=376.HTML" +//ASAM mode=writevalue name="GDI Pressure Max" parent="USERCAL_stRAMCAL" type=uint16 offset=10842 min=0 max=25 m=1 b=0 units="kPa" format=4.2 help="Boost Gear 6 HTML=377.HTML" +//ASAM mode=writevalue name="GDI MAP Min" parent="USERCAL_stRAMCAL" type=uint32 offset=10844 min=0 max=200 m=0.001 b=0 units="kPa" format=4.2 help="Boost Gear 6 HTML=378.HTML" +//ASAM mode=writevalue name="GDI MAP Max" parent="USERCAL_stRAMCAL" type=uint32 offset=10848 min=0 max=200 m=0.001 b=0 units="kPa" format=4.2 help="Boost Gear 6 HTML=379.HTML" + +//ASAM mode=writevalue name="EST Pos Rate Max" parent="USERCAL_stRAMCAL" type=uint16 offset=10852 min=0 max=200 m=100 b=0 units="Deg/s" format=4.2 help="EST Pos Rate Max HTML=380.HTML" +//ASAM mode=writevalue name="EST Neg Rate Max" parent="USERCAL_stRAMCAL" type=uint16 offset=10854 min=0 max=200 m=100 b=0 units="Deg/s" format=4.2 help="EST Neg Rate Max HTML=381.HTML" + +//ASAM mode=writevalue name="Pressure Control DPos" parent="USERCAL_stRAMCAL" type=uint16 offset=10856 min=0 max=1000 m=1 b=0 units="dl" format=4.2 help="EST Pos Rate Max HTML=382.HTML" +//ASAM mode=writevalue name="Pressure Control DNeg" parent="USERCAL_stRAMCAL" type=uint16 offset=10858 min=0 max=1000 m=1 b=0 units="dl" format=4.2 help="EST Pos Rate Max HTML=383.HTML" + +//ASAM mode=writevalue name="Shift Count Pressure Control Limit" parent="USERCAL_stRAMCAL" type=uint16 offset=10860 min=0 max=1 m=0.008 b=0 units="s" format=4.3 help="EST Pos Rate Max HTML=384.HTML" +//ASAM mode=writevalue name="Shift Pressure Control" parent="USERCAL_stRAMCAL" type=uint16 offset=10862 min=0 max=100 m=1 b=0 units="%" format=4.2 help="EST Pos Rate Max HTML=385.HTML" + +//ASAM mode=writevalue name="PWM 3D Slow 1 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=10864 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="PWM 3D Slow 1 IO Resource HTML=386.HTML" +//ASAM mode=writevalue name="PWM 3D Slow 2 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=10866 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="PWM 3D Slow 2 IO Resource HTML=387.HTML" +//ASAM mode=writevalue name="PWM 3D Slow 3 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=10868 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="PWM 3D Slow 3 IO Resource HTML=388.HTML" +//ASAM mode=writevalue name="PWM 3D Slow 4 IO Resource" parent="USERCAL_stRAMCAL" type=uint16 offset=10870 min=0 max=255 units="ENUMERATION EH_IO_GPSE1=0 EH_IO_GPSE2=1 EH_IO_GPSE3=2 EH_IO_GPSE4=3 EH_IO_GPSE5=4 EH_IO_GPSE6=5 EH_IO_GPSE7=6 EH_IO_GPSE8=7 EH_IO_UART1_TX=15 EH_IO_UART1_RX=16 EH_IO_UART1_CTS=17 EH_IO_UART1_RTS=18 EH_IO_UART2_TX=19 EH_IO_UART2_RX=20 EH_IO_SPI1_MISO=21 EH_IO_SPI1_MOSI=22 EH_IO_SPI1_CLK=23 EH_IO_SPI1_CS=24 EH_IO_TMR1=25 EH_IO_TMR2=26 EH_IO_TMR3=27 EH_IO_TMR4=28 EH_IO_TMR5=29 EH_IO_TMR6=30 EH_IO_TMR7=31 EH_IO_TMR8=32 EH_IO_TMR9=33 EH_IO_TMR10=34 EH_IO_TMR11=35 EH_IO_TMR12=36 EH_IO_TMR13=37 EH_IO_TMR14=38 EH_IO_TMR15=39 EH_IO_TMR16=40 EH_IO_TMR17=41 EH_IO_TMR18=42 EH_IO_IIC1_SCL=43 EH_IO_IIC1_SDA=44 EH_IO_GP1=47 EH_IO_GP2=48 EH_IO_GP3=49 EH_IO_GP4=50 EH_IO_GP5=51 EH_IO_GP6=52 EH_IO_GP7=53 EH_IO_GP8=54 EH_IO_GP9=55 EH_IO_GP10=56 EH_IO_GP11=57 EH_IO_GP12=58 EH_IO_GP13=59 EH_IO_GP14=60 EH_IO_UNUSED=125" format=3.0 help="PWM 3D Slow 4 IO Resource HTML=389.HTML" + +//ASAM mode=writevalue name="PWM 3D Slow 1 Period" parent="USERCAL_stRAMCAL" type=uint16 offset=10872 min=0 max=255 m=1 b=0 units="ms" format=2.0 help="PWM 3D Slow 1 Period HTML=390.HTML" +//ASAM mode=writevalue name="PWM 3D Slow 2 Period" parent="USERCAL_stRAMCAL" type=uint16 offset=10874 min=0 max=255 m=1 b=0 units="ms" format=2.0 help="PWM 3D Slow 2 Period HTML=391.HTML" +//ASAM mode=writevalue name="PWM 3D Slow 3 Period" parent="USERCAL_stRAMCAL" type=uint16 offset=10876 min=0 max=255 m=1 b=0 units="ms" format=2.0 help="PWM 3D Slow 3 Period HTML=392.HTML" +//ASAM mode=writevalue name="PWM 3D Slow 4 Period" parent="USERCAL_stRAMCAL" type=uint16 offset=10878 min=0 max=255 m=1 b=0 units="ms" format=2.0 help="PWM 3D Slow 4 Period HTML=393.HTML" + +//ASAM mode=writevalue name="Sensor Hyst Limit RPM" parent="USERCAL_stRAMCAL" type=uint16 offset=10880 min=0 max=8000 m=1 b=0 units="RPM" format=4.0 help="RPM Sensor Hyst Limit=394.HTML" + +//ASAM mode=writevalue name="PPS Cal Min" parent="USERCAL_stRAMCAL" type=uint32 offset=10882 min=0 max=5 m=0.001 b=0 units="V" format=3.2 help="TPS voltage at min throttle position or neutral ETC position HTML=395.HTML" +//ASAM mode=writevalue name="PPS Cal Max" parent="USERCAL_stRAMCAL" type=uint32 offset=10886 min=0 max=5 m=0.001 b=0 units="V" format=3.2 help="TPS voltage at maximum throttle position HTML=396.HTML" + +//ASAM mode=writeaxis_pts name="Pseudo Manifold Pressure Map_XAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=10890 min=0 max=8000 m=1 b=0 units="RPM" format=4.0 help="Pseudo Manifold Pressure MAP X Axis HTML=397.HTML" xcount=17 xindexvar="Engine Speed Raw" +//ASAM mode=writeaxis_pts name="Pseudo Manifold Pressure Map_YAXIS" parent="USERCAL_stRAMCAL" type=uint32 offset=10958 min=0 max=90 m=0.001 b=0 units="Degrees" format=3.1 help="Pseudo Manifold Pressure MAP Y Axis HTML=398.HTML" xcount=17 xindexvar="Throttle Angle" +//ASAM mode=writemap name="Pseudo Manifold Pressure Map" parent="USERCAL_stRAMCAL" type=uint32 offset=11026 min=0 max=101 m=0.001 b=0 units="kPa" format=4.1 help="Pseudo Manifold Pressure Map HTML=399.HTML" xcount=17 xindexvar="Engine Speed Raw" ycount=17 yindexvar="MAP kPa" + +//ASAM mode=writevalue name="Pseudo Manifold Pressure Enable" parent="USERCAL_stRAMCAL" type=uint8 offset=12182 min=0 max=1 m=1 b=0 units="bool" format=1.0 help="Pseudo Manifold Pressure Enable HTML=400.HTML" + +//ASAM mode=writevalue name="VSS Per 1k RPM G1" parent="USERCAL_stRAMCAL" type=uint16 offset=12183 min=0 max=6555 m=0.1 b=0 units="km/h" format=5.1 help="VSS Per 1000 RPM G1 HTML=401.HTML" +//ASAM mode=writevalue name="VSS Per 1k RPM G2" parent="USERCAL_stRAMCAL" type=uint16 offset=12185 min=0 max=6555 m=0.1 b=0 units="km/h" format=5.1 help="VSS Per 1000 RPM G2 HTML=402.HTML" +//ASAM mode=writevalue name="VSS Per 1k RPM G3" parent="USERCAL_stRAMCAL" type=uint16 offset=12187 min=0 max=6555 m=0.1 b=0 units="km/h" format=5.1 help="VSS Per 1000 RPM G3 HTML=403.HTML" +//ASAM mode=writevalue name="VSS Per 1k RPM G4" parent="USERCAL_stRAMCAL" type=uint16 offset=12189 min=0 max=6555 m=0.1 b=0 units="km/h" format=5.1 help="VSS Per 1000 RPM G4 HTML=404.HTML" +//ASAM mode=writevalue name="VSS Per 1k RPM G5" parent="USERCAL_stRAMCAL" type=uint16 offset=12191 min=0 max=6555 m=0.1 b=0 units="km/h" format=5.1 help="VSS Per 1000 RPM G5 HTML=405.HTML" +//ASAM mode=writevalue name="VSS Per 1k RPM G6" parent="USERCAL_stRAMCAL" type=uint16 offset=12193 min=0 max=6555 m=0.1 b=0 units="km/h" format=5.1 help="VSS Per 1000 RPM G6 HTML=406.HTML" +//ASAM mode=writevalue name="VSS Per 1k RPM G7" parent="USERCAL_stRAMCAL" type=uint16 offset=12195 min=0 max=6555 m=0.1 b=0 units="km/h" format=5.1 help="VSS Per 1000 RPM G7 HTML=407.HTML" +//ASAM mode=writevalue name="VSS Per 1k RPM G8" parent="USERCAL_stRAMCAL" type=uint16 offset=12197 min=0 max=6555 m=0.1 b=0 units="km/h" format=5.1 help="VSS Per 1000 RPM G8 HTML=408.HTML" + +//ASAM mode=writevalue name="VSS CAN Calibration" parent="USERCAL_stRAMCAL" type=uint16 offset=12199 max=65535 m=1 b=0 units="dl" format=5.0 help="VSS CAN Calibration HTML=409.HTML" + +//ASAM mode=writevalue name="ETC Override Keys" type=uint16 offset=12201 min=0 max=65535 m=1 b=0 units="dl" format=5.0 help="ETC Override Keys" +//ASAM mode=writevalue name="ETC Override" type=uint16 offset=12203 min=0 max=255 m=1 b=0 units="dl" format=5.0 help="ETC Override" +//ASAM mode=writevalue name="Vehicle Model Diag" type=uint16 offset=12205 min=0 max=255 units="ENUMERATION VAG_GTI_DSG_DQ250_Mk6=0 VAG_GTI_MT6_Mk6=1" format=3.0 help="ETC Override" + +//ASAM mode=writevalue name="CAL CRC" parent="USERCAL_stRAMCAL" type=uint16 offset=12207 min=0 max=255 m=1 b=0 units="dl" format=3.0 help="CAL CRC16" +/* NOTE MUST ALWAYS INCLUDE CAL STRUCT ELEMENTS ONE FOR ONE AND IN ORDER */ + +/* Testing offsets table for ASAM parsing tool here */ +#ifdef _USERCAL_C + +#define OFFSETS_DATA \ +{ \ + offsetof(USERCAL_tstCalibration, userCalADRefH),\ + offsetof(USERCAL_tstCalibration, userCalVRef445),\ + offsetof(USERCAL_tstCalibration, userCalVNernstTarget),\ + offsetof(USERCAL_tstCalibration, userCalRNernstReady),\ + offsetof(USERCAL_tstCalibration, userCalRHeaterThreshold),\ + offsetof(USERCAL_tstCalibration, au32UserCalPumpCurrentPFactor),\ + offsetof(USERCAL_tstCalibration, au32UserCalPumpCurrentMFactor),\ + offsetof(USERCAL_tstCalibration, ai32UserCalPumpCurrentOffset),\ + offsetof(USERCAL_tstCalibration, aUserCalPumpSpread),\ + offsetof(USERCAL_tstCalibration, aUserCalPumpLambda),\ + offsetof(USERCAL_tstCalibration, au8UserCalPumpSensorTrim),\ + offsetof(USERCAL_tstCalibration, aUserStoichFuelCal),\ + offsetof(USERCAL_tstCalibration, au8UserCalPumpDeadband),\ + offsetof(USERCAL_tstCalibration, au16UserCalFreeAirPoints),\ + offsetof(USERCAL_tstCalibration, aUserHeaterAlarmCurrent),\ + offsetof(USERCAL_tstCalibration, u8WarmUpDelay),\ + offsetof(USERCAL_tstCalibration, u8DisplayMode),\ + offsetof(USERCAL_tstCalibration, u8BackLightEnable),\ + offsetof(USERCAL_tstCalibration, userCalTPSCalMin),\ + offsetof(USERCAL_tstCalibration, userCalTPSCalMax),\ + offsetof(USERCAL_tstCalibration, aUserCURVEAfmTFSpread),\ + offsetof(USERCAL_tstCalibration, aUserCURVEAfmTFTable),\ + offsetof(USERCAL_tstCalibration, aUserInjResponseSpread),\ + offsetof(USERCAL_tstCalibration, aUserInjResponseTable),\ + offsetof(USERCAL_tstCalibration, aUserCoolantSensorSpread),\ + offsetof(USERCAL_tstCalibration, aUserCoolantSensorTable),\ + offsetof(USERCAL_tstCalibration, aUserCoolantEnrichmentSpread),\ + offsetof(USERCAL_tstCalibration, aUserCoolantEnrichmentTable),\ + offsetof(USERCAL_tstCalibration, aUserTAFRxSpread),\ + offsetof(USERCAL_tstCalibration, aUserTAFRySpread),\ + offsetof(USERCAL_tstCalibration, aUserMAPTAFR),\ + offsetof(USERCAL_tstCalibration, aUserTimingxSpread),\ + offsetof(USERCAL_tstCalibration, aUserTimingySpread),\ + offsetof(USERCAL_tstCalibration, aUserTimingMap),\ + offsetof(USERCAL_tstCalibration, aUserVExSpread),\ + offsetof(USERCAL_tstCalibration, aUserVEySpread),\ + offsetof(USERCAL_tstCalibration, aUserMAPVE),\ + offsetof(USERCAL_tstCalibration, aUserCoolantStartEnrichmentSpread),\ + offsetof(USERCAL_tstCalibration, aUserCoolantStartEnrichmentTable),\ + offsetof(USERCAL_tstCalibration, aUserCoolantPostStartEnrichmentSpread),\ + offsetof(USERCAL_tstCalibration, aUserCoolantPostStartEnrichmentTable),\ + offsetof(USERCAL_tstCalibration, aUserCrankingAirflowSpread),\ + offsetof(USERCAL_tstCalibration, aUserCrankingAirflowTable),\ + offsetof(USERCAL_tstCalibration, aUserDwellSpread),\ + offsetof(USERCAL_tstCalibration, aUserDwellTable),\ + offsetof(USERCAL_tstCalibration, aUserAirTempCorrectionSpread),\ + offsetof(USERCAL_tstCalibration, aUserAirTempCorrectionTable),\ + offsetof(USERCAL_tstCalibration, aUserTPSMovementCorrectionSpread),\ + offsetof(USERCAL_tstCalibration, aUserTPSMovementCorrectionTable),\ + offsetof(USERCAL_tstCalibration, aUserInjectionPhasingSpread),\ + offsetof(USERCAL_tstCalibration, aUserInjectionPhasingTable),\ + offsetof(USERCAL_tstCalibration, aUserCTSTimingCorrectionSpread),\ + offsetof(USERCAL_tstCalibration, aUserCTSTimingCorrectionTable),\ + offsetof(USERCAL_tstCalibration, aUserATSTimingCorrectionSpread),\ + offsetof(USERCAL_tstCalibration, aUserATSTimingCorrectionTable),\ + offsetof(USERCAL_tstCalibration, aUserISCSpeedTargetSpread),\ + offsetof(USERCAL_tstCalibration, aUserISCSpeedTargetTable),\ + offsetof(USERCAL_tstCalibration, aUserStepperCloseTable),\ + offsetof(USERCAL_tstCalibration, aUserStepperOpenTable),\ + offsetof(USERCAL_tstCalibration, u32UserStepperHomeSteps),\ + offsetof(USERCAL_tstCalibration, aUserPrimaryTriggerTable),\ + offsetof(USERCAL_tstCalibration, aUserSecondaryTriggerTable),\ + offsetof(USERCAL_tstCalibration, aUserSyncPointsTable),\ + offsetof(USERCAL_tstCalibration, u8UserPrimaryEdgeSetup),\ + offsetof(USERCAL_tstCalibration, u8UserSecondaryEdgeSetup),\ + offsetof(USERCAL_tstCalibration, u8UserPrimaryVREnable),\ + offsetof(USERCAL_tstCalibration, u8UserSecondaryVREnable),\ + offsetof(USERCAL_tstCalibration, u8UserFirstEdgeRisingPrimary),\ + offsetof(USERCAL_tstCalibration, u8UserFirstEdgeRisingSecondary),\ + offsetof(USERCAL_tstCalibration, au32InjectionSequence),\ + offsetof(USERCAL_tstCalibration, au32IgnitionSequence),\ + offsetof(USERCAL_tstCalibration, enSimpleCamSyncSource),\ + offsetof(USERCAL_tstCalibration, boCamSyncHighLate),\ + offsetof(USERCAL_tstCalibration, u32CamSyncSampleToothCount),\ + offsetof(USERCAL_tstCalibration, u16ManifoldVolumeCC),\ + offsetof(USERCAL_tstCalibration, u8CylCount),\ + offsetof(USERCAL_tstCalibration, u16InjFlowRate),\ + offsetof(USERCAL_tstCalibration, aUserBackupAirflowxSpread),\ + offsetof(USERCAL_tstCalibration, aUserBackupAirflowySpread),\ + offsetof(USERCAL_tstCalibration, aUserBackupAirflowMap),\ + offsetof(USERCAL_tstCalibration, u8ManifoldTimeConstantTrim),\ + offsetof(USERCAL_tstCalibration, u8EnableBackupAirflowTransients),\ + offsetof(USERCAL_tstCalibration, aUserPrimerSpread),\ + offsetof(USERCAL_tstCalibration, aUserPrimerTable),\ + offsetof(USERCAL_tstCalibration, aUserInjShortOpeningSpread),\ + offsetof(USERCAL_tstCalibration, aUserInjShortOpeningTable),\ + offsetof(USERCAL_tstCalibration, u32STTNegLimit),\ + offsetof(USERCAL_tstCalibration, u32STTPosLimit),\ + offsetof(USERCAL_tstCalibration, u32CLStepClosed),\ + offsetof(USERCAL_tstCalibration, u32CLIncClosed),\ + offsetof(USERCAL_tstCalibration, u32CLStepOpen),\ + offsetof(USERCAL_tstCalibration, u32CLIncOpen),\ + offsetof(USERCAL_tstCalibration, u16TimingMainOffset),\ + offsetof(USERCAL_tstCalibration, u32AFMTransientControlRPMLimit),\ + offsetof(USERCAL_tstCalibration, u8WastedSparkEnable),\ + offsetof(USERCAL_tstCalibration, u16AFRReinstate),\ + offsetof(USERCAL_tstCalibration, u16AFRCutoff),\ + offsetof(USERCAL_tstCalibration, u32TPSClosedLower),\ + offsetof(USERCAL_tstCalibration, u32TPSClosedUpper),\ + offsetof(USERCAL_tstCalibration, u32ISCESTTrimPos),\ + offsetof(USERCAL_tstCalibration, u32ISCESTTrimNeg),\ + offsetof(USERCAL_tstCalibration, u32CLO2ESTTrimPos),\ + offsetof(USERCAL_tstCalibration, u32CLO2ESTTrimNeg),\ + offsetof(USERCAL_tstCalibration, u16CylinderCC),\ + offsetof(USERCAL_tstCalibration, u8EnableAFMPrimaryInputOpen),\ + offsetof(USERCAL_tstCalibration, u32SpeedDensityAFMTPSLim),\ + offsetof(USERCAL_tstCalibration, au16SeqRPMLimit),\ + offsetof(USERCAL_tstCalibration, u16SeqRPMLimitHyst),\ + offsetof(USERCAL_tstCalibration, u16HighVacuumEnableKpa),\ + offsetof(USERCAL_tstCalibration, u16HighVacuumDisableKpa),\ + offsetof(USERCAL_tstCalibration, u16OverrunCutEnableRPM),\ + offsetof(USERCAL_tstCalibration, u16OverrunCutDisableRPM),\ + offsetof(USERCAL_tstCalibration, u16RPMRunThreshold),\ + offsetof(USERCAL_tstCalibration, u8SeqFuelAssign),\ + offsetof(USERCAL_tstCalibration, u16ESTFilterClosed),\ + offsetof(USERCAL_tstCalibration, u16ESTFilterOpen),\ + offsetof(USERCAL_tstCalibration, u16ESTCLGain),\ + offsetof(USERCAL_tstCalibration, u8EnableAFMPrimaryInputClosed),\ + offsetof(USERCAL_tstCalibration, s16SequenceFuelOffset),\ + offsetof(USERCAL_tstCalibration, u16SequenceFuelGain),\ + offsetof(USERCAL_tstCalibration, boTPSCANPrimary),\ + offsetof(USERCAL_tstCalibration, boPPSCANPrimary),\ + offsetof(USERCAL_tstCalibration, boCTSCANPrimary),\ + offsetof(USERCAL_tstCalibration, boATSCANPrimary),\ + offsetof(USERCAL_tstCalibration, boMAPCANPrimary),\ + offsetof(USERCAL_tstCalibration, au32PrioCANID),\ + offsetof(USERCAL_tstCalibration, au8SensorCANDataOffset),\ + offsetof(USERCAL_tstCalibration, au8SensorCANDataByteCount),\ + offsetof(USERCAL_tstCalibration, u32SyncPhaseRepeats),\ + offsetof(USERCAL_tstCalibration, s32MapSensorGain),\ + offsetof(USERCAL_tstCalibration, s32MapSensorOffset),\ + offsetof(USERCAL_tstCalibration, u8InjDivide),\ + offsetof(USERCAL_tstCalibration, u8CLO2Leftenable),\ + offsetof(USERCAL_tstCalibration, u8CLO2RightEnable),\ + offsetof(USERCAL_tstCalibration, u8ReturnlessEnable),\ + offsetof(USERCAL_tstCalibration, u16ReturnlessPressureKPa),\ + offsetof(USERCAL_tstCalibration, u8CrankingAirflowEnable),\ + offsetof(USERCAL_tstCalibration, u8StepperIACEnable),\ + offsetof(USERCAL_tstCalibration, u16IACStepsOpenHot),\ + offsetof(USERCAL_tstCalibration, u16IACStepsOpenCold),\ + offsetof(USERCAL_tstCalibration, u16IdleEntryOffset),\ + offsetof(USERCAL_tstCalibration, s32RadFanOnTemp),\ + offsetof(USERCAL_tstCalibration, s32RadFanOffTemp),\ + offsetof(USERCAL_tstCalibration, enFuelPumpRelay),\ + offsetof(USERCAL_tstCalibration, enESTBypass),\ + offsetof(USERCAL_tstCalibration, aUserAirSensorSpread),\ + offsetof(USERCAL_tstCalibration, aUserAirSensorTable),\ + offsetof(USERCAL_tstCalibration, aFuelIOResource),\ + offsetof(USERCAL_tstCalibration, aESTIOResource),\ + offsetof(USERCAL_tstCalibration, aIACIOResource),\ + offsetof(USERCAL_tstCalibration, boOBDISCADV),\ + offsetof(USERCAL_tstCalibration, u8TriggerType),\ + offsetof(USERCAL_tstCalibration, u8SyncType),\ + offsetof(USERCAL_tstCalibration, u8TriggerPullStrength),\ + offsetof(USERCAL_tstCalibration, u8SyncPullStrength),\ + offsetof(USERCAL_tstCalibration, u16MinLinearFuelPulse),\ + offsetof(USERCAL_tstCalibration, u16CTSADResource),\ + offsetof(USERCAL_tstCalibration, u16MAPADResource),\ + offsetof(USERCAL_tstCalibration, u16ATSADResource),\ + offsetof(USERCAL_tstCalibration, u16AFMADResource),\ + offsetof(USERCAL_tstCalibration, u16TPSADResource),\ + offsetof(USERCAL_tstCalibration, aUserTipInCorrectionSpread),\ + offsetof(USERCAL_tstCalibration, aUserTipInCorrectionTable),\ + offsetof(USERCAL_tstCalibration, aLogicBlockVar),\ + offsetof(USERCAL_tstCalibration, aLogicBlockOperand),\ + offsetof(USERCAL_tstCalibration, aLogicBlockChainOutput),\ + offsetof(USERCAL_tstCalibration, enThermoFanRelay),\ + offsetof(USERCAL_tstCalibration, aESTIOMuxResource),\ + offsetof(USERCAL_tstCalibration, boUEGOCANPrimary),\ + offsetof(USERCAL_tstCalibration, aPWM2DAxesSourceXIDX),\ + offsetof(USERCAL_tstCalibration, aPWM3DAxesSourceXIDX),\ + offsetof(USERCAL_tstCalibration, aPWM3DAxesSourceYIDX),\ + offsetof(USERCAL_tstCalibration, aPWM2DIOOutputResource),\ + offsetof(USERCAL_tstCalibration, aPWM3DIOOutputResource),\ + offsetof(USERCAL_tstCalibration, aUserPWM2D_1SpreadX),\ + offsetof(USERCAL_tstCalibration, aUserPWM2D_2SpreadX),\ + offsetof(USERCAL_tstCalibration, aUserPWM2D_3SpreadX),\ + offsetof(USERCAL_tstCalibration, aUserPWM2D_4SpreadX),\ + offsetof(USERCAL_tstCalibration, aUserPWM2D_5SpreadX),\ + offsetof(USERCAL_tstCalibration, aUserPWM2D_6SpreadX),\ + offsetof(USERCAL_tstCalibration, aUserPWM2D_7SpreadX),\ + offsetof(USERCAL_tstCalibration, aUserPWM2D_8SpreadX),\ + offsetof(USERCAL_tstCalibration, aUserPWM2D_1Data),\ + offsetof(USERCAL_tstCalibration, aUserPWM2D_2Data),\ + offsetof(USERCAL_tstCalibration, aUserPWM2D_3Data),\ + offsetof(USERCAL_tstCalibration, aUserPWM2D_4Data),\ + offsetof(USERCAL_tstCalibration, aUserPWM2D_5Data),\ + offsetof(USERCAL_tstCalibration, aUserPWM2D_6Data),\ + offsetof(USERCAL_tstCalibration, aUserPWM2D_7Data),\ + offsetof(USERCAL_tstCalibration, aUserPWM2D_8Data),\ + offsetof(USERCAL_tstCalibration, aUserPWM3D_1SpreadX),\ + offsetof(USERCAL_tstCalibration, aUserPWM3D_2SpreadX),\ + offsetof(USERCAL_tstCalibration, aUserPWM3D_3SpreadX),\ + offsetof(USERCAL_tstCalibration, aUserPWM3D_4SpreadX),\ + offsetof(USERCAL_tstCalibration, aUserPWM3D_1SpreadY),\ + offsetof(USERCAL_tstCalibration, aUserPWM3D_2SpreadY),\ + offsetof(USERCAL_tstCalibration, aUserPWM3D_3SpreadY),\ + offsetof(USERCAL_tstCalibration, aUserPWM3D_4SpreadY),\ + offsetof(USERCAL_tstCalibration, aUserPWM3D_1Data),\ + offsetof(USERCAL_tstCalibration, aUserPWM3D_2Data),\ + offsetof(USERCAL_tstCalibration, aUserPWM3D_3Data),\ + offsetof(USERCAL_tstCalibration, aUserPWM3D_4Data),\ + offsetof(USERCAL_tstCalibration, u16FuelPressureSolenoidResource),\ + offsetof(USERCAL_tstCalibration, u8VCTABPullupEnable),\ + offsetof(USERCAL_tstCalibration, u8VCTCDPullupEnable),\ + offsetof(USERCAL_tstCalibration, aVVTInputResource),\ + offsetof(USERCAL_tstCalibration, aVVTInputType),\ + offsetof(USERCAL_tstCalibration, u16FRSADResource),\ + offsetof(USERCAL_tstCalibration, aUserFuelFlowRateSpread),\ + offsetof(USERCAL_tstCalibration, aUserFuelFlowRateTable),\ + offsetof(USERCAL_tstCalibration, u8VariableFuelPressureEnable),\ + offsetof(USERCAL_tstCalibration, s32FuelPressureSensorGain),\ + offsetof(USERCAL_tstCalibration, s32FuelPressureSensorOffset),\ + offsetof(USERCAL_tstCalibration, u16FuelPressurePGain),\ + offsetof(USERCAL_tstCalibration, u16FuelPressureIGain),\ + offsetof(USERCAL_tstCalibration, u8FuelPrimeEnable),\ + offsetof(USERCAL_tstCalibration, aUserTimingMapStage1),\ + offsetof(USERCAL_tstCalibration, aUserTorquePedalTransferSpread),\ + offsetof(USERCAL_tstCalibration, aUserTorquePedalTransferTable),\ + offsetof(USERCAL_tstCalibration, aUserPressureValveFeedForwardSpread),\ + offsetof(USERCAL_tstCalibration, aUserPressureValveFeedForwardTable),\ + offsetof(USERCAL_tstCalibration, u16AFMMaxCycleDeltaUgPos),\ + offsetof(USERCAL_tstCalibration, u16AFMMaxCycleDeltaUgNeg),\ + offsetof(USERCAL_tstCalibration, aUserPWM2DPeriod),\ + offsetof(USERCAL_tstCalibration, aUserPWM3DPeriod),\ + offsetof(USERCAL_tstCalibration, u8FuelPumpPrimerTime),\ + offsetof(USERCAL_tstCalibration, u8DBSlaveConfig),\ + offsetof(USERCAL_tstCalibration, u8DBSlaveOptions),\ + offsetof(USERCAL_tstCalibration, u16AFRADResource),\ + offsetof(USERCAL_tstCalibration, u16PPSMADResource),\ + offsetof(USERCAL_tstCalibration, u16PPSSADResource),\ + offsetof(USERCAL_tstCalibration, s32AFRADInputGain),\ + offsetof(USERCAL_tstCalibration, s32AFRADInputOffset),\ + offsetof(USERCAL_tstCalibration, u16AFRFuelTypeGain),\ + offsetof(USERCAL_tstCalibration, au16AuxInputResource),\ + offsetof(USERCAL_tstCalibration, au16AuxInputFunction),\ + offsetof(USERCAL_tstCalibration, aUserFuelCutsSpread),\ + offsetof(USERCAL_tstCalibration, aUserFuelCutsTable),\ + offsetof(USERCAL_tstCalibration, au16AuxInputLowThres),\ + offsetof(USERCAL_tstCalibration, au16AuxInputHighThres),\ + offsetof(USERCAL_tstCalibration, u16FuelPressureControlOffset),\ + offsetof(USERCAL_tstCalibration, u16FuelPressureControlStartOffset),\ + offsetof(USERCAL_tstCalibration, u16ISCColdISCMin),\ + offsetof(USERCAL_tstCalibration, u16ISCColdISCMax),\ + offsetof(USERCAL_tstCalibration, u16ISCHotISCMin),\ + offsetof(USERCAL_tstCalibration, u16ISCHotISCMax),\ + offsetof(USERCAL_tstCalibration, u16GDIValveMin),\ + offsetof(USERCAL_tstCalibration, u16GDIValveMax),\ + offsetof(USERCAL_tstCalibration, u16GDIValveFF),\ + offsetof(USERCAL_tstCalibration, aUserPedalTransferSpread),\ + offsetof(USERCAL_tstCalibration, aUserPedalTransferTable),\ + offsetof(USERCAL_tstCalibration, u16PressureControlThreshold),\ + offsetof(USERCAL_tstCalibration, u16ThrottlePressureControlCal),\ + offsetof(USERCAL_tstCalibration, u16PressureControlHyst),\ + offsetof(USERCAL_tstCalibration, u8BoostChargeMAPEnable),\ + offsetof(USERCAL_tstCalibration, u16BoostChargeTPSLimit),\ + offsetof(USERCAL_tstCalibration, u16ISCEntryRamp),\ + offsetof(USERCAL_tstCalibration, u16ISCPostStartRamp),\ + offsetof(USERCAL_tstCalibration, u32AirflowFMELimitLow),\ + offsetof(USERCAL_tstCalibration, u32AirflowFMELimitHigh),\ + offsetof(USERCAL_tstCalibration, u16TorqueReductionMaxDuration),\ + offsetof(USERCAL_tstCalibration, u16StallSaverRPMThreshold),\ + offsetof(USERCAL_tstCalibration, aUserETCScaleSpread[17]),\ + offsetof(USERCAL_tstCalibration, aUserETCScaleTable[17]),\ + offsetof(USERCAL_tstCalibration, u16TorqueReductionMaxFuelCut),\ + offsetof(USERCAL_tstCalibration, u16ShiftCountLimit),\ + offsetof(USERCAL_tstCalibration, au16BoostTarget),\ + offsetof(USERCAL_tstCalibration, u16GDIPressureMin),\ + offsetof(USERCAL_tstCalibration, u16GDIPressureMax),\ + offsetof(USERCAL_tstCalibration, u32GDIMAPMin),\ + offsetof(USERCAL_tstCalibration, u32GDIMAPMax),\ + offsetof(USERCAL_tstCalibration, u16ESTPosRateMax),\ + offsetof(USERCAL_tstCalibration, u16ESTNegRateMax),\ + offsetof(USERCAL_tstCalibration, u16PressureControlDPos),\ + offsetof(USERCAL_tstCalibration, u16PressureControlDNeg),\ + offsetof(USERCAL_tstCalibration, u16ShiftCountPressureControlLimit),\ + offsetof(USERCAL_tstCalibration, u16ShiftPressureControl),\ + offsetof(USERCAL_tstCalibration, aPWM3DSlowIOOutputResource),\ + offsetof(USERCAL_tstCalibration, aPWM3DSlowPeriod),\ + offsetof(USERCAL_tstCalibration, u16SensorHystLimitRPM),\ + offsetof(USERCAL_tstCalibration, userCalPPSCalMin),\ + offsetof(USERCAL_tstCalibration, userCalPPSCalMax),\ + offsetof(USERCAL_tstCalibration, aUserPseudoMAPxSpread),\ + offsetof(USERCAL_tstCalibration, aUserPseudoMAPySpread),\ + offsetof(USERCAL_tstCalibration, aUserPseudoMAPMap),\ + offsetof(USERCAL_tstCalibration, u8PseudoMAPEnable),\ + offsetof(USERCAL_tstCalibration, u16VSSPerRPM),\ + offsetof(USERCAL_tstCalibration, u16VSSCANCal),\ + offsetof(USERCAL_tstCalibration, u16ETCOverrideKeys),\ + offsetof(USERCAL_tstCalibration, u16ETCOverride),\ + offsetof(USERCAL_tstCalibration, u16DiagType),\ + offsetof(USERCAL_tstCalibration, u16CRC16)} + +const uint32 __attribute__((used)) au32Offsets[]=OFFSETS_DATA; +//ASAM mode=readvalue name="au32Offsets" type=uint32 offset=12209 min=0 max=65535 m=1 b=0 units="dl" format=8.0 help="Internal" +#endif + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +void USERCAL_vStart(puint32 const pu32Arg);/*CR1_1*/ +void USERCAL_vRun(puint32 const pu32Arg);/*CR1_1*/ +void USERCAL_vTerminate(puint32 const pu32Arg);/*CR1_1*/ + + +#endif // USERCAL_H + diff --git a/source/Client/USERMAIN.c b/source/Client/USERMAIN.c new file mode 100644 index 0000000..2143336 --- /dev/null +++ b/source/Client/USERMAIN.c @@ -0,0 +1,32 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: USERMAIN */ +/* DESCRIPTION: This code module provides the user application entry */ +/* point */ +/* */ +/* FILE NAME: USERMAIN.c */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include "build.h" +#include "user.h" +#include "os.h" + +/* LOCAL VARIABLE DEFINITIONS (STATIC) ****************************************/ +uint32 USER_u32Stat; + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +int usermain(void); + +#ifdef BUILD_USER +int usermain(void) +{ + (void)USER_vStart(&OS_stSVCDataStruct); + + return (int)USER_u32Stat;/*CR1_6*/ +} +#endif //BUILD_USER + diff --git a/source/Client/USERMATH.c b/source/Client/USERMATH.c new file mode 100644 index 0000000..635622e --- /dev/null +++ b/source/Client/USERMATH.c @@ -0,0 +1,224 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: User Math */ +/* DESCRIPTION: This code module provides mathematical data filtering */ +/* functions for the user application */ +/* FILE NAME: USERMATH.c */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/* */ +/* */ +/* */ +/******************************************************************************/ + +/******************************************************************************/ +/* HEADER FILES */ +/******************************************************************************/ +#include "build.h" + +#ifdef BUILD_USER + +#include "USERMATH.H" + +uint8 USERMATH_au8TimeConstantData[] = USERMATH_nTimeConstantData; +uint32 USERMATH_rau32SquareRoot[] = USERMATH_nSQRT_DATA; +uint16 USERMATH_rau16CRCData[] = CRC16_DATA; + + +/* GLOBAL FUNCTION DEFINITIONS ************************************************/ +uint8 USERMATH_u8GetFilterFromTimeConstant(uint32 u32CalcPeriodMs, uint32 u32TimeConstantMs) +{ + uint32 u32Temp; + uint8 u8FilterVal; + + switch (u32CalcPeriodMs) + { + case 1: u32Temp = 256; break; + case 2: u32Temp = 128; break; + case 4: u32Temp = 64; break; + case 8: u32Temp = 32; break; + case 16: u32Temp = 16; break; + case 32: u32Temp = 8; break; + case 64: u32Temp = 4; break; + case 128: u32Temp = 2; break; + case 256: u32Temp = 1; break; + default: u32Temp = 32; break; + } + + u32Temp *= u32TimeConstantMs; + u32Temp /= 32; + u32Temp = MIN(0x1ff, u32Temp); + + u8FilterVal = USERMATH_au8TimeConstantData[u32Temp]; + + return u8FilterVal; +} + + + +uint16 USERMATH_u16SinglePoleLowPassFilter16(uint16 u16NewVal, uint8 u8FilterWeight, puint32 pu32FilterVal) +{ + u16NewVal = (UINT16_MAX >= u16NewVal) ? u16NewVal : USHRT_MAX;/*CR1_78*/ + *pu32FilterVal = (0x100 - u8FilterWeight) * (*pu32FilterVal);/*CR1_79*/ + *pu32FilterVal /= 0x100; + *pu32FilterVal += (u8FilterWeight * u16NewVal);/*CR1_79*/ + + return (uint16)*pu32FilterVal; +} + +uint32 USERMATH_u32SinglePoleLowPassFilter32(uint32 u32NewVal, uint8 u8FilterWeight, puint32 pu32FilterVal) +{ + uint32 u32Shift1 = 0; + uint32 u32Shift2 = 0; + uint32 u32Temp; + + while (0x1000000 <= u32NewVal) + { + u32NewVal /= 2; + u32Shift1++; + } + + while (0x1000000 <= *pu32FilterVal) + { + *pu32FilterVal /= 2; + u32Shift2++; + } + + *pu32FilterVal = (0x100 - u8FilterWeight) * (*pu32FilterVal); + *pu32FilterVal /= 0x100; + *pu32FilterVal = *pu32FilterVal << u32Shift2; + + u32Temp = (u8FilterWeight * u32NewVal); + u32Temp /= 0x100; + u32Temp = u32Temp << u32Shift1; + + *pu32FilterVal += u32Temp; + + return *pu32FilterVal; +} + +uint32 USERMATH_u32DiscardAndAverage32(puint32 pu32Samples, uint32 u32SampleCount, uint32 u32DiscardCount) +{ + uint32 u32Sum = 0; + uint32 u32IDX; + uint32 u32DiscardedCount = 0; + uint32 u32PreviousWorstDelta; + uint32 u32WorstDelta; + uint32 u32WorstDeltaIndex; + uint32 u32Average = 0;/*CR1_80*/ + uint32 u32Delta; + + if (0 < u32SampleCount)/*CR1_80*/ + { + for (u32IDX = 0; u32IDX < u32SampleCount; u32IDX++) + { + u32Sum += *(pu32Samples + u32IDX); + } + + u32Average = u32Sum / u32SampleCount; + u32PreviousWorstDelta = UINT_MAX;/*CR1_81*/ + + while (u32DiscardedCount < u32DiscardCount) + { + u32WorstDelta = 0; + + for (u32IDX = 0; u32IDX < u32SampleCount; u32IDX++) + { + u32Delta = (*(pu32Samples + u32IDX) > u32Average) ? + *(pu32Samples + u32IDX) - u32Average : u32Average - *(pu32Samples + u32IDX); + + if ((u32Delta >= u32WorstDelta) && (u32Delta < u32PreviousWorstDelta)) + { + u32WorstDelta = u32Delta; + u32WorstDeltaIndex = u32IDX; + } + } + + u32Sum -= *(pu32Samples + u32WorstDeltaIndex); + u32PreviousWorstDelta = u32WorstDelta; + u32DiscardedCount++; + } + + u32Average = u32Sum / (u32SampleCount - u32DiscardCount); + } + + return u32Average; +} + +sint32 USERMATH_s32DiscardAndAverage32(psint32 ps32Samples, uint32 u32SampleCount, uint32 u32DiscardCount) +{ + sint32 s32Sum = 0; + uint32 u32IDX; + uint32 u32DiscardedCount = 0; + sint32 s32PreviousWorstDelta; + sint32 s32WorstDelta; + uint32 u32WorstDeltaIndex; + sint32 s32Average; + sint32 s32Delta; + + for (u32IDX = 0; u32IDX < u32SampleCount; u32IDX++) + { + s32Sum += *(ps32Samples + u32IDX); + } + + s32Average = s32Sum / (sint32)u32SampleCount; + s32PreviousWorstDelta = INT_MAX;/*CR1_82*/ + + while (u32DiscardedCount < u32DiscardCount) + { + s32WorstDelta = 0; + + for (u32IDX = 0; u32IDX < u32SampleCount; u32IDX++) + { + s32Delta = s32Average - *(ps32Samples + u32IDX); + + if ((ABS(s32Delta) >= s32WorstDelta) && (ABS(s32Delta) < s32PreviousWorstDelta)) + { + s32WorstDelta = ABS(s32Delta); + u32WorstDeltaIndex = u32IDX; + } + } + + s32Sum -= *(ps32Samples + u32WorstDeltaIndex); + s32PreviousWorstDelta = s32WorstDelta; + u32DiscardedCount++; + } + + s32Average = s32Sum / (sint32)(u32SampleCount - u32DiscardCount); + + return s32Average; +} + + +uint32 USERMATH_u32GetSquareRoot(uint32 u32Fraction) +{ + uint32 u32Sqrt = 0; + + if (1000 > u32Fraction) + { + u32Sqrt = USERMATH_rau32SquareRoot[u32Fraction]; + } + + return u32Sqrt; +} + + +uint16 USERMATH_U16GetCRC(uint16 CRCSeed, puint8 pu8Data, uint32 u32Len) +{ + while (u32Len--) + { + CRCSeed = (CRCSeed << 8) ^ USERMATH_rau16CRCData[((CRCSeed >> 8) ^ *pu8Data++)]; + } + + return CRCSeed; +} + +#endif //BUILD_USER + + + + + diff --git a/source/Client/USERMATH.h b/source/Client/USERMATH.h new file mode 100644 index 0000000..1833872 --- /dev/null +++ b/source/Client/USERMATH.h @@ -0,0 +1,1596 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:USER_APP */ +/* PACKAGE TITLE: User Math Header File */ +/* DESCRIPTION: This code module provides mathematical data filtering */ +/* functions for the user application */ +/* FILE NAME: USERMATH.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#ifndef USERMATH_H +#define USERMATH_H + +#include +#include +#include +#include +#include "declarations.h" +#include "sys.h" +#include "types.h" + + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define ABS(a) (((a) > 0) ? (a) : (-a)) + +#define USERMATH_nTimeConstantData \ +{\ +0x1,\ +0x1,\ +0x1,\ +0x1,\ +0x1,\ +0x1,\ +0x1,\ +0x1,\ +0xB,\ +0x1F,\ +0x32,\ +0x43,\ +0x52,\ +0x60,\ +0x6D,\ +0x7A,\ +0x82,\ +0x88,\ +0x8D,\ +0x92,\ +0x96,\ +0x9B,\ +0x9F,\ +0xA3,\ +0xA7,\ +0xAB,\ +0xAE,\ +0xB2,\ +0xB5,\ +0xB8,\ +0xBB,\ +0xBE,\ +0xC0,\ +0xC2,\ +0xC3,\ +0xC4,\ +0xC6,\ +0xC7,\ +0xC8,\ +0xC9,\ +0xCA,\ +0xCC,\ +0xCD,\ +0xCE,\ +0xCF,\ +0xD0,\ +0xD1,\ +0xD2,\ +0xD3,\ +0xD4,\ +0xD5,\ +0xD5,\ +0xD6,\ +0xD7,\ +0xD8,\ +0xD9,\ +0xDA,\ +0xDB,\ +0xDB,\ +0xDC,\ +0xDD,\ +0xDE,\ +0xDE,\ +0xDF,\ +0xE0,\ +0xE0,\ +0xE0,\ +0xE1,\ +0xE1,\ +0xE1,\ +0xE2,\ +0xE2,\ +0xE2,\ +0xE3,\ +0xE3,\ +0xE3,\ +0xE4,\ +0xE4,\ +0xE4,\ +0xE5,\ +0xE5,\ +0xE5,\ +0xE5,\ +0xE6,\ +0xE6,\ +0xE6,\ +0xE6,\ +0xE7,\ +0xE7,\ +0xE7,\ +0xE7,\ +0xE8,\ +0xE8,\ +0xE8,\ +0xE8,\ +0xE9,\ +0xE9,\ +0xE9,\ +0xE9,\ +0xEA,\ +0xEA,\ +0xEA,\ +0xEA,\ +0xEB,\ +0xEB,\ +0xEB,\ +0xEB,\ +0xEB,\ +0xEC,\ +0xEC,\ +0xEC,\ +0xEC,\ +0xED,\ +0xED,\ +0xED,\ +0xED,\ +0xED,\ +0xEE,\ +0xEE,\ +0xEE,\ +0xEE,\ +0xEE,\ +0xEE,\ +0xEF,\ +0xEF,\ +0xEF,\ +0xEF,\ +0xEF,\ +0xF0,\ +0xF0,\ +0xF0,\ +0xF0,\ +0xF0,\ +0xF0,\ +0xF0,\ +0xF0,\ +0xF0,\ +0xF0,\ +0xF0,\ +0xF0,\ +0xF1,\ +0xF1,\ +0xF1,\ +0xF1,\ +0xF1,\ +0xF1,\ +0xF1,\ +0xF1,\ +0xF1,\ +0xF1,\ +0xF1,\ +0xF1,\ +0xF2,\ +0xF2,\ +0xF2,\ +0xF2,\ +0xF2,\ +0xF2,\ +0xF2,\ +0xF2,\ +0xF2,\ +0xF2,\ +0xF2,\ +0xF2,\ +0xF2,\ +0xF2,\ +0xF3,\ +0xF3,\ +0xF3,\ +0xF3,\ +0xF3,\ +0xF3,\ +0xF3,\ +0xF3,\ +0xF3,\ +0xF3,\ +0xF3,\ +0xF3,\ +0xF3,\ +0xF3,\ +0xF3,\ +0xF4,\ +0xF4,\ +0xF4,\ +0xF4,\ +0xF4,\ +0xF4,\ +0xF4,\ +0xF4,\ +0xF4,\ +0xF4,\ +0xF4,\ +0xF4,\ +0xF4,\ +0xF4,\ +0xF4,\ +0xF4,\ +0xF5,\ +0xF5,\ +0xF5,\ +0xF5,\ +0xF5,\ +0xF5,\ +0xF5,\ +0xF5,\ +0xF5,\ +0xF5,\ +0xF5,\ +0xF5,\ +0xF5,\ +0xF5,\ +0xF5,\ +0xF5,\ +0xF5,\ +0xF5,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF6,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF7,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF8,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xF9,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFA,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFB,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFC,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFD,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +0xFE,\ +} + +#define USERMATH_nSQRT_DATA \ +{0, \ +31, \ +44, \ +54, \ +63, \ +70, \ +77, \ +83, \ +89, \ +94, \ +100, \ +104, \ +109, \ +114, \ +118, \ +122, \ +126, \ +130, \ +134, \ +137, \ +141, \ +144, \ +148, \ +151, \ +154, \ +158, \ +161, \ +164, \ +167, \ +170, \ +173, \ +176, \ +178, \ +181, \ +184, \ +187, \ +189, \ +192, \ +194, \ +197, \ +200, \ +202, \ +204, \ +207, \ +209, \ +212, \ +214, \ +216, \ +219, \ +221, \ +223, \ +225, \ +228, \ +230, \ +232, \ +234, \ +236, \ +238, \ +240, \ +242, \ +244, \ +246, \ +248, \ +250, \ +252, \ +254, \ +256, \ +258, \ +260, \ +262, \ +264, \ +266, \ +268, \ +270, \ +272, \ +273, \ +275, \ +277, \ +279, \ +281, \ +282, \ +284, \ +286, \ +288, \ +289, \ +291, \ +293, \ +294, \ +296, \ +298, \ +300, \ +301, \ +303, \ +304, \ +306, \ +308, \ +309, \ +311, \ +313, \ +314, \ +316, \ +317, \ +319, \ +320, \ +322, \ +324, \ +325, \ +327, \ +328, \ +330, \ +331, \ +333, \ +334, \ +336, \ +337, \ +339, \ +340, \ +342, \ +343, \ +344, \ +346, \ +347, \ +349, \ +350, \ +352, \ +353, \ +354, \ +356, \ +357, \ +359, \ +360, \ +361, \ +363, \ +364, \ +366, \ +367, \ +368, \ +370, \ +371, \ +372, \ +374, \ +375, \ +376, \ +378, \ +379, \ +380, \ +382, \ +383, \ +384, \ +386, \ +387, \ +388, \ +389, \ +391, \ +392, \ +393, \ +394, \ +396, \ +397, \ +398, \ +400, \ +401, \ +402, \ +403, \ +404, \ +406, \ +407, \ +408, \ +409, \ +411, \ +412, \ +413, \ +414, \ +415, \ +417, \ +418, \ +419, \ +420, \ +421, \ +423, \ +424, \ +425, \ +426, \ +427, \ +428, \ +430, \ +431, \ +432, \ +433, \ +434, \ +435, \ +437, \ +438, \ +439, \ +440, \ +441, \ +442, \ +443, \ +444, \ +446, \ +447, \ +448, \ +449, \ +450, \ +451, \ +452, \ +453, \ +454, \ +456, \ +457, \ +458, \ +459, \ +460, \ +461, \ +462, \ +463, \ +464, \ +465, \ +466, \ +467, \ +469, \ +470, \ +471, \ +472, \ +473, \ +474, \ +475, \ +476, \ +477, \ +478, \ +479, \ +480, \ +481, \ +482, \ +483, \ +484, \ +485, \ +486, \ +487, \ +488, \ +489, \ +490, \ +491, \ +492, \ +493, \ +494, \ +495, \ +496, \ +497, \ +498, \ +500, \ +500, \ +501, \ +502, \ +503, \ +504, \ +505, \ +506, \ +507, \ +508, \ +509, \ +510, \ +511, \ +512, \ +513, \ +514, \ +515, \ +516, \ +517, \ +518, \ +519, \ +520, \ +521, \ +522, \ +523, \ +524, \ +525, \ +526, \ +527, \ +528, \ +529, \ +530, \ +531, \ +531, \ +532, \ +533, \ +534, \ +535, \ +536, \ +537, \ +538, \ +539, \ +540, \ +541, \ +542, \ +543, \ +544, \ +544, \ +545, \ +546, \ +547, \ +548, \ +549, \ +550, \ +551, \ +552, \ +553, \ +554, \ +554, \ +555, \ +556, \ +557, \ +558, \ +559, \ +560, \ +561, \ +562, \ +563, \ +563, \ +564, \ +565, \ +566, \ +567, \ +568, \ +569, \ +570, \ +570, \ +571, \ +572, \ +573, \ +574, \ +575, \ +576, \ +577, \ +577, \ +578, \ +579, \ +580, \ +581, \ +582, \ +583, \ +583, \ +584, \ +585, \ +586, \ +587, \ +588, \ +589, \ +589, \ +590, \ +591, \ +592, \ +593, \ +594, \ +594, \ +595, \ +596, \ +597, \ +598, \ +599, \ +600, \ +600, \ +601, \ +602, \ +603, \ +604, \ +604, \ +605, \ +606, \ +607, \ +608, \ +609, \ +609, \ +610, \ +611, \ +612, \ +613, \ +614, \ +614, \ +615, \ +616, \ +617, \ +618, \ +618, \ +619, \ +620, \ +621, \ +622, \ +622, \ +623, \ +624, \ +625, \ +626, \ +626, \ +627, \ +628, \ +629, \ +630, \ +630, \ +631, \ +632, \ +633, \ +634, \ +634, \ +635, \ +636, \ +637, \ +637, \ +638, \ +639, \ +640, \ +641, \ +641, \ +642, \ +643, \ +644, \ +644, \ +645, \ +646, \ +647, \ +648, \ +648, \ +649, \ +650, \ +651, \ +651, \ +652, \ +653, \ +654, \ +654, \ +655, \ +656, \ +657, \ +658, \ +658, \ +659, \ +660, \ +661, \ +661, \ +662, \ +663, \ +664, \ +664, \ +665, \ +666, \ +667, \ +667, \ +668, \ +669, \ +670, \ +670, \ +671, \ +672, \ +673, \ +673, \ +674, \ +675, \ +676, \ +676, \ +677, \ +678, \ +678, \ +679, \ +680, \ +681, \ +681, \ +682, \ +683, \ +684, \ +684, \ +685, \ +686, \ +687, \ +687, \ +688, \ +689, \ +689, \ +690, \ +691, \ +692, \ +692, \ +693, \ +694, \ +694, \ +695, \ +696, \ +697, \ +697, \ +698, \ +699, \ +700, \ +700, \ +701, \ +702, \ +702, \ +703, \ +704, \ +704, \ +705, \ +706, \ +707, \ +707, \ +708, \ +709, \ +709, \ +710, \ +711, \ +712, \ +712, \ +713, \ +714, \ +714, \ +715, \ +716, \ +716, \ +717, \ +718, \ +719, \ +719, \ +720, \ +721, \ +721, \ +722, \ +723, \ +723, \ +724, \ +725, \ +725, \ +726, \ +727, \ +728, \ +728, \ +729, \ +730, \ +730, \ +731, \ +732, \ +732, \ +733, \ +734, \ +734, \ +735, \ +736, \ +736, \ +737, \ +738, \ +738, \ +739, \ +740, \ +740, \ +741, \ +742, \ +742, \ +743, \ +744, \ +744, \ +745, \ +746, \ +746, \ +747, \ +748, \ +748, \ +749, \ +750, \ +750, \ +751, \ +752, \ +752, \ +753, \ +754, \ +754, \ +755, \ +756, \ +756, \ +757, \ +758, \ +758, \ +759, \ +760, \ +760, \ +761, \ +762, \ +762, \ +763, \ +764, \ +764, \ +765, \ +766, \ +766, \ +767, \ +768, \ +768, \ +769, \ +770, \ +770, \ +771, \ +772, \ +772, \ +773, \ +773, \ +774, \ +775, \ +775, \ +776, \ +777, \ +777, \ +778, \ +779, \ +779, \ +780, \ +781, \ +781, \ +782, \ +782, \ +783, \ +784, \ +784, \ +785, \ +786, \ +786, \ +787, \ +788, \ +788, \ +789, \ +789, \ +790, \ +791, \ +791, \ +792, \ +793, \ +793, \ +794, \ +794, \ +795, \ +796, \ +796, \ +797, \ +798, \ +798, \ +799, \ +800, \ +800, \ +801, \ +801, \ +802, \ +803, \ +803, \ +804, \ +804, \ +805, \ +806, \ +806, \ +807, \ +808, \ +808, \ +809, \ +809, \ +810, \ +811, \ +811, \ +812, \ +813, \ +813, \ +814, \ +814, \ +815, \ +816, \ +816, \ +817, \ +817, \ +818, \ +819, \ +819, \ +820, \ +820, \ +821, \ +822, \ +822, \ +823, \ +824, \ +824, \ +825, \ +825, \ +826, \ +827, \ +827, \ +828, \ +828, \ +829, \ +830, \ +830, \ +831, \ +831, \ +832, \ +833, \ +833, \ +834, \ +834, \ +835, \ +836, \ +836, \ +837, \ +837, \ +838, \ +839, \ +839, \ +840, \ +840, \ +841, \ +842, \ +842, \ +843, \ +843, \ +844, \ +844, \ +845, \ +846, \ +846, \ +847, \ +847, \ +848, \ +849, \ +849, \ +850, \ +850, \ +851, \ +852, \ +852, \ +853, \ +853, \ +854, \ +854, \ +855, \ +856, \ +856, \ +857, \ +857, \ +858, \ +859, \ +859, \ +860, \ +860, \ +861, \ +861, \ +862, \ +863, \ +863, \ +864, \ +864, \ +865, \ +866, \ +866, \ +867, \ +867, \ +868, \ +868, \ +869, \ +870, \ +870, \ +871, \ +871, \ +872, \ +872, \ +873, \ +874, \ +874, \ +875, \ +875, \ +876, \ +876, \ +877, \ +878, \ +878, \ +879, \ +879, \ +880, \ +880, \ +881, \ +882, \ +882, \ +883, \ +883, \ +884, \ +884, \ +885, \ +886, \ +886, \ +887, \ +887, \ +888, \ +888, \ +889, \ +889, \ +890, \ +891, \ +891, \ +892, \ +892, \ +893, \ +893, \ +894, \ +894, \ +895, \ +896, \ +896, \ +897, \ +897, \ +898, \ +898, \ +899, \ +900, \ +900, \ +901, \ +901, \ +902, \ +902, \ +903, \ +903, \ +904, \ +904, \ +905, \ +906, \ +906, \ +907, \ +907, \ +908, \ +908, \ +909, \ +909, \ +910, \ +911, \ +911, \ +912, \ +912, \ +913, \ +913, \ +914, \ +914, \ +915, \ +915, \ +916, \ +917, \ +917, \ +918, \ +918, \ +919, \ +919, \ +920, \ +920, \ +921, \ +921, \ +922, \ +923, \ +923, \ +924, \ +924, \ +925, \ +925, \ +926, \ +926, \ +927, \ +927, \ +928, \ +928, \ +929, \ +930, \ +930, \ +931, \ +931, \ +932, \ +932, \ +933, \ +933, \ +934, \ +934, \ +935, \ +935, \ +936, \ +937, \ +937, \ +938, \ +938, \ +939, \ +939, \ +940, \ +940, \ +941, \ +941, \ +942, \ +942, \ +943, \ +943, \ +944, \ +944, \ +945, \ +946, \ +946, \ +947, \ +947, \ +948, \ +948, \ +949, \ +949, \ +950, \ +950, \ +951, \ +951, \ +952, \ +952, \ +953, \ +953, \ +954, \ +954, \ +955, \ +956, \ +956, \ +957, \ +957, \ +958, \ +958, \ +959, \ +959, \ +960, \ +960, \ +961, \ +961, \ +962, \ +962, \ +963, \ +963, \ +964, \ +964, \ +965, \ +965, \ +966, \ +966, \ +967, \ +967, \ +968, \ +969, \ +969, \ +970, \ +970, \ +971, \ +971, \ +972, \ +972, \ +973, \ +973, \ +974, \ +974, \ +975, \ +975, \ +976, \ +976, \ +977, \ +977, \ +978, \ +978, \ +979, \ +979, \ +980, \ +980, \ +981, \ +981, \ +982, \ +982, \ +983, \ +983, \ +984, \ +984, \ +985, \ +985, \ +986, \ +986, \ +987, \ +987, \ +988, \ +988, \ +989, \ +989, \ +990, \ +990, \ +991, \ +991, \ +992, \ +992, \ +993, \ +993, \ +994, \ +994, \ +995, \ +995, \ +996, \ +996, \ +997, \ +997, \ +998, \ +998, \ +999} + +#define CRC16_DATA \ +{\ + 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,\ + 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,\ + 0x0919, 0x1890, 0x2A0B, 0x3B82, 0x4F3D, 0x5EB4, 0x6C2F, 0x7DA6,\ + 0x8551, 0x94D8, 0xA643, 0xB7CA, 0xC375, 0xD2FC, 0xE067, 0xF1EE,\ + 0x1232, 0x03BB, 0x3120, 0x20A9, 0x5416, 0x459F, 0x7704, 0x668D,\ + 0x9E7A, 0x8FF3, 0xBD68, 0xACE1, 0xD85E, 0xC9D7, 0xFB4C, 0xEAC5,\ + 0x1B2B, 0x0AA2, 0x3839, 0x29B0, 0x5D0F, 0x4C86, 0x7E1D, 0x6F94,\ + 0x9763, 0x86EA, 0xB471, 0xA5F8, 0xD147, 0xC0CE, 0xF255, 0xE3DC,\ + 0x2464, 0x35ED, 0x0776, 0x16FF, 0x6240, 0x73C9, 0x4152, 0x50DB,\ + 0xA82C, 0xB9A5, 0x8B3E, 0x9AB7, 0xEE08, 0xFF81, 0xCD1A, 0xDC93,\ + 0x2D7D, 0x3CF4, 0x0E6F, 0x1FE6, 0x6B59, 0x7AD0, 0x484B, 0x59C2,\ + 0xA135, 0xB0BC, 0x8227, 0x93AE, 0xE711, 0xF698, 0xC403, 0xD58A,\ + 0x3656, 0x27DF, 0x1544, 0x04CD, 0x7072, 0x61FB, 0x5360, 0x42E9,\ + 0xBA1E, 0xAB97, 0x990C, 0x8885, 0xFC3A, 0xEDB3, 0xDF28, 0xCEA1,\ + 0x3F4F, 0x2EC6, 0x1C5D, 0x0DD4, 0x796B, 0x68E2, 0x5A79, 0x4BF0,\ + 0xB307, 0xA28E, 0x9015, 0x819C, 0xF523, 0xE4AA, 0xD631, 0xC7B8,\ + 0x48C8, 0x5941, 0x6BDA, 0x7A53, 0x0EEC, 0x1F65, 0x2DFE, 0x3C77,\ + 0xC480, 0xD509, 0xE792, 0xF61B, 0x82A4, 0x932D, 0xA1B6, 0xB03F,\ + 0x41D1, 0x5058, 0x62C3, 0x734A, 0x07F5, 0x167C, 0x24E7, 0x356E,\ + 0xCD99, 0xDC10, 0xEE8B, 0xFF02, 0x8BBD, 0x9A34, 0xA8AF, 0xB926,\ + 0x5AFA, 0x4B73, 0x79E8, 0x6861, 0x1CDE, 0x0D57, 0x3FCC, 0x2E45,\ + 0xD6B2, 0xC73B, 0xF5A0, 0xE429, 0x9096, 0x811F, 0xB384, 0xA20D,\ + 0x53E3, 0x426A, 0x70F1, 0x6178, 0x15C7, 0x044E, 0x36D5, 0x275C,\ + 0xDFAB, 0xCE22, 0xFCB9, 0xED30, 0x998F, 0x8806, 0xBA9D, 0xAB14,\ + 0x6CAC, 0x7D25, 0x4FBE, 0x5E37, 0x2A88, 0x3B01, 0x099A, 0x1813,\ + 0xE0E4, 0xF16D, 0xC3F6, 0xD27F, 0xA6C0, 0xB749, 0x85D2, 0x945B,\ + 0x65B5, 0x743C, 0x46A7, 0x572E, 0x2391, 0x3218, 0x0083, 0x110A,\ + 0xE9FD, 0xF874, 0xCAEF, 0xDB66, 0xAFD9, 0xBE50, 0x8CCB, 0x9D42,\ + 0x7E9E, 0x6F17, 0x5D8C, 0x4C05, 0x38BA, 0x2933, 0x1BA8, 0x0A21,\ + 0xF2D6, 0xE35F, 0xD1C4, 0xC04D, 0xB4F2, 0xA57B, 0x97E0, 0x8669,\ + 0x7787, 0x660E, 0x5495, 0x451C, 0x31A3, 0x202A, 0x12B1, 0x0338,\ + 0xFBCF, 0xEA46, 0xD8DD, 0xC954, 0xBDEB, 0xAC62, 0x9EF9, 0x8F70\ +} + + +/* GLOBAL FUNCTION DECLARATIONS ***********************************************/ +uint8 USERMATH_u8GetFilterFromTimeConstant(uint32, uint32); +uint16 USERMATH_u16SinglePoleLowPassFilter16(uint16 u16NewVal, uint8 u8FilterWeight, puint32 pu32FilterVal);/*CR1_1*/ +uint32 USERMATH_u32SinglePoleLowPassFilter32(uint32 u32NewVal, uint8 u8FilterWeight, puint32 pu32FilterVal);/*CR1_1*/ +uint32 USERMATH_u32DiscardAndAverage32(puint32 pu32Samples, uint32 u32SampleCount, uint32 u32DiscardCount);/*CR1_1*/ +sint32 USERMATH_s32DiscardAndAverage32(psint32 ps32Samples, uint32 u32SampleCount, uint32 u32DiscardCount);/*CR1_1*/ +uint32 USERMATH_u32GetSquareRoot(uint32 u32Fraction); +uint16 USERMATH_U16GetCRC(uint16 CRCSeed, puint8 pu8Data, uint32 u32Len); + +#endif // UNITS_H + diff --git a/source/Client/golf_mk6.h b/source/Client/golf_mk6.h new file mode 100644 index 0000000..d53824b --- /dev/null +++ b/source/Client/golf_mk6.h @@ -0,0 +1,2210 @@ +#define USERCAL_nROMCAL {\ +/* userCalADRefH */\ + 3290u,\ +/* userCalVRef445 */\ + 4530u,\ +/* userCalVNernstTarget */\ + 4450u,\ +/* userCalRNernstReady */\ + 300000u,\ +/* userCalRHeaterThreshold */\ + 6500u,\ +/* au32UserCalPumpCurrentPFactor */\ + {9300u},\ +/* au32UserCalPumpCurrentMFactor */\ + {9300u},\ +/* ai32UserCalPumpCurrentOffset */\ + {2u},\ +/* aUserCalPumpSpread */\ + {-1850000u,\ + -1465000u,\ + -1080000u,\ + -920000u,\ + -760000u,\ + -615000u,\ + -470000u,\ + -235000u,\ + 0,\ + 170000u,\ + 340000u,\ + 510000u,\ + 680000u,\ + 815000u,\ + 950000u,\ + 1400000u,\ + 2550000u},\ +/* aUserCalPumpLambda */\ + {700u,\ + 750u,\ + 800u,\ + 825,\ + 850u,\ + 875u,\ + 900u,\ + 955u,\ + 1000u,\ + 1094u,\ + 1180u,\ + 1305u,\ + 1430u,\ + 1565u,\ + 1700u,\ + 2350u,\ + 4160u},\ +/* au8UserCalPumpSensorTrim */\ + {74u},\ +/* aUserStoichFuelCal */\ + 1470u,\ +/* au8UserCalPumpDeadband */\ + {2u},\ +/* au16UserCalFreeAirPoints */\ + {3310u,\ + 3320u,\ + 3330u,\ + 3340u,\ + 3350u,\ + 3360u,\ + 3370u,\ + 3380u,\ + 3390u,\ + 3400u,\ + 3410u,\ + 3420u,\ + 3430u,\ + 3440u,\ + 3450u,\ + 3460u,\ + 3470u,\ + 3480u,\ + 3490u},\ +/* aUserHeaterAlarmCurrent */\ + {2600u},\ +/* u8WarmUpDelay */\ + 10u,\ +/* u8DisplayMode */\ + 1u,\ +/* u8BackLightEnable */\ + 1u,\ +/* userCalTPSCalMin */\ + 500u,\ +/* userCalTPSCalMax */\ + 4500u,\ +/* aUserCURVEAfmTFSpread */\ + {500u,\ + 1000u,\ + 1500u,\ + 2000u,\ + 2500u,\ + 3000u,\ + 3500u,\ + 4000u,\ + 4500u,\ + 5000u,\ + 5500u,\ + 6000u,\ + 7000u,\ + 8000u,\ + 9000u,\ + 10000u,\ + 11000u},\ +/* aUserCURVEAfmTFTable */\ + {0,\ + 720000,\ + 1400000,\ + 1900000,\ + 3100000,\ + 6000000,\ + 9600000,\ + 14000000,\ + 19000000,\ + 28000000,\ + 38000000,\ + 52000000,\ + 73000000,\ + 102000000,\ + 143000000,\ + 200000000,\ + 280000000},\ +/* aUserInjResponseSpread */\ + {7500u,\ + 8000u,\ + 8500u,\ + 9000u,\ + 9500u,\ + 10000u,\ + 10500u,\ + 11000u,\ + 11500u,\ + 12000u,\ + 12500u,\ + 13000u,\ + 13500u,\ + 14000u,\ + 14500u,\ + 15000u,\ + 15500u},\ +/* aUserInjResponseTable */\ + {215u,\ + 210u,\ + 205u,\ + 200u,\ + 195u,\ + 190u,\ + 185u,\ + 180u,\ + 175u,\ + 170u,\ + 165u,\ + 160u,\ + 160u,\ + 160u,\ + 160u,\ + 160u,\ + 160u},\ +/* aUserCoolantSensorSpread */\ + {500u,\ + 750u,\ + 1000u,\ + 1250u,\ + 1500u,\ + 1750u,\ + 2000u,\ + 2250u,\ + 2500u,\ + 2750u,\ + 3000u,\ + 3250u,\ + 3500u,\ + 3750u,\ + 4000u,\ + 4250u,\ + 4500u},\ +/* aUserCoolantSensorTable */\ + {500000,\ + 200000,\ + 122000,\ + 112000,\ + 105000,\ + 100000,\ + 95000,\ + 87000,\ + 79000,\ + 71000,\ + 60000,\ + 40000,\ + 30000,\ + 20000,\ + 15000,\ + 10000,\ + -20000},\ +/* aUserCoolantEnrichmentSpread */\ + {-40000,\ + -30000,\ + -20000,\ + -10000,\ + 0,\ + 10000,\ + 20000,\ + 30000,\ + 40000,\ + 50000,\ + 60000,\ + 70000,\ + 80000,\ + 90000,\ + 100000,\ + 110000,\ + 120000},\ +/* aUserCoolantEnrichmentTable */\ + {1600u,\ + 1500u,\ + 1400u,\ + 1300u,\ + 1200u,\ + 1160u,\ + 1120u,\ + 1080u,\ + 1040u,\ + 1020u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u},\ +/* aUserTAFRxSpread */\ + {0u,\ + 500u,\ + 1000u,\ + 1500u,\ + 2000u,\ + 2500u,\ + 3000u,\ + 3500u,\ + 4000u,\ + 4500u,\ + 5000u,\ + 5500u,\ + 6000u,\ + 6500u,\ + 7000u,\ + 7500u,\ + 8000u},\ +/* aUserTAFRySpread */\ +{20000u,\ + 30000u,\ + 40000u,\ + 50000u,\ + 60000u,\ + 70000u,\ + 80000u,\ + 90000u,\ + 100000u,\ + 115000u,\ + 130000u,\ + 145000u,\ + 160000u,\ + 175000u,\ + 190000u,\ + 205000u,\ + 220000u},\ + /* aUserMAPTAFR */\ + {{1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100,1100},\ + {1470,1470,1450,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1470,1400},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1290,1290,1290,1190,1190,1190},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1290,1290,1290,1290,1290,1290},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1290,1290,1290,1290,1290,1290},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1290,1290,1290,1290,1290,1290},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1290,1290,1290,1290,1290,1290},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1290,1290,1290,1290,1290,1290},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1290,1290,1290,1290,1290,1290},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1290,1290,1290,1290,1290,1290},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1290,1290,1290,1290,1290,1290},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1260,1190,1190,1190,1190,1190,1190},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1260,1190,1190,1190,1190,1190,1190},\ + {1470,1470,1470,1470,1470,1470,1470,1470,1400,1330,1260,1190,1190,1190,1190,1190,1190},\ + {1900,1470,1470,1470,1470,1470,1470,1470,1400,1330,1260,1190,1190,1190,1190,1190,1190},\ + {1900,1470,1470,1470,1470,1470,1470,1470,1400,1330,1260,1190,1190,1190,1190,1190,1190},\ + {1900,1470,1470,1470,1470,1470,1470,1470,1400,1330,1260,1190,1190,1190,1190,1190,1190}},\ +/* aUserTimingxSpread */\ + {0u,\ + 500u,\ + 1000u,\ + 1500u,\ + 2000u,\ + 2500u,\ + 3000u,\ + 3500u,\ + 4000u,\ + 4500u,\ + 5000u,\ + 5500u,\ + 6000u,\ + 6500u,\ + 7000u,\ + 7500u,\ + 8000u},\ +/* aUserTimingySpread */\ +{20000u,\ + 30000u,\ + 40000u,\ + 50000u,\ + 60000u,\ + 70000u,\ + 80000u,\ + 90000u,\ + 100000u,\ + 115000u,\ + 130000u,\ + 145000u,\ + 160000u,\ + 175000u,\ + 190000u,\ + 205000u,\ + 220000u},\ +/* aUserTimingMap */\ + {{130,130,130,130,120,60,0,0,0,0,0,0,0,0,0,0,0},\ + {180,180,180,180,170,160,150,140,130,120,110,100,90,80,70,70,70},\ + {120,120,120,120,120,120,110,120,120,120,90,80,80,80,80,80,80},\ + {140,150,160,170,160,150,140,130,120,120,120,120,120,120,120,120,120},\ + {260,280,300,300,290,280,270,260,250,240,220,170,160,130,120,120,120},\ + {280,340,360,390,390,390,360,340,330,300,260,220,180,140,100,90,90},\ + {280,340,360,390,390,390,360,340,330,300,260,220,180,140,100,90,90},\ + {280,340,360,390,390,390,360,340,330,300,260,220,180,140,100,90,90},\ + {280,340,360,390,390,390,360,340,330,300,260,220,180,140,100,90,90},\ + {280,340,360,390,390,390,360,340,330,300,260,220,180,140,100,90,90},\ + {280,340,360,390,390,390,360,340,330,300,260,220,180,140,100,90,90},\ + {280,340,360,390,390,390,360,340,330,300,260,220,180,140,100,90,90},\ + {280,240,360,330,280,260,250,230,230,230,220,170,140,100,90,110,130},\ + {220,260,360,360,340,320,280,270,260,250,220,170,150,110,110,130,150},\ + {140,260,360,360,340,320,280,270,260,250,220,200,150,120,120,160,160},\ + {140,260,360,360,340,320,280,270,260,250,250,220,200,130,120,160,170},\ + {90,90,90,90,90,90,90,90,90,90,90,80,80,80,80,80,80}},\ +/* aUserVExSpread */\ + {0u,\ + 500u,\ + 1000u,\ + 1500u,\ + 2000u,\ + 2500u,\ + 3000u,\ + 3500u,\ + 4000u,\ + 4500u,\ + 5000u,\ + 5500u,\ + 6000u,\ + 6500u,\ + 7000u,\ + 7500u,\ + 8000u},\ +/* aUserVEySpread */\ +{20000u,\ + 30000u,\ + 40000u,\ + 50000u,\ + 60000u,\ + 70000u,\ + 80000u,\ + 90000u,\ + 100000u,\ + 115000u,\ + 130000u,\ + 145000u,\ + 160000u,\ + 175000u,\ + 190000u,\ + 205000u,\ + 220000u},\ +/* aUserMAPVE */\ + {{600,600,600,600,600,600,600,700,800,800,800,800,800,800,800,800,800},\ + {550,570,590,610,630,650,700,700,700,700,700,700,700,700,700,700,700},\ + {580,610,630,650,670,690,700,700,700,700,700,650,650,650,650,650,650},\ + {610,630,650,670,690,700,700,700,670,670,670,670,670,670,670,670,670},\ + {640,660,680,690,700,710,710,710,710,710,710,710,710,720,720,720,720},\ + {670,680,690,700,710,720,720,720,720,720,720,720,720,720,720,720,720},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {680,690,700,710,720,730,730,730,730,730,730,730,730,730,730,730,730},\ + {600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600}},\ +/* aUserCoolantStartEnrichmentSpread */\ + {-40000,\ + -30000,\ + -20000,\ + -10000,\ + 0,\ + 10000,\ + 20000,\ + 30000,\ + 40000,\ + 50000,\ + 60000,\ + 70000,\ + 80000,\ + 90000,\ + 100000,\ + 110000,\ + 120000},\ +/* aUserCoolantStartEnrichmentTable */\ + {1700u,\ + 1600u,\ + 1500u,\ + 1450u,\ + 1400u,\ + 1350u,\ + 1300u,\ + 1250u,\ + 1200u,\ + 1150u,\ + 1100u,\ + 1050u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u},\ +/* aUserCoolantPostStartEnrichmentSpread */\ + {-40000,\ + -30000,\ + -20000,\ + -10000,\ + 0,\ + 10000,\ + 20000,\ + 30000,\ + 40000,\ + 50000,\ + 60000,\ + 70000,\ + 80000,\ + 90000,\ + 100000,\ + 110000,\ + 120000},\ +/* aUserCoolantPostStartEnrichmentTable */\ + {1200u,\ + 1160u,\ + 1140u,\ + 1120u,\ + 1100u,\ + 1090u,\ + 1080u,\ + 1070u,\ + 1060u,\ + 1050u,\ + 1050u,\ + 1050u,\ + 1050u,\ + 1050u,\ + 1050u,\ + 1050u,\ + 1050u},\ +/* aUserCrankingAirflowSpread */\ + {150u,\ + 160u,\ + 170u,\ + 180u,\ + 190u,\ + 200u,\ + 210u,\ + 220u,\ + 230u,\ + 240u,\ + 250u,\ + 260u,\ + 270u,\ + 280u,\ + 290u,\ + 300u,\ + 400u},\ +/* aUserCrankingAirflowTable */\ + {3400u,\ + 3500u,\ + 3600u,\ + 3700u,\ + 3800u,\ + 3900u,\ + 4000u,\ + 4100u,\ + 4200u,\ + 4300u,\ + 4400u,\ + 4500u,\ + 4600u,\ + 4700u,\ + 4800u,\ + 4900u,\ + 5000u},\ +/* aUserDwellSpread */\ + {7500u,\ + 8000u,\ + 8500u,\ + 9000u,\ + 9500u,\ + 10000u,\ + 10500u,\ + 11000u,\ + 11500u,\ + 12000u,\ + 12500u,\ + 13000u,\ + 13500u,\ + 14000u,\ + 14500u,\ + 15000u,\ + 15500u},\ +/* aUserDwellTable */\ + {7600u,\ + 7200u,\ + 6800u,\ + 6400u,\ + 6000u,\ + 5600u,\ + 5200u,\ + 4800u,\ + 4400u,\ + 4000u,\ + 3600u,\ + 3400u,\ + 3200u,\ + 3000u,\ + 3000u,\ + 3000u,\ + 3000u},\ +/* aUserAirTempCorrectionSpread */\ + {-40000,\ + -30000,\ + -20000,\ + -10000,\ + 0,\ + 10000,\ + 20000,\ + 30000,\ + 40000,\ + 50000,\ + 60000,\ + 70000,\ + 80000,\ + 90000,\ + 100000,\ + 110000,\ + 120000},\ +/* aUserAirTempCorrectionTable */\ + {1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u},\ +/* aUserTPSMovementCorrectionSpread */\ + {0x7ffc0000,\ + 0x7ffc8000,\ + 0x7ffd0000,\ + 0x7ffd8000,\ + 0x7ffe0000,\ + 0x7ffe8000,\ + 0x7fff0000,\ + 0x7fff8000,\ + 0x80008000,\ + 0x80010000,\ + 0x80018000,\ + 0x80020000,\ + 0x80028000,\ + 0x80030000,\ + 0x80038000,\ + 0x80040000,\ + 0x80048000},\ +/* aUserTPSMovementCorrectionTable */\ + {1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u},\ +/* aUserInjectionPhasingSpread */\ + {0u,\ + 500u,\ + 1000u,\ + 1500u,\ + 2000u,\ + 2500u,\ + 3000u,\ + 3500u,\ + 4000u,\ + 4500u,\ + 5000u,\ + 6500u,\ + 7000u,\ + 7500u,\ + 8000u,\ + 8500u,\ + 9000u},\ +/* aUserInjectionPhasingTable */\ +{0u,\ + 100u,\ + 200u,\ + 300u,\ + 400u,\ + 500u,\ + 600u,\ + 700u,\ + 800u,\ + 900u,\ + 1000u,\ + 1100u,\ + 1200u,\ + 1300u,\ + 1400u,\ + 1500u,\ + 1600u},\ +/* aUserCTSTimingCorrectionSpread */\ + {-40000,\ + -30000,\ + -20000,\ + -10000,\ + 0,\ + 10000,\ + 20000,\ + 30000,\ + 40000,\ + 50000,\ + 60000,\ + 70000,\ + 80000,\ + 90000,\ + 100000,\ + 110000,\ + 120000},\ +/* aUserCTSTimingCorrectionTable */\ + {31u,\ + 25u,\ + 22u,\ + 18u,\ + 15u,\ + 14u,\ + 13u,\ + 12u,\ + 11u,\ + 10u,\ + 10u,\ + 10u,\ + 10u,\ + 10u,\ + 10u,\ + 10u,\ + 10u},\ +/* aUserATSTimingCorrectionSpread */\ +{-40000,\ + -30000,\ + -20000,\ + -10000,\ + 0,\ + 10000,\ + 20000,\ + 30000,\ + 40000,\ + 50000,\ + 60000,\ + 70000,\ + 80000,\ + 90000,\ + 100000,\ + 110000,\ + 120000},\ +/* aUserATSTimingCorrectionTable */\ + {31u,\ + 25u,\ + 22u,\ + 18u,\ + 15u,\ + 14u,\ + 13u,\ + 12u,\ + 11u,\ + 10u,\ + 10u,\ + 10u,\ + 10u,\ + 10u,\ + 10u,\ + 10u,\ + 10u},\ +/* aUserISCSpeedTargetSpread */\ +{-40000,\ + -30000,\ + -20000,\ + -10000,\ + 0,\ + 10000,\ + 20000,\ + 30000,\ + 40000,\ + 50000,\ + 60000,\ + 70000,\ + 80000,\ + 90000,\ + 100000,\ + 110000,\ + 120000},\ +/* aUserISCSpeedTargetTable */\ +{ 1200u,\ + 1100u,\ + 1000u,\ + 980u,\ + 960u,\ + 920u,\ + 880u,\ + 840u,\ + 800u,\ + 760u,\ + 720u,\ + 720u,\ + 720u,\ + 720u,\ + 720u,\ + 720u,\ + 720u},\ +/* aUserStepperCloseTable */\ +{5,\ + 9,\ + 10,\ + 6},\ +/* aUserStepperOpenTable */\ +{6,\ + 10,\ + 9,\ + 5},\ +/* u32UserStepperHomeSteps */\ +24,\ +/* aUserPrimaryTriggerTable */\ +{0x0,\ + 0x444,\ + 0x888,\ + 0xCCC,\ + 0x1110,\ + 0x1555,\ + 0x1999,\ + 0x1DDD,\ + 0x2222,\ + 0x2666,\ + 0x2AAA,\ + 0x2EEE,\ + 0x3333,\ + 0x3777,\ + 0x3BBB,\ + 0x4000,\ + 0x4444,\ + 0x4888,\ + 0x4CCC,\ + 0x5111,\ + 0x5555,\ + 0x5999,\ + 0x5DDD,\ + 0x6222,\ + 0x6666,\ + 0x6AAA,\ + 0x6EEE,\ + 0x7333,\ + 0x7777,\ + 0x7BBB,\ + 0x8000,\ + 0x8444,\ + 0x8888,\ + 0x8CCC,\ + 0x9111,\ + 0x9555,\ + 0x9999,\ + 0x9DDD,\ + 0xA222,\ + 0xA666,\ + 0xAAAA,\ + 0xAEEE,\ + 0xBBBC,\ + 0xC000,\ + 0xC444,\ + 0xC888,\ + 0xCCCC,\ + 0xD111,\ + 0xD555,\ + 0xD999,\ + 0xDDDD,\ + 0xE222,\ + 0xE666,\ + 0xEAAA,\ + 0xEEEE,\ + 0xF333,\ + 0xF777,\ + 0xFBBB,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0x0000,\ + 0},\ +/* aUserSecondaryTriggerTable */\ +{0x0,\ + 0x444,\ + 0x888,\ + 0xCCC,\ + 0x1111,\ + 0x1555,\ + 0x1999,\ + 0x1DDD,\ + 0x2AAA,\ + 0x2EEE,\ + 0x3333,\ + 0x3777,\ + 0x3BBB,\ + 0x4000,\ + 0x4444,\ + 0x4888,\ + 0x4CCC,\ + 0x5111,\ + 0x5555,\ + 0x5999,\ + 0x5DDD,\ + 0x6222,\ + 0x6666,\ + 0x6AAA,\ + 0x6EEE,\ + 0x7333,\ + 0x7777,\ + 0x7BBB,\ + 0x8000,\ + 0x8444,\ + 0x8888,\ + 0x8CCC,\ + 0x9111,\ + 0x9555,\ + 0x9999,\ + 0x9DDD,\ + 0xA222,\ + 0xA666,\ + 0xAAAA,\ + 0xAEEE},\ +{ 0x0, 0x4000, 0x8000, 0xc000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},\ +/* u8UserPrimaryEdgeSetup */\ +0x1,\ +/* u8UserSecondaryEdgeSetup */\ +0x1,\ +/* u8UserPrimaryVREnable */\ +1,\ +/* u8UserSecondaryVREnable */\ +0,\ +/* u8UserFirstEdgeRisingPrimary */\ +0,\ +/* u8UserFirstEdgeRisingSecondary */\ +0,\ +/* au32InjectionSequence */\ +{0x0000, 0x0000, 0x0400, 0x0602},\ +/* au32IgnitionSequence */\ +{0xff00, 0xff02, 0xff04, 0xff06},\ +/* enSimpleCamSyncSource */\ +EH_IO_Invalid,\ +/* boCamSyncHighLate */\ +1,\ +/* u32CamSyncSampleToothCount */\ +15,\ +/* u16ManifoldVolumeCC */\ +2000,\ +/* u8CylCount */\ +4,\ +/* u16InjFlowRate */\ +13000,\ +/* aUserBackupAirflowxSpread */\ +{0,\ +500,\ +1000,\ +1500,\ +2000,\ +2500,\ +3000,\ +3500,\ +4000,\ +4500,\ +5000},\ +/* aUserBackupAirflowySpread */\ +{0x0,\ + 0xB32,\ + 0x1664,\ + 0x2196,\ + 0x2CC8,\ + 0x37FB,\ + 0x432D,\ + 0x5991,\ + 0x865A,\ + 0xDFEC,\ + 0x15F90},\ +/* aUserBackupAirflowMap */\ +{ {0x3C14DC, 0x4417A3, 0x4417A3, 0x4417A3, 0x4417A3, 0x4417A3, 0x4417A3, 0x4417A3, 0x4417A3, 0x4417A3, 0x4417A3},\ + { 0x5B8D80, 0x7704C0, 0x8C30AC, 0xC84588, 0xF05370, 0x1186158, 0x1186158, 0x1186158, 0x1186158, 0x1186158, 0x1186158},\ + { 0x6ACFC0, 0x8F6EC0, 0xBBAEE0, 0xFD4BC0, 0x1312D00, 0x16E3600, 0x1AB3F00, 0x1F78A40, 0x2349340, 0x243D580, 0x2625A00},\ + { 0x6ACFC0, 0x989680, 0xB28720, 0xDBBA00, 0x112A880, 0x14FB180, 0x1BD8E80, 0x2255100, 0x2BDE780, 0x3567E00, 0x3993FD8},\ + { 0x7270E0, 0x989680, 0xCAF120, 0xE975A0, 0x11D56E0, 0x1681B80, 0x1D905C0, 0x2CD29C0, 0x3938700, 0x4B1A130, 0x4D9AF18},\ + { 0x7270E0, 0x989680, 0xCAF120, 0xF73140, 0x1406F40, 0x19BFCC0, 0x243D580, 0x3938700, 0x4B1A130, 0x59A5380, 0x68E7780},\ + { 0x7270E0, 0x989680, 0xCAF120, 0xF73140, 0x132B3A0, 0x1BA8140, 0x2AEA540, 0x3C14DC0, 0x529CAE8, 0x6BA55F8, 0x7D2B750},\ + { 0x7270E0, 0x989680, 0xCAF120, 0xF73140, 0x132B3A0, 0x1F4ADD4, 0x2AEA540, 0x3EF1480, 0x55D4A80, 0x6F94740, 0x8F0D180},\ + { 0x7270E0, 0x989680, 0xCAF120, 0xF73140, 0x132B3A0, 0x1F4ADD4, 0x2AEA540, 0x40D9900, 0x59A5380, 0x754D4C0, 0xA21FE80},\ + { 0x7270E0, 0x989680, 0xCAF120, 0xF73140, 0x132B3A0, 0x1F4ADD4, 0x2AEA540, 0x42C1D80, 0x5D75C80, 0x8583B00, 0xBEBC200},\ + { 0x7270E0, 0x989680, 0xCAF120, 0xF73140, 0x132B3A0, 0x1F4ADD4, 0x2AEA540, 0x42C1D80, 0x623A7C0, 0x9896800, 0xDB58580}},\ +/* u8ManifoldTimeConstantTrim */\ +0x1f,\ +/* u8EnableBackupAirflowTransients */\ +0x00,\ +/* aUserPrimerSpread */\ +{-40000,\ + -30000,\ + -20000,\ + -10000,\ + 0,\ + 10000,\ + 20000,\ + 30000,\ + 40000,\ + 50000,\ + 60000},\ +/* aUserPrimerTable */\ +{1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u},\ +/* aUserInjShortOpeningSpread */\ +{0,\ + 200,\ + 400,\ + 600,\ + 800,\ + 1000,\ + 1200,\ + 1400,\ + 1600,\ + 1800,\ + 2000},\ +/* aUserInjShortOpeningTable */\ +{870u,\ + 870u,\ + 870u,\ + 890u,\ + 930u,\ + 1030u,\ + 1200u,\ + 1400u,\ + 1600u,\ + 1800u,\ + 2000u},\ +/* u32STTNegLimit */\ +800,\ +/* u32STTPosLimit */\ +1150,\ +/* u32CLStepClosed */\ +5,\ +/* u32CLIncClosed */\ +1,\ +/* u32CLStepOpen */\ +7,\ +/* u32CLIncOpen */\ +2,\ +/* u16TimingMainOffset */\ +10000,\ +/* u32AFMTransientControlRPMLimit */\ +3000,\ +/* u8WastedSparkEnable */\ +0,\ +/* u16AFRReinstate */\ +1500,\ +/* u16AFRCutoff */\ +1700,\ +/* u32TPSClosedLower */\ +5300,\ +/* u32TPSClosedUpper */\ +8300,\ +/* u32ISCESTTrimPos */\ +7000,\ +/* u32ISCESTTrimNeg */\ +7000,\ +/* u32CLO2ESTTrimPos */\ +2000,\ +/* u32CLO2ESTTrimNeg */\ +2000,\ +/* u16CylinderCC */\ +500,\ +/* u8EnableAFMPrimaryInputOpen */\ +1,\ +/* u32SpeedDensityAFMTPSLim */\ +35000,\ +/* au16SeqRPMLimit */\ +{6000,\ + 6000,\ + 6000,\ + 6000,\ + 6000,\ + 6000,\ + 6000,\ + 6000},\ +/* u16SeqRPMLimitHyst */\ +200,\ +/* u16HighVacuumEnableKpa */\ +13000,\ +/* u16HighVacuumDisableKpa */\ +18000,\ +/* u16OverrunCutEnableRPM */\ +500,\ +/* u16OverrunCutDisableRPM */\ +800,\ +/* u16RPMRunThreshold */\ +350,\ +/* u8SeqFuelAssign */\ +6,\ +/* u16ESTFilterClosed */\ +10,\ +/* u16ESTFilterOpen */\ +80,\ +/* u16ESTCLGain */\ +40,\ +/* u8EnableAFMPrimaryInputClosed */\ +1,\ +/* s16SequenceFuelOffset */\ +1,\ +/* s16SequenceFuelOffset */\ +1,\ +/* s16SequenceFuelOffset */\ +1,\ +/* s16SequenceFuelOffset */\ +1,\ +/* s16SequenceFuelGain */\ +1000,\ +/* s16SequenceFuelGain */\ +1000,\ +/* s16SequenceFuelGain */\ +1000,\ +/* s16SequenceFuelGain */\ +1000,\ +/* boTPSCANPrimary */\ +0,\ +/* boPPSCANPrimary */\ +0,\ +/* boCTSCANPrimary */\ +0,\ +/* boATSCANPrimary */\ +0,\ +/* boMAPCANPrimary */\ +0,\ +/* au32PrioCANID */\ +1217,\ +/* au32PrioCANID */\ +401,\ +/* au32PrioCANID */\ +1001,\ +/* au32PrioCANID */\ +2024,\ +/* au8SensorCANDataOffset */\ +{16,16,16,16,16,16,16,16},\ +/* au8SensorCANDataByteCount */\ +{2,2,2,2,2,2,2,2},\ +/* u32SyncPhaseRepeats */\ +2,\ +/* s32MapSensorGain */\ +38700,\ +/* s32MapSensorOffset */\ +31000,\ +/* u8InjDivide */\ +1,\ +/* u8CLO2Leftenable */\ +0,\ +/* u8CLO2RightEnable */\ +0,\ +/* u8ReturnlessEnable */\ +0,\ +/* u16ReturnlessPressureKPa */\ +450,\ +/* u8CrankingAirflowEnable */\ +1,\ +/* u8StepperIACEnable */\ +0,\ +/* u16IACStepsOpenHot */\ +10,\ +/* u16IACStepsOpenCold */\ +80,\ +/* u16IdleEntryOffset */\ +555,\ +/* s32RadFanOnTemp */\ +80005,\ +/* s32RadFanOffTemp */\ +60005,\ +/* enFuelPumpRelay */\ +EH_IO_Invalid,\ +/* enESTBypass */\ +EH_IO_Invalid,\ +/* aUserAirSensorSpread */\ +{203u,\ + 299u,\ + 391u,\ + 606u,\ + 802u,\ + 1014u,\ + 1407u,\ + 1774u,\ + 2110u,\ + 2432u,\ + 2946u,\ + 3565u,\ + 4067u,\ + 4658u,\ + 4782u,\ + 4856u,\ + 4924u},\ +/* aUserAirSensorTable */\ +{500000,\ + 200000,\ + 140000,\ + 132000,\ + 122000,\ + 110000,\ + 100000,\ + 87000,\ + 79000,\ + 71000,\ + 60000,\ + 40000,\ + 20000,\ + 2000,\ + -6000,\ + -15000,\ + -40000},\ +/* aFuelIOResource */\ +{EH_IO_Invalid, EH_IO_Invalid, EH_IO_TMR13, EH_IO_TMR12},\ +/* aESTIOResource */\ +{EH_IO_TMR9, EH_IO_TMR8, EH_IO_TMR7, EH_IO_TMR6},\ +/* aIACIOResource */\ +{EH_IO_Invalid, EH_IO_Invalid, EH_IO_Invalid, EH_IO_Invalid},\ +/* boOBDISCADV */\ +0,\ +/* u8TriggerType */\ +2,\ +/* u8SyncType */\ +0,\ +/* u8TriggerPullStrength */\ +2,\ +/* u8SyncPullStrength */\ +0,\ +/* u16MinLinearFuelPulse */\ +0,\ +/* u16CTSADResource */\ +EH_IO_GPSE2,\ +/* u16MAPADResource */\ +EH_IO_TMR16,\ +/* u16ATSADResource */\ +EH_IO_Invalid,\ +/* u16AFMADResource */\ +EH_IO_Invalid,\ +/* u16TPSADResource */\ +EH_IO_GPSE4,\ +/* aUserTipInCorrectionSpread */\ +{0,\ + 250,\ + 500,\ + 1000,\ + 1250,\ + 1500,\ + 1750,\ + 2000,\ + 2250,\ + 2500,\ + 2750,\ + 3000,\ + 3250,\ + 3500,\ + 3750,\ + 4000,\ + 4250},\ +/* aUserTipInCorrectionTable */\ +{1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u},\ +/* Logic Block Var */\ +{0u,\ + 0u,\ + 0u,\ + 0u,\ + 0u,\ + 0u,\ + 0u,\ + 0u},\ +/* Logic Block Operand */\ +{1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u,\ + 1000u},\ +/* Logic Block Chain Output */\ +{0u,\ + 0u,\ + 0u,\ + 0u,\ + 0u,\ + 0u,\ + 0u,\ + 0u},\ +/* Thermofan Relay */\ +EH_IO_Invalid,\ +/* EST IO Mux Resource */\ +{EH_IO_Invalid,\ + EH_IO_Invalid,\ + EH_IO_Invalid,\ + EH_IO_Invalid},\ +/* UEGO CAN Primary */\ +1,\ +/* PWM 2D 1 Axis Source X */\ +255,\ +/* PWM 2D 2 Axis Source X */\ +1,\ +/* PWM 2D 3 Axis Source X */\ +0,\ +/* PWM 2D 4 Axis Source X */\ +0,\ +/* PWM 2D 5 Axis Source X */\ +255,\ +/* PWM 2D 6 Axis Source X */\ +255,\ +/* PWM 2D 7 Axis Source X */\ +255,\ +/* PWM 2D 8 Axis Source X */\ +255,\ +/* PWM 3D 1 Axis Source X */\ +0,\ +/* PWM 3D 2 Axis Source X */\ +255,\ +/* PWM 3D 3 Axis Source X */\ +255,\ +/* PWM 3D 4 Axis Source X */\ +255,\ +/* PWM 3D 1 Axis Source Y */\ +5,\ +/* PWM 3D 2 Axis Source Y */\ +255,\ +/* PWM 3D 3 Axis Source Y */\ +255,\ +/* PWM 3D 4 Axis Source Y */\ +255,\ +/* PWM 2D 1 IO Resource */\ +EH_IO_Invalid,\ +/* PWM 2D 2 IO Resource */\ +EH_IO_TMR3,\ +/* PWM 2D 3 IO Resource */\ +EH_IO_TMR4,\ +/* PWM 2D 4 IO Resource */\ +EH_IO_TMR5,\ +/* PWM 2D 5 IO Resource */\ +EH_IO_Invalid,\ +/* PWM 2D 6 IO Resource */\ +EH_IO_Invalid,\ +/* PWM 2D 7 IO Resource */\ +EH_IO_Invalid,\ +/* PWM 2D 8 IO Resource */\ +EH_IO_Invalid,\ +/* PWM 3D 1 IO Resource */\ +EH_IO_Invalid,\ +/* PWM 3D 2 IO Resource */\ +EH_IO_Invalid,\ +/* PWM 3D 3 IO Resource */\ +EH_IO_Invalid,\ +/* PWM 3D 4 IO Resource */\ +EH_IO_Invalid,\ +/* PWM 2D 1 Table_XAXIS */\ +{0,\ + 0x1000,\ + 0x2000,\ + 0x3000,\ + 0x4000,\ + 0x5000,\ + 0x6000,\ + 0x7000,\ + 0x8000,\ + 0x9000,\ + 0xa000,\ + 0xb000,\ + 0xc000,\ + 0xd000,\ + 0xe000,\ + 0xf000,\ + 0xffff},\ +/* PWM 2D 2 Table_XAXIS */\ +{0,\ + 10000,\ + 13000,\ + 16000,\ + 20000,\ + 25000,\ + 30000,\ + 35000,\ + 40000,\ + 45000,\ + 50000,\ + 55000,\ + 60000,\ + 65000,\ + 70000,\ + 75000,\ + 90000},\ +/* PWM 2D 3 Table_XAXIS */\ +{0,\ + 500,\ + 1100,\ + 1200,\ + 2000,\ + 2500,\ + 3000,\ + 3500,\ + 4000,\ + 4500,\ + 5000,\ + 5500,\ + 6000,\ + 6500,\ + 7000,\ + 7500,\ + 9000},\ +/* PWM 2D 4 Table_XAXIS */\ +{0,\ + 100,\ + 200,\ + 1000,\ + 1500,\ + 2000,\ + 2500,\ + 3000,\ + 3500,\ + 4000,\ + 4500,\ + 5000,\ + 5500,\ + 6000,\ + 6500,\ + 7000,\ + 7500},\ +/* PWM 2D 5 Table_XAXIS */\ +{0,\ + 0x100,\ + 0x200,\ + 0x300,\ + 0x400,\ + 0x500,\ + 0x600,\ + 0x700,\ + 0x800,\ + 0x900,\ + 0xa00,\ + 0xb00,\ + 0xc00,\ + 0xd00,\ + 0xe00,\ + 0xf00,\ + 0xffff},\ +/* PWM 2D 6 Table_XAXIS */\ +{0,\ + 0x100,\ + 0x200,\ + 0x300,\ + 0x400,\ + 0x500,\ + 0x600,\ + 0x700,\ + 0x800,\ + 0x900,\ + 0xa00,\ + 0xb00,\ + 0xc00,\ + 0xd00,\ + 0xe00,\ + 0xf00,\ + 0xfff},\ +/* PWM 2D 7 Table_XAXIS */\ +{0,\ + 0x10,\ + 0x20,\ + 0x30,\ + 0x40,\ + 0x50,\ + 0x60,\ + 0x70,\ + 0x80,\ + 0x90,\ + 0xa0,\ + 0xb0,\ + 0xc0,\ + 0xd0,\ + 0xe0,\ + 0xf0,\ + 0xff},\ +/* PWM 2D 8 Table_XAXIS */\ +{0,\ + 0x100,\ + 0x200,\ + 0x300,\ + 0x400,\ + 0x500,\ + 0x600,\ + 0x700,\ + 0x800,\ + 0x900,\ + 0xa00,\ + 0xb00,\ + 0xc00,\ + 0xd00,\ + 0xe00,\ + 0xf00,\ + 0xfff},\ +/* PWM 2D 1 Table */\ +{10000,\ + 10000,\ + 10000,\ + 10000,\ + 10000,\ + 10000,\ + 10000,\ + 10000,\ + 32000,\ + 55000,\ + 55000,\ + 55000,\ + 55000,\ + 55000,\ + 55000,\ + 55000,\ + 55000},\ +/* PWM 2D 2 Table */\ +{50000,\ + 50000,\ + 6000,\ + 6000,\ + 6000,\ + 6000,\ + 6000,\ + 6000,\ + 6000,\ + 6000,\ + 6000,\ + 6000,\ + 6000,\ + 6000,\ + 60000,\ + 6000,\ + 6000},\ +/* PWM 2D 3 Table */\ +{6000,\ + 6000,\ + 6000,\ + 60000,\ + 60000,\ + 60000,\ + 60000,\ + 60000,\ + 60000,\ + 60000,\ + 60000,\ + 60000,\ + 60000,\ + 60000,\ + 60000,\ + 60000,\ + 60000},\ +/* PWM 2D 4 Table */\ +{60000,\ + 60000,\ + 40000,\ + 40000,\ + 40000,\ + 30000,\ + 20000,\ + 10000,\ + 5000,\ + 5000,\ + 5000,\ + 5000,\ + 5000,\ + 5000,\ + 5000,\ + 5000,\ + 5000},\ +/* PWM 2D 5 Table */\ +{0,\ + 54,\ + 100,\ + 150,\ + 200,\ + 250,\ + 300,\ + 350,\ + 400,\ + 450,\ + 500,\ + 550,\ + 600,\ + 650,\ + 700,\ + 750,\ + 800},\ +/* PWM 2D 6 Table */\ +{0,\ + 55,\ + 100,\ + 150,\ + 200,\ + 250,\ + 300,\ + 350,\ + 400,\ + 450,\ + 500,\ + 550,\ + 600,\ + 650,\ + 700,\ + 750,\ + 800},\ +/* PWM 2D 7 Table */\ +{0,\ + 56,\ + 100,\ + 150,\ + 200,\ + 250,\ + 300,\ + 350,\ + 400,\ + 450,\ + 500,\ + 550,\ + 600,\ + 650,\ + 700,\ + 750,\ + 800},\ +/* PWM 2D 8 Table */\ +{0,\ + 57,\ + 100,\ + 150,\ + 200,\ + 250,\ + 300,\ + 350,\ + 400,\ + 450,\ + 500,\ + 550,\ + 600,\ + 650,\ + 700,\ + 750,\ + 800},\ +/* PWM 3D 1 Map_XAXIS */\ +{0u,\ + 500u,\ + 1000u,\ + 1500u,\ + 2000u,\ + 2500u,\ + 3000u,\ + 3500u,\ + 4000u,\ + 4500u,\ + 5000u,\ + 5500u,\ + 6000u,\ + 6500u,\ + 7000u,\ + 7500u,\ +8000u},\ +/* PWM 3D 2 Map_XAXIS */\ +{0,\ + 1000,\ + 2000,\ + 3000,\ + 4000,\ + 5000,\ + 6000,\ + 7000,\ + 8000,\ + 9000,\ + 10000,\ + 11000,\ + 12000,\ + 13000,\ + 14000,\ + 15000,\ + 16000},\ +/* PWM 3D 3 Map_XAXIS */\ +{0,\ + 0x107,\ + 0x207,\ + 0x307,\ + 0x407,\ + 0x507,\ + 0x607,\ + 0x707,\ + 0x807,\ + 0x907,\ + 0xa07,\ + 0xb07,\ + 0xc07,\ + 0xd07,\ + 0xe07,\ + 0xf07,\ + 0xfff},\ +/* PWM 3D 4 Map_XAXIS */\ +{0,\ + 0x10,\ + 0x20,\ + 0x30,\ + 0x40,\ + 0x50,\ + 0x60,\ + 0x70,\ + 0x80,\ + 0x90,\ + 0xa0,\ + 0xb0,\ + 0xc0,\ + 0xd0,\ + 0xe0,\ + 0xf0,\ + 0xff},\ +/* PWM 3D 1 Map_YAXIS */\ +{0,\ + 0x1000,\ + 0x2000,\ + 0x3000,\ + 0x4000,\ + 0x5000,\ + 0x6000,\ + 0x7000,\ + 0x8000,\ + 0x9000,\ + 0xa000,\ + 0xb000,\ + 0xc000,\ + 0xd000,\ + 0xe000,\ + 0xf000,\ + 0xffff},\ +/* PWM 3D 2 Map_YAXIS */\ +{0,\ + 0x1040,\ + 0x2040,\ + 0x3040,\ + 0x4040,\ + 0x5040,\ + 0x6040,\ + 0x7040,\ + 0x8040,\ + 0x9040,\ + 0xa040,\ + 0xb040,\ + 0xc040,\ + 0xd040,\ + 0xe040,\ + 0xf040,\ + 0xffff},\ +/* PWM 3D 3 Map_YAXIS */\ +{0,\ + 0x108,\ + 0x208,\ + 0x308,\ + 0x408,\ + 0x508,\ + 0x608,\ + 0x708,\ + 0x808,\ + 0x908,\ + 0xa08,\ + 0xb08,\ + 0xc08,\ + 0xd08,\ + 0xe08,\ + 0xf08,\ + 0xfff},\ +/* PWM 3D 4 Map_YAXIS */\ +{0,\ + 0x100,\ + 0x200,\ + 0x300,\ + 0x400,\ + 0x500,\ + 0x600,\ + 0x700,\ + 0x800,\ + 0x900,\ + 0xa00,\ + 0xb00,\ + 0xc00,\ + 0xd00,\ + 0xe00,\ + 0xf00,\ + 0xfff},\ +/* PWM 3D Map 1 */\ +{\ + { 55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000},\ + { 55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000},\ + { 55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000,55000},\ + { 25000,25000,25000,25000,25000,27000,29000,31000,33000,40000,45000,50000,55000,55000,55000,55000,60000},\ + { 25000,25000,25000,25000,25000,27000,29000,31000,33000,40000,45000,50000,55000,55000,55000,55000,60000},\ + { 25000,25000,25000,25000,25000,27000,29000,31000,33000,40000,45000,50000,55000,55000,55000,55000,60000},\ + { 18000,18000,18000,18000,21000,24000,27000,30000,33000,39000,41000,44000,47000,50000,56000,53000,60000},\ + { 18000,18000,18000,18000,21000,24000,27000,30000,33000,39000,41000,44000,47000,50000,56000,59000,60000},\ + { 18000,18000,18000,18000,21000,24000,27000,30000,33000,41000,45000,49000,53000,57000,59000,59000,60000},\ + { 18000,18000,18000,18000,21000,24000,27000,30000,33000,41000,45000,49000,53000,57000,59000,59000,60000},\ + { 18000,18000,18000,18000,21000,24000,27000,30000,33000,41000,45000,49000,53000,57000,59000,59000,60000},\ + { 18000,18000,18000,18000,21000,24000,27000,30000,33000,41000,45000,49000,53000,57000,59000,59000,60000},\ + { 18000,18000,18000,18000,21000,24000,27000,30000,33000,41000,45000,49000,53000,57000,59000,59000,60000},\ + { 18000,18000,18000,18000,21000,24000,27000,30000,33000,41000,45000,49000,53000,57000,59000,59000,60000},\ + { 18000,18000,18000,18000,21000,24000,27000,30000,33000,41000,45000,49000,53000,57000,57000,59000,60000},\ + { 18000,18000,18000,18000,21000,24000,27000,30000,33000,41000,45000,49000,53000,57000,57000,57000,60000},\ + { 18000,18000,18000,18000,21000,24000,27000,30000,33000,41000,45000,49000,53000,57000,57000,57000,60000},\ +},\ +/* PWM 3D Map 2 */\ +{\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160},\ + { 100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + { 100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + { 100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + { 0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ +},\ +/* PWM 3D Map 3 */\ +{\ + { 0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160},\ + { 0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160},\ + { 100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + { 100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + { 100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + { 0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ +},\ +/* PWM 3D Map 4 */\ +{\ + { 100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + { 100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + { 100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + { 100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + { 100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + { 100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + { 100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + { 100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\ +},\ +/* Fuel Pressure Solenoid Resource */\ +EH_IO_TMR1,\ +/* VCT AB Pullup Enable */\ +1,\ +/* VCT CD Pullup Enable */\ +1,\ +/* aVVTInputResource */\ +{EH_IO_TMR18,EH_IO_Invalid,EH_IO_Invalid,EH_IO_Invalid},\ +/* aVVTInputType */\ +{1,0,0,0},\ +/* u16FRPADResource */\ +EH_IO_GPSE5,\ +/* aUserFuelFlowRateSpread */\ +{0,1500,3000,4500,6000,7500,9000,10500,12000,13500,15000,16500,18000,19500,21000,22500,24000},\ +/* aUserFuelFlowRateTable */\ +{0,3547,5015,6143,7094,7931,8688,9384,10124,10641,11216,11764,12289,12793,13274,13741,14191},\ +/* u8VariableFuelPressureEnable */\ +1,\ +/* s32FuelPressureSensorGain */\ +30000,\ +/* s32FuelPressureSensorOffset */\ +-760,\ +/* u16FuelPressurePGain */\ +2500,\ +/* u16FuelPressureIGain */\ +550,\ +/* u8FuelPrimeEnable */\ +0,\ +/* aUserTimingMapStage1 */\ +{ {130,130,130,130,120,60,0,0,0,0,0,0,0,0,0,0,0},\ + { 130,130,130,130,120,120,120,120,120,120,120,120,120,120,120,120,120},\ + { 130,130,130,130,120,120,120,120,120,120,120,120,120,120,120,120,120},\ + { 130,130,140,160,180,200,200,200,200,180,160,140,120,120,120,120,120},\ + { 130,150,180,210,240,270,270,250,230,210,190,170,150,130,110,90,70},\ + { 130,150,180,210,240,270,270,250,230,210,190,170,150,130,110,90,70},\ + { 130,150,180,210,240,270,270,250,230,210,190,170,150,130,110,90,70},\ + { 130,150,180,210,240,270,270,250,230,210,190,170,150,130,110,90,70},\ + { 130,150,180,210,240,270,270,250,230,210,190,170,150,130,110,90,70},\ + { 130,150,180,210,240,270,270,250,230,210,190,170,150,130,110,90,70},\ + { 130,150,180,210,240,270,270,250,230,210,190,170,150,130,110,90,70},\ + { 130,150,180,210,240,270,270,250,230,210,190,170,150,130,110,90,70},\ + { 130,150,180,210,240,270,270,250,230,210,190,170,150,130,110,90,70},\ + { 130,150,180,210,240,270,270,250,230,210,190,170,150,130,110,90,70},\ + { 130,150,180,210,240,270,270,250,230,210,190,170,150,130,110,90,70},\ + { 130,150,180,210,240,270,270,250,230,210,190,170,150,130,110,90,70},\ + { 90,90,90,90,90,90,90,90,90,90,90,80,80,80,80,80,80}},\ +/* aUserTorquePedalTransferSpread */\ +{0,1400,2800,4200,5600,7000,8400,9800,11200,12600,14000,15400,16800,18800,20800,22800,24800},\ +/* aUserTorquePedalTransferTable */\ +{0,200,3500,6200,8100,9800,11200,12500,13700,14800,15900,16900,17800,19100,20400,21600,24800},\ +/* aUserPressureValveFeedForwardSpread */\ +{-16000,-14000,-12000,-10000,-8000,-6000,-4000,-2000,0,2000,4000,6000,8000,10000,12000,14000,16000},\ +/* aUserTPressureValveFeedForwardTable */\ +{57000,57000,57000,57000,52000,47000,42000,37000,32000,27000,22000,17000,12000,7000,2000,2000,2000},\ +/* AFMMaxCycleDeltamgPos */\ +5000u,\ +/* AFMMaxCycleDeltamgNeg */\ +3000u,\ +/* aUserPWM2DPeriod */\ +{23500,2400,9400,23500,5000,5000,5000,5000},\ +/* aUserPWM3DPeriod */\ +{5000,5000,5000,5000},\ +/* u8FuelPumpPrimerTime */\ +5u,\ +/* u8DBSlaveConfig */\ +1u,\ +/* u8DBSlaveOptions */\ +2u,\ +/* u16AFRADResource */\ +EH_IO_Invalid,\ +/* u16PPSMADResource */\ +EH_IO_GPSE1,\ +/* u16PPSSADResource */\ +EH_IO_GPSE3,\ +/* au16AuxInputResource */\ +{EH_IO_Invalid,EH_IO_Invalid,EH_IO_Invalid,EH_IO_Invalid},\ +/* au16AuxInputFunction */\ +{11,0,0,0},\ +/* s32AFRADInputGain */\ +650,\ +/* s32AFRADInputOffset */\ +0,\ +/* u16AFRFuelTypeGain */\ +1000,\ +/* aUserFuelCutsSpread */\ +{2000,2500,3000,3500,4000,4500,5000,5500,6000,6500,7000,7500,8000,8500,9000,9500,10000},\ +/* aUserFuelCutsTable */\ +{0,40,40,60,60,60,80,100,100,100,100,100,100,100,100,100,100},\ +/* au16AuxInputLowThres */\ +{1600,1600,1600,1600},\ +/* au16AuxInputHighThres */\ +{4000,4000,4000,4000},\ +/* u16FuelPressureControlOffset */\ +20,\ +/* u16FuelPressureControlStartOffset */\ +10,\ +/* aUserTimingSecondary1xSpread */\ +{0u,\ + 500u,\ + 1000u,\ + 1500u,\ + 2000u,\ + 2500u,\ + 3000u,\ + 3500u,\ + 4000u,\ + 4500u,\ + 5000u,\ + 5500u,\ + 6000u,\ + 6500u,\ + 7000u,\ + 7500u,\ +8000u},\ +/* aUserTimingSecondary1ySpread */\ +{20000u,\ +30000u,\ +40000u,\ +50000u,\ +60000u,\ +70000u,\ +80000u,\ +90000u,\ +100000u,\ +115000u,\ +130000u,\ +145000u,\ +160000u,\ +175000u,\ +190000u,\ +205000u,\ +220000u},\ +/* u16ISCColdISCMin */\ +1500,\ +/* u16ISCColdISCMax */\ +4000,\ +/* u16ISCHotISCMin */\ +100,\ +/* u16ISCHotISCMax */\ +2000,\ +/* u16GDIValveMin */\ +2200,\ +/* u16GDIValveMax */\ +11000,\ +/* u16GDIValveFF */\ +2000,\ +/* aUserPedalTransferSpread */\ +{500u,\ +750u,\ +1000u,\ +1250u,\ +1500u,\ +1750u,\ +2000u,\ +2250u,\ +2500u,\ +2750u,\ +3000u,\ +3250u,\ +3500u,\ +3750u,\ +4000u,\ +4250u,\ +4500u},\ +/* aUserPedalTransferTable */\ +{1000u,\ +1050u,\ +1100u,\ +1150u,\ +1200u,\ +1400u,\ +1700u,\ +2100u,\ +2500u,\ +2750u,\ +3000u,\ +3250u,\ +3500u,\ +3750u,\ +4000u,\ +4250u,\ +4500u},\ +/* u16PressureControlThreshold */\ +2500u,\ +/* u16ThrottlePressureControlCal */\ +10u,\ +/* u16PressureControlHyst */\ +1000u,\ +/* u8BoostChargeMAPEnable */\ +1u,\ +/* u16BoostChargeTPSLimit */\ +45000u,\ +/* u16ISCEntryRamp */\ +200u,\ +/* u16ISCPoststartRamp */\ +200u,\ +/* u32AirflowFMELimitLow */\ +5000000u,\ +/* u32AirflowFMELimitHigh */\ +8000000u,\ +/* u16TorqueReductionMaxDuration */\ +20u,\ +/* u16StallSaverRPMThreshold */\ +200u,\ +/* aUserETCScaleSpread */\ +{2000u,\ +2250u,\ +2500u,\ +2750u,\ +3000u,\ +3250u,\ +3500u,\ +3750u,\ +4000u,\ +4250u,\ +4500u,\ +4750u,\ +5000u,\ +5250u,\ +5500u,\ +5750u,\ +6000u},\ +/* aUserETCScaleTable */\ +{14u,\ +16u,\ +18u,\ +20u,\ +22u,\ +24u,\ +26u,\ +28u,\ +30u,\ +32u,\ +34u,\ +36u,\ +38u,\ +40u,\ +42u,\ +44u,\ +46u},\ +/* u16TorqueReductionMaxFuelCut */\ +10u,\ +/* u16ShiftCountLimit */\ +100u,\ +/* au16BoostTarget */\ +{16000u,18000u,19000u,19000u,19000u,19000u},\ +/* u16GDIPressureMin */\ +7000u,\ +/* u16GDIPressureMax */\ +18500u,\ +/* u16GDIMAPMin */\ +50000u,\ +/* u16GDIMAPMax */\ +150000u,\ +/* u16ESTPosRateMax */\ +1u,\ +/* u16ESTNegRateMax) */\ +2u,\ +/* u16PressureControlDPos */\ +10u,\ +/* u16PressureControlDNeg */\ +10u,\ +/* u16ShiftCountPressureControlLimit */\ +20u,\ +/* u16ShiftPressureControl */\ +48u,\ +/* aPWM3DSlowIOOutputResource */\ +{EH_IO_TMR2, EH_IO_Invalid, EH_IO_Invalid, EH_IO_Invalid},\ +/* aPWM3DSlowPeriod */\ +{50, 50, 50, 50},\ +/* u16SensorHystLimitRPM */\ +500u,\ +/* userCalPPSCalMin */\ +800u,\ +/* userCalPPSCalMax */\ +3500u,\ +/* aUserPseudoMAPxSpread */\ +{0u,\ + 500u,\ + 1000u,\ + 1500u,\ + 2000u,\ + 2500u,\ + 3000u,\ + 3500u,\ + 4000u,\ + 4500u,\ + 5000u,\ + 5500u,\ + 6000u,\ + 6500u,\ + 7000u,\ + 7500u,\ +8000u},\ +/* aUserPseudoMAPySpread */\ +{0u,\ + 5000u,\ + 10000u,\ + 15000u,\ + 20000u,\ + 25000u,\ + 30000u,\ + 35000u,\ + 40000u,\ + 45000u,\ + 50000u,\ + 55000u,\ + 60000u,\ + 65000u,\ + 70000u,\ + 75000u,\ + 90000u},\ +/* aUserPseudoMAPMap */\ +{{82000,83000,84000,85000,86000,90000,90000,90000,90000,90000,90000,90000,90000,90000,90000,90000,90000},\ +{17000,28000,44000,63000,86000,89000,89000,89000,89000,89000,89000,89000,89000,89000,89000,89000,90000},\ +{8000,17000,34000,49000,62000,71000,77000,82000,85000,87000,89000,91000,92000,94000,96000,97000,101000},\ +{5000,12000,26000,40000,53000,62000,70000,75000,80000,83000,85000,88000,90000,92000,94000,95000,101000},\ +{4000,10000,21000,34000,46000,56000,64000,70000,75000,79000,82000,84000,86000,88000,90000,92000,101000},\ +{2000,8000,18000,29000,41000,50000,59000,65000,71000,75000,78000,81000,83000,85000,87000,88000,101000},\ +{1000,7000,15000,26000,36000,46000,54000,61000,67000,72000,75000,78000,81000,83000,84000,86000,101000},\ +{1000,6000,13000,23000,33000,42000,50000,58000,64000,68000,72000,76000,78000,81000,82000,84000,101000},\ +{0,5000,12000,21000,30000,39000,48000,55000,61000,66000,70000,73000,76000,79000,81000,82000,101000},\ +{0,4000,11000,19000,28000,37000,45000,52000,58000,63000,67000,71000,74000,77000,79000,81000,101000},\ +{0,4000,10000,17000,26000,34000,42000,49000,55000,61000,65000,69000,72000,75000,77000,79000,101000},\ +{0,4000,9000,16000,24000,32000,40000,47000,53000,58000,63000,67000,70000,73000,75000,77000,101000},\ +{0,3000,8000,15000,22000,30000,38000,45000,50000,56000,61000,65000,68000,71000,74000,76000,101000},\ +{0,3000,7000,14000,21000,29000,36000,43000,49000,54000,59000,63000,67000,70000,72000,74000,101000},\ +{0,3000,7000,13000,20000,27000,34000,41000,47000,52000,57000,61000,65000,68000,71000,73000,101000},\ +{0,3000,6000,12000,19000,26000,33000,39000,45000,50000,55000,60000,63000,66000,69000,72000,101000},\ +{0,2000,6000,11000,18000,25000,31000,38000,44000,49000,54000,58000,62000,65000,68000,70000,101000}},\ +/* u8PseudoMAPEnable */\ +1,\ +/* u16VSSPerRPM */\ +{\ + 82,\ + 131,\ + 193,\ + 262,\ + 335,\ + 397,\ + 450,\ + 500},\ +/* u16VSSCANCal */\ +507,\ +/* u16ETCOverrideKeys */\ +0,\ +/* u16ETCOverride */\ +0,\ +/* u16DiagType */\ +1,\ +/* u16CRC16 */\ +0x1234,\ +(uint8*)&au32Offsets\ +} + diff --git a/source/GenericDrivers/diskio.h b/source/GenericDrivers/diskio.h new file mode 100644 index 0000000..00d8615 --- /dev/null +++ b/source/GenericDrivers/diskio.h @@ -0,0 +1,85 @@ +/*----------------------------------------------------------------------- +/ Low level disk interface modlue include file (C)ChaN, 2013 +/-----------------------------------------------------------------------*/ + +#ifndef _DISKIO_DEFINED +#define _DISKIO_DEFINED + +#ifdef __cplusplus +extern "C" { +#endif + +#include "integer.h" + + +/* Status of Disk Functions */ +typedef BYTE DSTATUS; + +/* Results of Disk Functions */ +typedef enum { + RES_OK = 0, /* 0: Successful */ + RES_ERROR, /* 1: R/W Error */ + RES_WRPRT, /* 2: Write Protected */ + RES_NOTRDY, /* 3: Not Ready */ + RES_PARERR /* 4: Invalid Parameter */ +} DRESULT; + + +/*---------------------------------------*/ +/* Prototypes for disk control functions */ + + +DSTATUS disk_initialize (BYTE pdrv); +DSTATUS disk_status (BYTE pdrv); +DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); +DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); +DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); + + +/* Disk Status Bits (DSTATUS) */ +#define STA_NOINIT 0x01 /* Drive not initialized */ +#define STA_NODISK 0x02 /* No medium in the drive */ +#define STA_PROTECT 0x04 /* Write protected */ + + +/* Command code for disk_ioctrl fucntion */ + +/* Generic command (used by FatFs) */ +#define CTRL_SYNC 0 /* Flush disk cache (for write functions) */ +#define GET_SECTOR_COUNT 1 /* Get media size (for only f_mkfs()) */ +//#define GET_SECTOR_SIZE 2 /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */ +#define GET_BLOCK_SIZE 3 /* Get erase block size (for only f_mkfs()) */ +#define CTRL_ERASE_SECTOR 4 /* Force erased a block of sectors (for only _USE_ERASE) */ + +/* Generic command (not used by FatFs) */ +//#define CTRL_POWER 5 /* Get/Set power status */ +//#define CTRL_LOCK 6 /* Lock/Unlock media removal */ +//#define CTRL_EJECT 7 /* Eject media */ +//#define CTRL_FORMAT 8 /* Create physical format on the media */ + +/* MMC/SDC specific ioctl command */ +#define MMC_GET_TYPE 10 /* Get card type */ +#define MMC_GET_CSD 11 /* Get CSD */ +#define MMC_GET_CID 12 /* Get CID */ +#define MMC_GET_OCR 13 /* Get OCR */ +#define MMC_GET_SDSTAT 14 /* Get SD status */ + +/* ATA/CF specific ioctl command */ +#define ATA_GET_REV 20 /* Get F/W revision */ +#define ATA_GET_MODEL 21 /* Get model name */ +#define ATA_GET_SN 22 /* Get serial number */ + + +/* MMC card type flags (MMC_GET_TYPE) */ +#define CT_MMC 0x01 /* MMC ver 3 */ +#define CT_SD1 0x02 /* SD ver 1 */ +#define CT_SD2 0x04 /* SD ver 2 */ +#define CT_SDC (CT_SD1|CT_SD2) /* SD */ +#define CT_BLOCK 0x08 /* Block addressing */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/GenericDrivers/ff.c b/source/GenericDrivers/ff.c new file mode 100644 index 0000000..257e81f --- /dev/null +++ b/source/GenericDrivers/ff.c @@ -0,0 +1,4524 @@ +/*----------------------------------------------------------------------------/ +/ FatFs - FAT file system module R0.10 (C)ChaN, 2013 +/-----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following terms. +/ +/ Copyright (C) 2013, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/-----------------------------------------------------------------------------/ +/ Feb 26,'06 R0.00 Prototype. +/ +/ Apr 29,'06 R0.01 First stable version. +/ +/ Jun 01,'06 R0.02 Added FAT12 support. +/ Removed unbuffered mode. +/ Fixed a problem on small (<32M) partition. +/ Jun 10,'06 R0.02a Added a configuration option (_FS_MINIMUM). +/ +/ Sep 22,'06 R0.03 Added f_rename(). +/ Changed option _FS_MINIMUM to _FS_MINIMIZE. +/ Dec 11,'06 R0.03a Improved cluster scan algorithm to write files fast. +/ Fixed f_mkdir() creates incorrect directory on FAT32. +/ +/ Feb 04,'07 R0.04 Supported multiple drive system. +/ Changed some interfaces for multiple drive system. +/ Changed f_mountdrv() to f_mount(). +/ Added f_mkfs(). +/ Apr 01,'07 R0.04a Supported multiple partitions on a physical drive. +/ Added a capability of extending file size to f_lseek(). +/ Added minimization level 3. +/ Fixed an endian sensitive code in f_mkfs(). +/ May 05,'07 R0.04b Added a configuration option _USE_NTFLAG. +/ Added FSINFO support. +/ Fixed DBCS name can result FR_INVALID_NAME. +/ Fixed short seek (<= csize) collapses the file object. +/ +/ Aug 25,'07 R0.05 Changed arguments of f_read(), f_write() and f_mkfs(). +/ Fixed f_mkfs() on FAT32 creates incorrect FSINFO. +/ Fixed f_mkdir() on FAT32 creates incorrect directory. +/ Feb 03,'08 R0.05a Added f_truncate() and f_utime(). +/ Fixed off by one error at FAT sub-type determination. +/ Fixed btr in f_read() can be mistruncated. +/ Fixed cached sector is not flushed when create and close without write. +/ +/ Apr 01,'08 R0.06 Added fputc(), fputs(), fprintf() and fgets(). +/ Improved performance of f_lseek() on moving to the same or following cluster. +/ +/ Apr 01,'09 R0.07 Merged Tiny-FatFs as a configuration option. (_FS_TINY) +/ Added long file name feature. +/ Added multiple code page feature. +/ Added re-entrancy for multitask operation. +/ Added auto cluster size selection to f_mkfs(). +/ Added rewind option to f_readdir(). +/ Changed result code of critical errors. +/ Renamed string functions to avoid name collision. +/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg. +/ Added multiple sector size feature. +/ Jun 21,'09 R0.07c Fixed f_unlink() can return FR_OK on error. +/ Fixed wrong cache control in f_lseek(). +/ Added relative path feature. +/ Added f_chdir() and f_chdrive(). +/ Added proper case conversion to extended character. +/ Nov 03,'09 R0.07e Separated out configuration options from ff.h to ffconf.h. +/ Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH. +/ Fixed name matching error on the 13 character boundary. +/ Added a configuration option, _LFN_UNICODE. +/ Changed f_readdir() to return the SFN with always upper case on non-LFN cfg. +/ +/ May 15,'10 R0.08 Added a memory configuration option. (_USE_LFN = 3) +/ Added file lock feature. (_FS_SHARE) +/ Added fast seek feature. (_USE_FASTSEEK) +/ Changed some types on the API, XCHAR->TCHAR. +/ Changed .fname in the FILINFO structure on Unicode cfg. +/ String functions support UTF-8 encoding files on Unicode cfg. +/ Aug 16,'10 R0.08a Added f_getcwd(). +/ Added sector erase feature. (_USE_ERASE) +/ Moved file lock semaphore table from fs object to the bss. +/ Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'. +/ Fixed f_mkfs() creates wrong FAT32 volume. +/ Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write(). +/ f_lseek() reports required table size on creating CLMP. +/ Extended format syntax of f_printf(). +/ Ignores duplicated directory separators in given path name. +/ +/ Sep 06,'11 R0.09 f_mkfs() supports multiple partition to complete the multiple partition feature. +/ Added f_fdisk(). +/ Aug 27,'12 R0.09a Changed f_open() and f_opendir() reject null object pointer to avoid crash. +/ Changed option name _FS_SHARE to _FS_LOCK. +/ Fixed assertion failure due to OS/2 EA on FAT12/16 volume. +/ Jan 24,'13 R0.09b Added f_setlabel() and f_getlabel(). +/ +/ Oct 02,'13 R0.10 Added selection of character encoding on the file. (_STRF_ENCODE) +/ Added f_closedir(). +/ Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO) +/ Added forced mount feature with changes of f_mount(). +/ Improved behavior of volume auto detection. +/ Improved write throughput of f_puts() and f_printf(). +/ Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write(). +/ Fixed f_write() can be truncated when the file size is close to 4GB. +/ Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code. +/ +/ Patch at October 12 is applied. +/---------------------------------------------------------------------------*/ + +#include "ff.h" /* Declarations of FatFs API */ +#include "diskio.h" /* Declarations of disk I/O functions */ +#include "sysabstract.h" /* Abstract the time function */ + +/*-------------------------------------------------------------------------- + + Module Private Definitions + +---------------------------------------------------------------------------*/ + +#if _FATFS != 80960 /* Revision ID */ +#error Wrong include file (ff.h). +#endif + + +/* Definitions on sector size */ +#if _MAX_SS != 512 && _MAX_SS != 1024 && _MAX_SS != 2048 && _MAX_SS != 4096 +#error Wrong sector size. +#endif +#if _MAX_SS != 512 +#define SS(fs) ((fs)->ssize) /* Variable sector size */ +#else +#define SS(fs) 512U /* Fixed sector size */ +#endif + + +/* Reentrancy related */ +#if _FS_REENTRANT +#if _USE_LFN == 1 +#error Static LFN work area cannot be used at thread-safe configuration. +#endif +#define ENTER_FF(fs) { if (!lock_fs(fs)) return FR_TIMEOUT; } +#define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; } +#else +#define ENTER_FF(fs) +#define LEAVE_FF(fs, res) return res +#endif + +#define ABORT(fs, res) { fp->err = (BYTE)(res); LEAVE_FF(fs, res); } + + +/* File access control feature */ +#if _FS_LOCK +#if _FS_READONLY +#error _FS_LOCK must be 0 at read-only cfg. +#endif +typedef struct { + FATFS *fs; /* Object ID 1, volume (NULL:blank entry) */ + DWORD clu; /* Object ID 2, directory */ + WORD idx; /* Object ID 3, directory index */ + WORD ctr; /* Object open counter, 0:none, 0x01..0xFF:read mode open count, 0x100:write mode */ +} FILESEM; +#endif + + + +/* DBCS code ranges and SBCS extend character conversion table */ + +#if _CODE_PAGE == 932 /* Japanese Shift-JIS */ +#define _DF1S 0x81 /* DBC 1st byte range 1 start */ +#define _DF1E 0x9F /* DBC 1st byte range 1 end */ +#define _DF2S 0xE0 /* DBC 1st byte range 2 start */ +#define _DF2E 0xFC /* DBC 1st byte range 2 end */ +#define _DS1S 0x40 /* DBC 2nd byte range 1 start */ +#define _DS1E 0x7E /* DBC 2nd byte range 1 end */ +#define _DS2S 0x80 /* DBC 2nd byte range 2 start */ +#define _DS2E 0xFC /* DBC 2nd byte range 2 end */ + +#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0x80 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 949 /* Korean */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x41 +#define _DS1E 0x5A +#define _DS2S 0x61 +#define _DS2E 0x7A +#define _DS3S 0x81 +#define _DS3E 0xFE + +#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0xA1 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 437 /* U.S. (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 720 /* Arabic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 737 /* Greek (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \ + 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 775 /* Baltic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF} + +#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \ + 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \ + 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 857 /* Turkish (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 862 /* Hebrew (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 866 /* Russian (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF} + +#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1253 /* Greek (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \ + 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF} + +#elif _CODE_PAGE == 1254 /* Turkish (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1256 /* Arabic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1257 /* Baltic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F} + +#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */ +#if _USE_LFN +#error Cannot use LFN feature without valid code page. +#endif +#define _DF1S 0 + +#else +#error Unknown code page + +#endif + + +/* Character code support macros */ +#define IsUpper(c) (((c)>='A')&&((c)<='Z')) +#define IsLower(c) (((c)>='a')&&((c)<='z')) +#define IsDigit(c) (((c)>='0')&&((c)<='9')) + +#if _DF1S /* Code page is DBCS */ + +#ifdef _DF2S /* Two 1st byte areas */ +#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E)) +#else /* One 1st byte area */ +#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) +#endif + +#ifdef _DS3S /* Three 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E)) +#else /* Two 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E)) +#endif + +#else /* Code page is SBCS */ + +#define IsDBCS1(c) 0 +#define IsDBCS2(c) 0 + +#endif /* _DF1S */ + + +/* Name status flags */ +#define NS 11 /* Index of name status byte in fn[] */ +#define NS_LOSS 0x01 /* Out of 8.3 format */ +#define NS_LFN 0x02 /* Force to create LFN entry */ +#define NS_LAST 0x04 /* Last segment */ +#define NS_BODY 0x08 /* Lower case flag (body) */ +#define NS_EXT 0x10 /* Lower case flag (ext) */ +#define NS_DOT 0x20 /* Dot entry */ + + +/* FAT sub-type boundaries */ +#define MIN_FAT16 4086U /* Minimum number of clusters for FAT16 */ +#define MIN_FAT32 65526U /* Minimum number of clusters for FAT32 */ + + +/* FatFs refers the members in the FAT structures as byte array instead of +/ structure member because the structure is not binary compatible between +/ different platforms */ + +#define BS_jmpBoot 0 /* Jump instruction (3) */ +#define BS_OEMName 3 /* OEM name (8) */ +#define BPB_BytsPerSec 11 /* Sector size [byte] (2) */ +#define BPB_SecPerClus 13 /* Cluster size [sector] (1) */ +#define BPB_RsvdSecCnt 14 /* Size of reserved area [sector] (2) */ +#define BPB_NumFATs 16 /* Number of FAT copies (1) */ +#define BPB_RootEntCnt 17 /* Number of root directory entries for FAT12/16 (2) */ +#define BPB_TotSec16 19 /* Volume size [sector] (2) */ +#define BPB_Media 21 /* Media descriptor (1) */ +#define BPB_FATSz16 22 /* FAT size [sector] (2) */ +#define BPB_SecPerTrk 24 /* Track size [sector] (2) */ +#define BPB_NumHeads 26 /* Number of heads (2) */ +#define BPB_HiddSec 28 /* Number of special hidden sectors (4) */ +#define BPB_TotSec32 32 /* Volume size [sector] (4) */ +#define BS_DrvNum 36 /* Physical drive number (2) */ +#define BS_BootSig 38 /* Extended boot signature (1) */ +#define BS_VolID 39 /* Volume serial number (4) */ +#define BS_VolLab 43 /* Volume label (8) */ +#define BS_FilSysType 54 /* File system type (1) */ +#define BPB_FATSz32 36 /* FAT size [sector] (4) */ +#define BPB_ExtFlags 40 /* Extended flags (2) */ +#define BPB_FSVer 42 /* File system version (2) */ +#define BPB_RootClus 44 /* Root directory first cluster (4) */ +#define BPB_FSInfo 48 /* Offset of FSINFO sector (2) */ +#define BPB_BkBootSec 50 /* Offset of backup boot sector (2) */ +#define BS_DrvNum32 64 /* Physical drive number (2) */ +#define BS_BootSig32 66 /* Extended boot signature (1) */ +#define BS_VolID32 67 /* Volume serial number (4) */ +#define BS_VolLab32 71 /* Volume label (8) */ +#define BS_FilSysType32 82 /* File system type (1) */ +#define FSI_LeadSig 0 /* FSI: Leading signature (4) */ +#define FSI_StrucSig 484 /* FSI: Structure signature (4) */ +#define FSI_Free_Count 488 /* FSI: Number of free clusters (4) */ +#define FSI_Nxt_Free 492 /* FSI: Last allocated cluster (4) */ +#define MBR_Table 446 /* MBR: Partition table offset (2) */ +#define SZ_PTE 16 /* MBR: Size of a partition table entry */ +#define BS_55AA 510 /* Boot sector signature (2) */ + +#define DIR_Name 0 /* Short file name (11) */ +#define DIR_Attr 11 /* Attribute (1) */ +#define DIR_NTres 12 /* NT flag (1) */ +#define DIR_CrtTimeTenth 13 /* Created time sub-second (1) */ +#define DIR_CrtTime 14 /* Created time (2) */ +#define DIR_CrtDate 16 /* Created date (2) */ +#define DIR_LstAccDate 18 /* Last accessed date (2) */ +#define DIR_FstClusHI 20 /* Higher 16-bit of first cluster (2) */ +#define DIR_WrtTime 22 /* Modified time (2) */ +#define DIR_WrtDate 24 /* Modified date (2) */ +#define DIR_FstClusLO 26 /* Lower 16-bit of first cluster (2) */ +#define DIR_FileSize 28 /* File size (4) */ +#define LDIR_Ord 0 /* LFN entry order and LLE flag (1) */ +#define LDIR_Attr 11 /* LFN attribute (1) */ +#define LDIR_Type 12 /* LFN type (1) */ +#define LDIR_Chksum 13 /* Sum of corresponding SFN entry */ +#define LDIR_FstClusLO 26 /* Filled by zero (0) */ +#define SZ_DIR 32 /* Size of a directory entry */ +#define LLE 0x40 /* Last long entry flag in LDIR_Ord */ +#define DDE 0xE5 /* Deleted directory entry mark in DIR_Name[0] */ +#define NDDE 0x05 /* Replacement of the character collides with DDE */ + + +/*------------------------------------------------------------*/ +/* Module private work area */ +/*------------------------------------------------------------*/ +/* Note that uninitialized variables with static duration are +/ zeroed/nulled at start-up. If not, the compiler or start-up +/ routine is out of ANSI-C standard. +*/ + +#if _VOLUMES +static +FATFS *FatFs[_VOLUMES]; /* Pointer to the file system objects (logical drives) */ +#else +#error Number of volumes must not be 0. +#endif + +static +WORD Fsid; /* File system mount ID */ + +#if _FS_RPATH && _VOLUMES >= 2 +static +BYTE CurrVol; /* Current drive */ +#endif + +#if _FS_LOCK +static +FILESEM Files[_FS_LOCK]; /* Open object lock semaphores */ +#endif + +#if _USE_LFN == 0 /* No LFN feature */ +#define DEF_NAMEBUF BYTE sfn[12] +#define INIT_BUF(dobj) (dobj).fn = sfn +#define FREE_BUF() + +#elif _USE_LFN == 1 /* LFN feature with static working buffer */ +static +WCHAR LfnBuf[_MAX_LFN+1]; +#define DEF_NAMEBUF BYTE sfn[12] +#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = LfnBuf; } +#define FREE_BUF() + +#elif _USE_LFN == 2 /* LFN feature with dynamic working buffer on the stack */ +#define DEF_NAMEBUF BYTE sfn[12]; WCHAR lbuf[_MAX_LFN+1] +#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = lbuf; } +#define FREE_BUF() + +#elif _USE_LFN == 3 /* LFN feature with dynamic working buffer on the heap */ +#define DEF_NAMEBUF BYTE sfn[12]; WCHAR *lfn +#define INIT_BUF(dobj) { lfn = ff_memalloc((_MAX_LFN + 1) * 2); \ + if (!lfn) LEAVE_FF((dobj).fs, FR_NOT_ENOUGH_CORE); \ + (dobj).lfn = lfn; (dobj).fn = sfn; } +#define FREE_BUF() ff_memfree(lfn) + +#else +#error Wrong LFN configuration. +#endif + + +#ifdef _EXCVT +static +const BYTE ExCvt[] = _EXCVT; /* Upper conversion table for extended characters */ +#endif + + + + + + +/*-------------------------------------------------------------------------- + + Module Private Functions + +---------------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------*/ +/* String functions */ +/*-----------------------------------------------------------------------*/ + +/* Copy memory to memory */ +static +void mem_cpy (void* dst, const void* src, UINT cnt) { + BYTE *d = (BYTE*)dst; + const BYTE *s = (const BYTE*)src; + +#if _WORD_ACCESS == 1 + while (cnt >= sizeof (int)) { + *(int*)d = *(int*)s; + d += sizeof (int); s += sizeof (int); + cnt -= sizeof (int); + } +#endif + while (cnt--) + *d++ = *s++; +} + +/* Fill memory */ +static +void mem_set (void* dst, int val, UINT cnt) { + BYTE *d = (BYTE*)dst; + + while (cnt--) + *d++ = (BYTE)val; +} + +/* Compare memory to memory */ +static +int mem_cmp (const void* dst, const void* src, UINT cnt) { + const BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src; + int r = 0; + + while (cnt-- && (r = *d++ - *s++) == 0) ; + return r; +} + +/* Check if chr is contained in the string */ +static +int chk_chr (const char* str, int chr) { + while (*str && *str != chr) str++; + return *str; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Request/Release grant to access the volume */ +/*-----------------------------------------------------------------------*/ +#if _FS_REENTRANT +static +int lock_fs ( + FATFS* fs /* File system object */ +) +{ + return ff_req_grant(fs->sobj); +} + + +static +void unlock_fs ( + FATFS* fs, /* File system object */ + FRESULT res /* Result code to be returned */ +) +{ + if (fs && + res != FR_NOT_ENABLED && + res != FR_INVALID_DRIVE && + res != FR_INVALID_OBJECT && + res != FR_TIMEOUT) { + ff_rel_grant(fs->sobj); + } +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* File lock control functions */ +/*-----------------------------------------------------------------------*/ +#if _FS_LOCK + +static +FRESULT chk_lock ( /* Check if the file can be accessed */ + DIR* dp, /* Directory object pointing the file to be checked */ + int acc /* Desired access (0:Read, 1:Write, 2:Delete/Rename) */ +) +{ + UINT i, be; + + /* Search file semaphore table */ + for (i = be = 0; i < _FS_LOCK; i++) { + if (Files[i].fs) { /* Existing entry */ + if (Files[i].fs == dp->fs && /* Check if the object matched with an open object */ + Files[i].clu == dp->sclust && + Files[i].idx == dp->index) break; + } else { /* Blank entry */ + be = 1; + } + } + if (i == _FS_LOCK) /* The object is not opened */ + return (be || acc == 2) ? FR_OK : FR_TOO_MANY_OPEN_FILES; /* Is there a blank entry for new object? */ + + /* The object has been opened. Reject any open against writing file and all write mode open */ + return (acc || Files[i].ctr == 0x100) ? FR_LOCKED : FR_OK; +} + + +static +int enq_lock (void) /* Check if an entry is available for a new object */ +{ + UINT i; + + for (i = 0; i < _FS_LOCK && Files[i].fs; i++) ; + return (i == _FS_LOCK) ? 0 : 1; +} + + +static +UINT inc_lock ( /* Increment object open counter and returns its index (0:Internal error) */ + DIR* dp, /* Directory object pointing the file to register or increment */ + int acc /* Desired access (0:Read, 1:Write, 2:Delete/Rename) */ +) +{ + UINT i; + + + for (i = 0; i < _FS_LOCK; i++) { /* Find the object */ + if (Files[i].fs == dp->fs && + Files[i].clu == dp->sclust && + Files[i].idx == dp->index) break; + } + + if (i == _FS_LOCK) { /* Not opened. Register it as new. */ + for (i = 0; i < _FS_LOCK && Files[i].fs; i++) ; + if (i == _FS_LOCK) return 0; /* No free entry to register (int err) */ + Files[i].fs = dp->fs; + Files[i].clu = dp->sclust; + Files[i].idx = dp->index; + Files[i].ctr = 0; + } + + if (acc && Files[i].ctr) return 0; /* Access violation (int err) */ + + Files[i].ctr = acc ? 0x100 : Files[i].ctr + 1; /* Set semaphore value */ + + return i + 1; +} + + +static +FRESULT dec_lock ( /* Decrement object open counter */ + UINT i /* Semaphore index (1..) */ +) +{ + WORD n; + FRESULT res; + + + if (--i < _FS_LOCK) { /* Shift index number origin from 0 */ + n = Files[i].ctr; + if (n == 0x100) n = 0; /* If write mode open, delete the entry */ + if (n) n--; /* Decrement read mode open count */ + Files[i].ctr = n; + if (!n) Files[i].fs = 0; /* Delete the entry if open count gets zero */ + res = FR_OK; + } else { + res = FR_INT_ERR; /* Invalid index nunber */ + } + return res; +} + + +static +void clear_lock ( /* Clear lock entries of the volume */ + FATFS *fs +) +{ + UINT i; + + for (i = 0; i < _FS_LOCK; i++) { + if (Files[i].fs == fs) Files[i].fs = 0; + } +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Move/Flush disk access window in the file system object */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT sync_window ( + FATFS* fs /* File system object */ +) +{ + DWORD wsect; + UINT nf; + + + if (fs->wflag) { /* Write back the sector if it is dirty */ + wsect = fs->winsect; /* Current sector number */ + if (disk_write(fs->drv, fs->win, wsect, 1)) + return FR_DISK_ERR; + fs->wflag = 0; + if (wsect - fs->fatbase < fs->fsize) { /* Is it in the FAT area? */ + for (nf = fs->n_fats; nf >= 2; nf--) { /* Reflect the change to all FAT copies */ + wsect += fs->fsize; + disk_write(fs->drv, fs->win, wsect, 1); + } + } + } + return FR_OK; +} +#endif + + +static +FRESULT move_window ( + FATFS* fs, /* File system object */ + DWORD sector /* Sector number to make appearance in the fs->win[] */ +) +{ + if (sector != fs->winsect) { /* Changed current window */ +#if !_FS_READONLY + if (sync_window(fs) != FR_OK) + return FR_DISK_ERR; +#endif + if (disk_read(fs->drv, fs->win, sector, 1)) + return FR_DISK_ERR; + fs->winsect = sector; + } + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Synchronize file system and strage device */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT sync_fs ( /* FR_OK: successful, FR_DISK_ERR: failed */ + FATFS* fs /* File system object */ +) +{ + FRESULT res; + + + res = sync_window(fs); + if (res == FR_OK) { + /* Update FSINFO sector if needed */ + if (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) { + /* Create FSINFO structure */ + mem_set(fs->win, 0, SS(fs)); + ST_WORD(fs->win+BS_55AA, 0xAA55); + ST_DWORD(fs->win+FSI_LeadSig, 0x41615252); + ST_DWORD(fs->win+FSI_StrucSig, 0x61417272); + ST_DWORD(fs->win+FSI_Free_Count, fs->free_clust); + ST_DWORD(fs->win+FSI_Nxt_Free, fs->last_clust); + /* Write it into the FSINFO sector */ + fs->winsect = fs->volbase + 1; + disk_write(fs->drv, fs->win, fs->winsect, 1); + fs->fsi_flag = 0; + } + /* Make sure that no pending write process in the physical drive */ + if (disk_ioctl(fs->drv, CTRL_SYNC, 0) != RES_OK) + res = FR_DISK_ERR; + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Get sector# from cluster# */ +/*-----------------------------------------------------------------------*/ + + +DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */ + FATFS* fs, /* File system object */ + DWORD clst /* Cluster# to be converted */ +) +{ + clst -= 2; + if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */ + return clst * fs->csize + fs->database; +} + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Read value of a FAT entry */ +/*-----------------------------------------------------------------------*/ + + +DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status */ + FATFS* fs, /* File system object */ + DWORD clst /* Cluster# to get the link information */ +) +{ + UINT wc, bc; + BYTE *p; + + + if (clst < 2 || clst >= fs->n_fatent) /* Check range */ + return 1; + + switch (fs->fs_type) { + case FS_FAT12 : + bc = (UINT)clst; bc += bc / 2; + if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break; + wc = fs->win[bc % SS(fs)]; bc++; + if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break; + wc |= fs->win[bc % SS(fs)] << 8; + return clst & 1 ? wc >> 4 : (wc & 0xFFF); + + case FS_FAT16 : + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break; + p = &fs->win[clst * 2 % SS(fs)]; + return LD_WORD(p); + + case FS_FAT32 : + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break; + p = &fs->win[clst * 4 % SS(fs)]; + return LD_DWORD(p) & 0x0FFFFFFF; + } + + return 0xFFFFFFFF; /* An error occurred at the disk I/O layer */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Change value of a FAT entry */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY + +FRESULT put_fat ( + FATFS* fs, /* File system object */ + DWORD clst, /* Cluster# to be changed in range of 2 to fs->n_fatent - 1 */ + DWORD val /* New value to mark the cluster */ +) +{ + UINT bc; + BYTE *p; + FRESULT res; + + + if (clst < 2 || clst >= fs->n_fatent) { /* Check range */ + res = FR_INT_ERR; + + } else { + switch (fs->fs_type) { + case FS_FAT12 : + bc = (UINT)clst; bc += bc / 2; + res = move_window(fs, fs->fatbase + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc % SS(fs)]; + *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val; + bc++; + fs->wflag = 1; + res = move_window(fs, fs->fatbase + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc % SS(fs)]; + *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F)); + break; + + case FS_FAT16 : + res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))); + if (res != FR_OK) break; + p = &fs->win[clst * 2 % SS(fs)]; + ST_WORD(p, (WORD)val); + break; + + case FS_FAT32 : + res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))); + if (res != FR_OK) break; + p = &fs->win[clst * 4 % SS(fs)]; + val |= LD_DWORD(p) & 0xF0000000; + ST_DWORD(p, val); + break; + + default : + res = FR_INT_ERR; + } + fs->wflag = 1; + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Remove a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT remove_chain ( + FATFS* fs, /* File system object */ + DWORD clst /* Cluster# to remove a chain from */ +) +{ + FRESULT res; + DWORD nxt; +#if _USE_ERASE + DWORD scl = clst, ecl = clst, rt[2]; +#endif + + if (clst < 2 || clst >= fs->n_fatent) { /* Check range */ + res = FR_INT_ERR; + + } else { + res = FR_OK; + while (clst < fs->n_fatent) { /* Not a last link? */ + nxt = get_fat(fs, clst); /* Get cluster status */ + if (nxt == 0) break; /* Empty cluster? */ + if (nxt == 1) { res = FR_INT_ERR; break; } /* Internal error? */ + if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } /* Disk error? */ + res = put_fat(fs, clst, 0); /* Mark the cluster "empty" */ + if (res != FR_OK) break; + if (fs->free_clust != 0xFFFFFFFF) { /* Update FSINFO */ + fs->free_clust++; + fs->fsi_flag |= 1; + } +#if _USE_ERASE + if (ecl + 1 == nxt) { /* Is next cluster contiguous? */ + ecl = nxt; + } else { /* End of contiguous clusters */ + rt[0] = clust2sect(fs, scl); /* Start sector */ + rt[1] = clust2sect(fs, ecl) + fs->csize - 1; /* End sector */ + disk_ioctl(fs->drv, CTRL_ERASE_SECTOR, rt); /* Erase the block */ + scl = ecl = nxt; + } +#endif + clst = nxt; /* Next cluster */ + } + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Stretch or Create a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */ + FATFS* fs, /* File system object */ + DWORD clst /* Cluster# to stretch. 0 means create a new chain. */ +) +{ + DWORD cs, ncl, scl; + FRESULT res; + + + if (clst == 0) { /* Create a new chain */ + scl = fs->last_clust; /* Get suggested start point */ + if (!scl || scl >= fs->n_fatent) scl = 1; + } + else { /* Stretch the current chain */ + cs = get_fat(fs, clst); /* Check the cluster status */ + if (cs < 2) return 1; /* It is an invalid cluster */ + if (cs < fs->n_fatent) return cs; /* It is already followed by next cluster */ + scl = clst; + } + + ncl = scl; /* Start cluster */ + for (;;) { + ncl++; /* Next cluster */ + if (ncl >= fs->n_fatent) { /* Wrap around */ + ncl = 2; + if (ncl > scl) return 0; /* No free cluster */ + } + cs = get_fat(fs, ncl); /* Get the cluster status */ + if (cs == 0) break; /* Found a free cluster */ + if (cs == 0xFFFFFFFF || cs == 1)/* An error occurred */ + return cs; + if (ncl == scl) return 0; /* No free cluster */ + } + + res = put_fat(fs, ncl, 0x0FFFFFFF); /* Mark the new cluster "last link" */ + if (res == FR_OK && clst != 0) { + res = put_fat(fs, clst, ncl); /* Link it to the previous one if needed */ + } + if (res == FR_OK) { + fs->last_clust = ncl; /* Update FSINFO */ + if (fs->free_clust != 0xFFFFFFFF) { + fs->free_clust--; + fs->fsi_flag |= 1; + } + } else { + ncl = (res == FR_DISK_ERR) ? 0xFFFFFFFF : 1; + } + + return ncl; /* Return new cluster number or error code */ +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Convert offset into cluster with link map table */ +/*-----------------------------------------------------------------------*/ + +#if _USE_FASTSEEK +static +DWORD clmt_clust ( /* <2:Error, >=2:Cluster number */ + FIL* fp, /* Pointer to the file object */ + DWORD ofs /* File offset to be converted to cluster# */ +) +{ + DWORD cl, ncl, *tbl; + + + tbl = fp->cltbl + 1; /* Top of CLMT */ + cl = ofs / SS(fp->fs) / fp->fs->csize; /* Cluster order from top of the file */ + for (;;) { + ncl = *tbl++; /* Number of cluters in the fragment */ + if (!ncl) return 0; /* End of table? (error) */ + if (cl < ncl) break; /* In this fragment? */ + cl -= ncl; tbl++; /* Next fragment */ + } + return cl + *tbl; /* Return the cluster number */ +} +#endif /* _USE_FASTSEEK */ + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Set directory index */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_sdi ( + DIR* dp, /* Pointer to directory object */ + WORD idx /* Index of directory table */ +) +{ + DWORD clst; + WORD ic; + + + dp->index = idx; + clst = dp->sclust; + if (clst == 1 || clst >= dp->fs->n_fatent) /* Check start cluster range */ + return FR_INT_ERR; + if (!clst && dp->fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */ + clst = dp->fs->dirbase; + + if (clst == 0) { /* Static table (root-directory in FAT12/16) */ + dp->clust = clst; + if (idx >= dp->fs->n_rootdir) /* Index is out of range */ + return FR_INT_ERR; + dp->sect = dp->fs->dirbase + idx / (SS(dp->fs) / SZ_DIR); /* Sector# */ + } + else { /* Dynamic table (sub-dirs or root-directory in FAT32) */ + ic = SS(dp->fs) / SZ_DIR * dp->fs->csize; /* Entries per cluster */ + while (idx >= ic) { /* Follow cluster chain */ + clst = get_fat(dp->fs, clst); /* Get next cluster */ + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ + if (clst < 2 || clst >= dp->fs->n_fatent) /* Reached to end of table or int error */ + return FR_INT_ERR; + idx -= ic; + } + dp->clust = clst; + dp->sect = clust2sect(dp->fs, clst) + idx / (SS(dp->fs) / SZ_DIR); /* Sector# */ + } + + dp->dir = dp->fs->win + (idx % (SS(dp->fs) / SZ_DIR)) * SZ_DIR; /* Ptr to the entry in the sector */ + + return FR_OK; /* Seek succeeded */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Move directory table index next */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:Could not stretch */ + DIR* dp, /* Pointer to the directory object */ + int stretch /* 0: Do not stretch table, 1: Stretch table if needed */ +) +{ + DWORD clst; + WORD i; + + + i = dp->index + 1; + if (!i || !dp->sect) /* Report EOT when index has reached 65535 */ + return FR_NO_FILE; + + if (!(i % (SS(dp->fs) / SZ_DIR))) { /* Sector changed? */ + dp->sect++; /* Next sector */ + + if (!dp->clust) { /* Static table */ + if (i >= dp->fs->n_rootdir) /* Report EOT if it reached end of static table */ + return FR_NO_FILE; + } + else { /* Dynamic table */ + if (((i / (SS(dp->fs) / SZ_DIR)) & (dp->fs->csize - 1)) == 0) { /* Cluster changed? */ + clst = get_fat(dp->fs, dp->clust); /* Get next cluster */ + if (clst <= 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + if (clst >= dp->fs->n_fatent) { /* If it reached end of dynamic table, */ +#if !_FS_READONLY + BYTE c; + if (!stretch) return FR_NO_FILE; /* If do not stretch, report EOT */ + clst = create_chain(dp->fs, dp->clust); /* Stretch cluster chain */ + if (clst == 0) return FR_DENIED; /* No free cluster */ + if (clst == 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + /* Clean-up stretched table */ + if (sync_window(dp->fs)) return FR_DISK_ERR;/* Flush disk access window */ + mem_set(dp->fs->win, 0, SS(dp->fs)); /* Clear window buffer */ + dp->fs->winsect = clust2sect(dp->fs, clst); /* Cluster start sector */ + for (c = 0; c < dp->fs->csize; c++) { /* Fill the new cluster with 0 */ + dp->fs->wflag = 1; + if (sync_window(dp->fs)) return FR_DISK_ERR; + dp->fs->winsect++; + } + dp->fs->winsect -= c; /* Rewind window offset */ +#else + if (!stretch) return FR_NO_FILE; /* If do not stretch, report EOT */ + return FR_NO_FILE; /* Report EOT */ +#endif + } + dp->clust = clst; /* Initialize data for new cluster */ + dp->sect = clust2sect(dp->fs, clst); + } + } + } + + dp->index = i; /* Current index */ + dp->dir = dp->fs->win + (i % (SS(dp->fs) / SZ_DIR)) * SZ_DIR; /* Current entry in the window */ + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Reserve directory entry */ +/*-----------------------------------------------------------------------*/ + +#if !_FS_READONLY +static +FRESULT dir_alloc ( + DIR* dp, /* Pointer to the directory object */ + UINT nent /* Number of contiguous entries to allocate (1-21) */ +) +{ + FRESULT res; + UINT n; + + + res = dir_sdi(dp, 0); + if (res == FR_OK) { + n = 0; + do { + res = move_window(dp->fs, dp->sect); + if (res != FR_OK) break; + if (dp->dir[0] == DDE || dp->dir[0] == 0) { /* Is it a blank entry? */ + if (++n == nent) break; /* A block of contiguous entries is found */ + } else { + n = 0; /* Not a blank entry. Restart to search */ + } + res = dir_next(dp, 1); /* Next entry with table stretch enabled */ + } while (res == FR_OK); + } + if (res == FR_NO_FILE) res = FR_DENIED; /* No directory entry to allocate */ + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Load/Store start cluster number */ +/*-----------------------------------------------------------------------*/ + +static +DWORD ld_clust ( + FATFS* fs, /* Pointer to the fs object */ + BYTE* dir /* Pointer to the directory entry */ +) +{ + DWORD cl; + + cl = LD_WORD(dir+DIR_FstClusLO); + if (fs->fs_type == FS_FAT32) + cl |= (DWORD)LD_WORD(dir+DIR_FstClusHI) << 16; + + return cl; +} + + +#if !_FS_READONLY +static +void st_clust ( + BYTE* dir, /* Pointer to the directory entry */ + DWORD cl /* Value to be set */ +) +{ + ST_WORD(dir+DIR_FstClusLO, cl); + ST_WORD(dir+DIR_FstClusHI, cl >> 16); +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* LFN handling - Test/Pick/Fit an LFN segment from/to directory entry */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; /* Offset of LFN characters in the directory entry */ + + +static +int cmp_lfn ( /* 1:Matched, 0:Not matched */ + WCHAR* lfnbuf, /* Pointer to the LFN to be compared */ + BYTE* dir /* Pointer to the directory entry containing a part of LFN */ +) +{ + UINT i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & ~LLE) - 1) * 13; /* Get offset in the LFN buffer */ + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last character has not been processed */ + wc = ff_wtoupper(uc); /* Convert it to upper case */ + if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++])) /* Compare it */ + return 0; /* Not matched */ + } else { + if (uc != 0xFFFF) return 0; /* Check filler */ + } + } while (++s < 13); /* Repeat until all characters in the entry are checked */ + + if ((dir[LDIR_Ord] & LLE) && wc && lfnbuf[i]) /* Last segment matched but different length */ + return 0; + + return 1; /* The part of LFN matched */ +} + + + +static +int pick_lfn ( /* 1:Succeeded, 0:Buffer overflow */ + WCHAR* lfnbuf, /* Pointer to the Unicode-LFN buffer */ + BYTE* dir /* Pointer to the directory entry */ +) +{ + UINT i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */ + + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last character has not been processed */ + if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ + lfnbuf[i++] = wc = uc; /* Store it */ + } else { + if (uc != 0xFFFF) return 0; /* Check filler */ + } + } while (++s < 13); /* Read all character in the entry */ + + if (dir[LDIR_Ord] & LLE) { /* Put terminator if it is the last LFN part */ + if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ + lfnbuf[i] = 0; + } + + return 1; +} + + +#if !_FS_READONLY +static +void fit_lfn ( + const WCHAR* lfnbuf, /* Pointer to the LFN buffer */ + BYTE* dir, /* Pointer to the directory entry */ + BYTE ord, /* LFN order (1-20) */ + BYTE sum /* SFN sum */ +) +{ + UINT i, s; + WCHAR wc; + + + dir[LDIR_Chksum] = sum; /* Set check sum */ + dir[LDIR_Attr] = AM_LFN; /* Set attribute. LFN entry */ + dir[LDIR_Type] = 0; + ST_WORD(dir+LDIR_FstClusLO, 0); + + i = (ord - 1) * 13; /* Get offset in the LFN buffer */ + s = wc = 0; + do { + if (wc != 0xFFFF) wc = lfnbuf[i++]; /* Get an effective character */ + ST_WORD(dir+LfnOfs[s], wc); /* Put it */ + if (!wc) wc = 0xFFFF; /* Padding characters following last character */ + } while (++s < 13); + if (wc == 0xFFFF || !lfnbuf[i]) ord |= LLE; /* Bottom LFN part is the start of LFN sequence */ + dir[LDIR_Ord] = ord; /* Set the LFN order */ +} + +#endif +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Create numbered name */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +void gen_numname ( + BYTE* dst, /* Pointer to generated SFN */ + const BYTE* src, /* Pointer to source SFN to be modified */ + const WCHAR* lfn, /* Pointer to LFN */ + WORD seq /* Sequence number */ +) +{ + BYTE ns[8], c; + UINT i, j; + + + mem_cpy(dst, src, 11); + + if (seq > 5) { /* On many collisions, generate a hash number instead of sequential number */ + do seq = (seq >> 1) + (seq << 15) + (WORD)*lfn++; while (*lfn); + } + + /* itoa (hexdecimal) */ + i = 7; + do { + c = (seq % 16) + '0'; + if (c > '9') c += 7; + ns[i--] = c; + seq /= 16; + } while (seq); + ns[i] = '~'; + + /* Append the number */ + for (j = 0; j < i && dst[j] != ' '; j++) { + if (IsDBCS1(dst[j])) { + if (j == i - 1) break; + j++; + } + } + do { + dst[j++] = (i < 8) ? ns[i++] : ' '; + } while (j < 8); +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Calculate sum of an SFN */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +BYTE sum_sfn ( + const BYTE* dir /* Pointer to the SFN entry */ +) +{ + BYTE sum = 0; + UINT n = 11; + + do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n); + return sum; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Find an object in the directory */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_find ( + DIR* dp /* Pointer to the directory object linked to the file name */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN + BYTE a, ord, sum; +#endif + + res = dir_sdi(dp, 0); /* Rewind directory object */ + if (res != FR_OK) return res; + +#if _USE_LFN + ord = sum = 0xFF; +#endif + do { + res = move_window(dp->fs, dp->sect); + if (res != FR_OK) break; + dir = dp->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ +#if _USE_LFN /* LFN configuration */ + a = dir[DIR_Attr] & AM_MASK; + if (c == DDE || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (dp->lfn) { + if (c & LLE) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= ~LLE; ord = c; /* LFN start order */ + dp->lfn_idx = dp->index; + } + /* Check validity of the LFN entry and compare it with given name */ + ord = (c == ord && sum == dir[LDIR_Chksum] && cmp_lfn(dp->lfn, dir)) ? ord - 1 : 0xFF; + } + } else { /* An SFN entry is found */ + if (!ord && sum == sum_sfn(dir)) break; /* LFN matched? */ + ord = 0xFF; dp->lfn_idx = 0xFFFF; /* Reset LFN sequence */ + if (!(dp->fn[NS] & NS_LOSS) && !mem_cmp(dir, dp->fn, 11)) break; /* SFN matched? */ + } + } +#else /* Non LFN configuration */ + if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dp->fn, 11)) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dp, 0); /* Next entry */ + } while (res == FR_OK); + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 || _USE_LABEL || _FS_RPATH >= 2 +static +FRESULT dir_read ( + DIR* dp, /* Pointer to the directory object */ + int vol /* Filtered by 0:file/directory or 1:volume label */ +) +{ + FRESULT res; + BYTE a, c, *dir; +#if _USE_LFN + BYTE ord = 0xFF, sum = 0xFF; +#endif + + res = FR_NO_FILE; + while (dp->sect) { + res = move_window(dp->fs, dp->sect); + if (res != FR_OK) break; + dir = dp->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ + a = dir[DIR_Attr] & AM_MASK; +#if _USE_LFN /* LFN configuration */ + if (c == DDE || (!_FS_RPATH && c == '.') || (int)(a == AM_VOL) != vol) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (c & LLE) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= ~LLE; ord = c; + dp->lfn_idx = dp->index; + } + /* Check LFN validity and capture it */ + ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dp->lfn, dir)) ? ord - 1 : 0xFF; + } else { /* An SFN entry is found */ + if (ord || sum != sum_sfn(dir)) /* Is there a valid LFN? */ + dp->lfn_idx = 0xFFFF; /* It has no LFN. */ + break; + } + } +#else /* Non LFN configuration */ + if (c != DDE && (_FS_RPATH || c != '.') && a != AM_LFN && (int)(a == AM_VOL) == vol) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dp, 0); /* Next entry */ + if (res != FR_OK) break; + } + + if (res != FR_OK) dp->sect = 0; + + return res; +} +#endif /* _FS_MINIMIZE <= 1 || _USE_LABEL || _FS_RPATH >= 2 */ + + + + +/*-----------------------------------------------------------------------*/ +/* Register an object to the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many SFN collision, FR_DISK_ERR:Disk error */ + DIR* dp /* Target directory with object name to be created */ +) +{ + FRESULT res; +#if _USE_LFN /* LFN configuration */ + WORD n, ne; + BYTE sn[12], *fn, sum; + WCHAR *lfn; + + + fn = dp->fn; lfn = dp->lfn; + mem_cpy(sn, fn, 12); + + if (_FS_RPATH && (sn[NS] & NS_DOT)) /* Cannot create dot entry */ + return FR_INVALID_NAME; + + if (sn[NS] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */ + fn[NS] = 0; dp->lfn = 0; /* Find only SFN */ + for (n = 1; n < 100; n++) { + gen_numname(fn, sn, lfn, n); /* Generate a numbered name */ + res = dir_find(dp); /* Check if the name collides with existing SFN */ + if (res != FR_OK) break; + } + if (n == 100) return FR_DENIED; /* Abort if too many collisions */ + if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */ + fn[NS] = sn[NS]; dp->lfn = lfn; + } + + if (sn[NS] & NS_LFN) { /* When LFN is to be created, allocate entries for an SFN + LFNs. */ + for (n = 0; lfn[n]; n++) ; + ne = (n + 25) / 13; + } else { /* Otherwise allocate an entry for an SFN */ + ne = 1; + } + res = dir_alloc(dp, ne); /* Allocate entries */ + + if (res == FR_OK && --ne) { /* Set LFN entry if needed */ + res = dir_sdi(dp, (WORD)(dp->index - ne)); + if (res == FR_OK) { + sum = sum_sfn(dp->fn); /* Sum value of the SFN tied to the LFN */ + do { /* Store LFN entries in bottom first */ + res = move_window(dp->fs, dp->sect); + if (res != FR_OK) break; + fit_lfn(dp->lfn, dp->dir, (BYTE)ne, sum); + dp->fs->wflag = 1; + res = dir_next(dp, 0); /* Next entry */ + } while (res == FR_OK && --ne); + } + } +#else /* Non LFN configuration */ + res = dir_alloc(dp, 1); /* Allocate an entry for SFN */ +#endif + + if (res == FR_OK) { /* Set SFN entry */ + res = move_window(dp->fs, dp->sect); + if (res == FR_OK) { + mem_set(dp->dir, 0, SZ_DIR); /* Clean the entry */ + mem_cpy(dp->dir, dp->fn, 11); /* Put SFN */ +#if _USE_LFN + dp->dir[DIR_NTres] = dp->fn[NS] & (NS_BODY | NS_EXT); /* Put NT flag */ +#endif + dp->fs->wflag = 1; + } + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Remove an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY && !_FS_MINIMIZE +static +FRESULT dir_remove ( /* FR_OK: Successful, FR_DISK_ERR: A disk error */ + DIR* dp /* Directory object pointing the entry to be removed */ +) +{ + FRESULT res; +#if _USE_LFN /* LFN configuration */ + WORD i; + + i = dp->index; /* SFN index */ + res = dir_sdi(dp, (WORD)((dp->lfn_idx == 0xFFFF) ? i : dp->lfn_idx)); /* Goto the SFN or top of the LFN entries */ + if (res == FR_OK) { + do { + res = move_window(dp->fs, dp->sect); + if (res != FR_OK) break; + *dp->dir = DDE; /* Mark the entry "deleted" */ + dp->fs->wflag = 1; + if (dp->index >= i) break; /* When reached SFN, all entries of the object has been deleted. */ + res = dir_next(dp, 0); /* Next entry */ + } while (res == FR_OK); + if (res == FR_NO_FILE) res = FR_INT_ERR; + } + +#else /* Non LFN configuration */ + res = dir_sdi(dp, dp->index); + if (res == FR_OK) { + res = move_window(dp->fs, dp->sect); + if (res == FR_OK) { + *dp->dir = DDE; /* Mark the entry "deleted" */ + dp->fs->wflag = 1; + } + } +#endif + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Pick a segment and create the object name in directory form */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT create_name ( + DIR* dp, /* Pointer to the directory object */ + const TCHAR** path /* Pointer to pointer to the segment in the path string */ +) +{ +#if _USE_LFN /* LFN configuration */ + BYTE b, cf; + WCHAR w, *lfn; + UINT i, ni, si, di; + const TCHAR *p; + + /* Create LFN in Unicode */ + for (p = *path; *p == '/' || *p == '\\'; p++) ; /* Strip duplicated separator */ + lfn = dp->lfn; + si = di = 0; + for (;;) { + w = p[si++]; /* Get a character */ + if (w < ' ' || w == '/' || w == '\\') break; /* Break on end of segment */ + if (di >= _MAX_LFN) /* Reject too long name */ + return FR_INVALID_NAME; +#if !_LFN_UNICODE + w &= 0xFF; + if (IsDBCS1(w)) { /* Check if it is a DBC 1st byte (always false on SBCS cfg) */ + b = (BYTE)p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(b)) + return FR_INVALID_NAME; /* Reject invalid sequence */ + w = (w << 8) + b; /* Create a DBC */ + } + w = ff_convert(w, 1); /* Convert ANSI/OEM to Unicode */ + if (!w) return FR_INVALID_NAME; /* Reject invalid code */ +#endif + if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject illegal characters for LFN */ + return FR_INVALID_NAME; + lfn[di++] = w; /* Store the Unicode character */ + } + *path = &p[si]; /* Return pointer to the next segment */ + cf = (w < ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ +#if _FS_RPATH + if ((di == 1 && lfn[di-1] == '.') || /* Is this a dot entry? */ + (di == 2 && lfn[di-1] == '.' && lfn[di-2] == '.')) { + lfn[di] = 0; + for (i = 0; i < 11; i++) + dp->fn[i] = (i < di) ? '.' : ' '; + dp->fn[i] = cf | NS_DOT; /* This is a dot entry */ + return FR_OK; + } +#endif + while (di) { /* Strip trailing spaces and dots */ + w = lfn[di-1]; + if (w != ' ' && w != '.') break; + di--; + } + if (!di) return FR_INVALID_NAME; /* Reject nul string */ + + lfn[di] = 0; /* LFN is created */ + + /* Create SFN in directory form */ + mem_set(dp->fn, ' ', 11); + for (si = 0; lfn[si] == ' ' || lfn[si] == '.'; si++) ; /* Strip leading spaces and dots */ + if (si) cf |= NS_LOSS | NS_LFN; + while (di && lfn[di - 1] != '.') di--; /* Find extension (di<=si: no extension) */ + + b = i = 0; ni = 8; + for (;;) { + w = lfn[si++]; /* Get an LFN character */ + if (!w) break; /* Break on end of the LFN */ + if (w == ' ' || (w == '.' && si != di)) { /* Remove spaces and dots */ + cf |= NS_LOSS | NS_LFN; continue; + } + + if (i >= ni || si == di) { /* Extension or end of SFN */ + if (ni == 11) { /* Long extension */ + cf |= NS_LOSS | NS_LFN; break; + } + if (si != di) cf |= NS_LOSS | NS_LFN; /* Out of 8.3 format */ + if (si > di) break; /* No extension */ + si = di; i = 8; ni = 11; /* Enter extension section */ + b <<= 2; continue; + } + + if (w >= 0x80) { /* Non ASCII character */ +#ifdef _EXCVT + w = ff_convert(w, 0); /* Unicode -> OEM code */ + if (w) w = ExCvt[w - 0x80]; /* Convert extended character to upper (SBCS) */ +#else + w = ff_convert(ff_wtoupper(w), 0); /* Upper converted Unicode -> OEM code */ +#endif + cf |= NS_LFN; /* Force create LFN entry */ + } + + if (_DF1S && w >= 0x100) { /* Double byte character (always false on SBCS cfg) */ + if (i >= ni - 1) { + cf |= NS_LOSS | NS_LFN; i = ni; continue; + } + dp->fn[i++] = (BYTE)(w >> 8); + } else { /* Single byte character */ + if (!w || chk_chr("+,;=[]", w)) { /* Replace illegal characters for SFN */ + w = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */ + } else { + if (IsUpper(w)) { /* ASCII large capital */ + b |= 2; + } else { + if (IsLower(w)) { /* ASCII small capital */ + b |= 1; w -= 0x20; + } + } + } + } + dp->fn[i++] = (BYTE)w; + } + + if (dp->fn[0] == DDE) dp->fn[0] = NDDE; /* If the first character collides with deleted mark, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) /* Create LFN entry when there are composite capitals */ + cf |= NS_LFN; + if (!(cf & NS_LFN)) { /* When LFN is in 8.3 format without extended character, NT flags are created */ + if ((b & 0x03) == 0x01) cf |= NS_EXT; /* NT flag (Extension has only small capital) */ + if ((b & 0x0C) == 0x04) cf |= NS_BODY; /* NT flag (Filename has only small capital) */ + } + + dp->fn[NS] = cf; /* SFN is created */ + + return FR_OK; + + +#else /* Non-LFN configuration */ + BYTE b, c, d, *sfn; + UINT ni, si, i; + const char *p; + + /* Create file name in directory form */ + for (p = *path; *p == '/' || *p == '\\'; p++) ; /* Strip duplicated separator */ + sfn = dp->fn; + mem_set(sfn, ' ', 11); + si = i = b = 0; ni = 8; +#if _FS_RPATH + if (p[si] == '.') { /* Is this a dot entry? */ + for (;;) { + c = (BYTE)p[si++]; + if (c != '.' || si >= 3) break; + sfn[i++] = c; + } + if (c != '/' && c != '\\' && c > ' ') return FR_INVALID_NAME; + *path = &p[si]; /* Return pointer to the next segment */ + sfn[NS] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of path */ + return FR_OK; + } +#endif + for (;;) { + c = (BYTE)p[si++]; + if (c <= ' ' || c == '/' || c == '\\') break; /* Break on end of segment */ + if (c == '.' || i >= ni) { + if (ni != 8 || c != '.') return FR_INVALID_NAME; + i = 8; ni = 11; + b <<= 2; continue; + } + if (c >= 0x80) { /* Extended character? */ + b |= 3; /* Eliminate NT flag */ +#ifdef _EXCVT + c = ExCvt[c - 0x80]; /* To upper extended characters (SBCS cfg) */ +#else +#if !_DF1S + return FR_INVALID_NAME; /* Reject extended characters (ASCII cfg) */ +#endif +#endif + } + if (IsDBCS1(c)) { /* Check if it is a DBC 1st byte (always false on SBCS cfg) */ + d = (BYTE)p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(d) || i >= ni - 1) /* Reject invalid DBC */ + return FR_INVALID_NAME; + sfn[i++] = c; + sfn[i++] = d; + } else { /* Single byte code */ + if (chk_chr("\"*+,:;<=>\?[]|\x7F", c)) /* Reject illegal chrs for SFN */ + return FR_INVALID_NAME; + if (IsUpper(c)) { /* ASCII large capital? */ + b |= 2; + } else { + if (IsLower(c)) { /* ASCII small capital? */ + b |= 1; c -= 0x20; + } + } + sfn[i++] = c; + } + } + *path = &p[si]; /* Return pointer to the next segment */ + c = (c <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ + + if (!i) return FR_INVALID_NAME; /* Reject nul string */ + if (sfn[0] == DDE) sfn[0] = NDDE; /* When first character collides with DDE, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x03) == 0x01) c |= NS_EXT; /* NT flag (Name extension has only small capital) */ + if ((b & 0x0C) == 0x04) c |= NS_BODY; /* NT flag (Name body has only small capital) */ + + sfn[NS] = c; /* Store NT flag, File name is created */ + + return FR_OK; +#endif +} + + + + +/*-----------------------------------------------------------------------*/ +/* Get file information from directory entry */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 || _FS_RPATH >= 2 +static +void get_fileinfo ( /* No return code */ + DIR* dp, /* Pointer to the directory object */ + FILINFO* fno /* Pointer to the file information to be filled */ +) +{ + UINT i; + TCHAR *p, c; + + + p = fno->fname; + if (dp->sect) { /* Get SFN */ + BYTE *dir = dp->dir; + + i = 0; + while (i < 11) { /* Copy name body and extension */ + c = (TCHAR)dir[i++]; + if (c == ' ') continue; /* Skip padding spaces */ + if (c == NDDE) c = (TCHAR)DDE; /* Restore replaced DDE character */ + if (i == 9) *p++ = '.'; /* Insert a . if extension is exist */ +#if _USE_LFN + if (IsUpper(c) && (dir[DIR_NTres] & (i >= 9 ? NS_EXT : NS_BODY))) + c += 0x20; /* To lower */ +#if _LFN_UNICODE + if (IsDBCS1(c) && i != 8 && i != 11 && IsDBCS2(dir[i])) + c = c << 8 | dir[i++]; + c = ff_convert(c, 1); /* OEM -> Unicode */ + if (!c) c = '?'; +#endif +#endif + *p++ = c; + } + fno->fattrib = dir[DIR_Attr]; /* Attribute */ + fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */ + fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */ + fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */ + } + *p = 0; /* Terminate SFN string by a \0 */ + +#if _USE_LFN + if (fno->lfname) { + WCHAR w, *lfn; + + i = 0; p = fno->lfname; + if (dp->sect && fno->lfsize && dp->lfn_idx != 0xFFFF) { /* Get LFN if available */ + lfn = dp->lfn; + while ((w = *lfn++) != 0) { /* Get an LFN character */ +#if !_LFN_UNICODE + w = ff_convert(w, 0); /* Unicode -> OEM */ + if (!w) { i = 0; break; } /* No LFN if it could not be converted */ + if (_DF1S && w >= 0x100) /* Put 1st byte if it is a DBC (always false on SBCS cfg) */ + p[i++] = (TCHAR)(w >> 8); +#endif + if (i >= fno->lfsize - 1) { i = 0; break; } /* No LFN if buffer overflow */ + p[i++] = (TCHAR)w; + } + } + p[i] = 0; /* Terminate LFN string by a \0 */ + } +#endif +} +#endif /* _FS_MINIMIZE <= 1 || _FS_RPATH >= 2*/ + + + + +/*-----------------------------------------------------------------------*/ +/* Get logical drive number from path name */ +/*-----------------------------------------------------------------------*/ + +static +int get_ldnumber ( /* Returns logical drive number (-1:invalid drive) */ + const TCHAR** path /* Pointer to pointer to the path name */ +) +{ + int vol = -1; + + + if (*path) { + vol = (*path)[0] - '0'; + if ((UINT)vol < 9 && (*path)[1] == ':') { /* There is a drive number */ + *path += 2; /* Get value and strip it */ + if (vol >= _VOLUMES) vol = -1; /* Check if the drive number is valid */ + } else { /* No drive number use default drive */ +#if _FS_RPATH && _VOLUMES >= 2 + vol = CurrVol; /* Current drive */ +#else + vol = 0; /* Drive 0 */ +#endif + } + } + + return vol; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Follow a file path */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ + DIR* dp, /* Directory object to return last directory and found object */ + const TCHAR* path /* Full-path string to find a file or directory */ +) +{ + FRESULT res; + BYTE *dir, ns; + + +#if _FS_RPATH + if (*path == '/' || *path == '\\') { /* There is a heading separator */ + path++; dp->sclust = 0; /* Strip it and start from the root directory */ + } else { /* No heading separator */ + dp->sclust = dp->fs->cdir; /* Start from the current directory */ + } +#else + if (*path == '/' || *path == '\\') /* Strip heading separator if exist */ + path++; + dp->sclust = 0; /* Always start from the root directory */ +#endif + + if ((UINT)*path < ' ') { /* Null path name is the origin directory itself */ + res = dir_sdi(dp, 0); + dp->dir = 0; + } else { /* Follow path */ + for (;;) { + res = create_name(dp, &path); /* Get a segment name of the path */ + if (res != FR_OK) break; + res = dir_find(dp); /* Find an object with the sagment name */ + ns = dp->fn[NS]; + if (res != FR_OK) { /* Failed to find the object */ + if (res == FR_NO_FILE) { /* Object is not found */ + if (_FS_RPATH && (ns & NS_DOT)) { /* If dot entry is not exist, */ + dp->sclust = 0; dp->dir = 0; /* it is the root directory and stay there */ + if (!(ns & NS_LAST)) continue; /* Continue to follow if not last segment */ + res = FR_OK; /* Ended at the root directroy. Function completed. */ + } else { /* Could not find the object */ + if (!(ns & NS_LAST)) res = FR_NO_PATH; /* Adjust error code if not last segment */ + } + } + break; + } + if (ns & NS_LAST) break; /* Last segment matched. Function completed. */ + dir = dp->dir; /* Follow the sub-directory */ + if (!(dir[DIR_Attr] & AM_DIR)) { /* It is not a sub-directory and cannot follow */ + res = FR_NO_PATH; break; + } + dp->sclust = ld_clust(dp->fs, dir); + } + } + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Load a sector and check if it is an FAT boot sector */ +/*-----------------------------------------------------------------------*/ + +static +BYTE check_fs ( /* 0:FAT boor sector, 1:Valid boor sector but not FAT, 2:Not a boot sector, 3:Disk error */ + FATFS* fs, /* File system object */ + DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */ +) +{ + fs->wflag = 0; fs->winsect = 0xFFFFFFFF; /* Invaidate window */ + if (move_window(fs, sect) != FR_OK) /* Load boot record */ + return 3; + + if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55) /* Check boot record signature (always placed at offset 510 even if the sector size is >512) */ + return 2; + + if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146) /* Check "FAT" string */ + return 0; + if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146) /* Check "FAT" string */ + return 0; + + return 1; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Find logical drive and check if the volume is mounted */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ + FATFS** rfs, /* Pointer to pointer to the found file system object */ + const TCHAR** path, /* Pointer to pointer to the path name (drive number) */ + BYTE wmode /* !=0: Check write protection for write access */ +) +{ + BYTE fmt; + int vol; + DSTATUS stat; + DWORD bsect, fasize, tsect, sysect, nclst, szbfat; + WORD nrsv; + FATFS *fs; + + + /* Get logical drive number from the path name */ + *rfs = 0; + vol = get_ldnumber(path); + if (vol < 0) return FR_INVALID_DRIVE; + + /* Check if the file system object is valid or not */ + fs = FatFs[vol]; /* Get pointer to the file system object */ + if (!fs) return FR_NOT_ENABLED; /* Is the file system object available? */ + + ENTER_FF(fs); /* Lock the volume */ + *rfs = fs; /* Return pointer to the file system object */ + + if (fs->fs_type) { /* If the volume has been mounted */ + stat = disk_status(fs->drv); + if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized */ + if (!_FS_READONLY && wmode && (stat & STA_PROTECT)) /* Check write protection if needed */ + return FR_WRITE_PROTECTED; + return FR_OK; /* The file system object is valid */ + } + } + + /* The file system object is not valid. */ + /* Following code attempts to mount the volume. (analyze BPB and initialize the fs object) */ + + fs->fs_type = 0; /* Clear the file system object */ + fs->drv = LD2PD(vol); /* Bind the logical drive and a physical drive */ + stat = disk_initialize(fs->drv); /* Initialize the physical drive */ + if (stat & STA_NOINIT) /* Check if the initialization succeeded */ + return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */ + if (!_FS_READONLY && wmode && (stat & STA_PROTECT)) /* Check disk write protection if needed */ + return FR_WRITE_PROTECTED; +#if _MAX_SS != 512 /* Get sector size (variable sector size cfg only) */ + if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &fs->ssize) != RES_OK) + return FR_DISK_ERR; +#endif + /* Find an FAT partition on the drive. Supports only generic partitioning, FDISK and SFD. */ + bsect = 0; + fmt = check_fs(fs, bsect); /* Load sector 0 and check if it is an FAT boot sector as SFD */ + if (fmt == 1 || (!fmt && (LD2PT(vol)))) { /* Not an FAT boot sector or forced partition number */ + UINT i; + DWORD br[4]; + + for (i = 0; i < 4; i++) { /* Get partition offset */ + BYTE *pt = fs->win+MBR_Table + i * SZ_PTE; + br[i] = pt[4] ? LD_DWORD(&pt[8]) : 0; + } + i = LD2PT(vol); /* Partition number: 0:auto, 1-4:forced */ + if (i) i--; + do { /* Find an FAT volume */ + bsect = br[i]; + fmt = bsect ? check_fs(fs, bsect) : 2; /* Check the partition */ + } while (!LD2PT(vol) && fmt && ++i < 4); + } + if (fmt == 3) return FR_DISK_ERR; /* An error occured in the disk I/O layer */ + if (fmt) return FR_NO_FILESYSTEM; /* No FAT volume is found */ + + /* An FAT volume is found. Following code initializes the file system object */ + + if (LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs)) /* (BPB_BytsPerSec must be equal to the physical sector size) */ + return FR_NO_FILESYSTEM; + + fasize = LD_WORD(fs->win+BPB_FATSz16); /* Number of sectors per FAT */ + if (!fasize) fasize = LD_DWORD(fs->win+BPB_FATSz32); + fs->fsize = fasize; + + fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FAT copies */ + if (fs->n_fats != 1 && fs->n_fats != 2) /* (Must be 1 or 2) */ + return FR_NO_FILESYSTEM; + fasize *= fs->n_fats; /* Number of sectors for FAT area */ + + fs->csize = fs->win[BPB_SecPerClus]; /* Number of sectors per cluster */ + if (!fs->csize || (fs->csize & (fs->csize - 1))) /* (Must be power of 2) */ + return FR_NO_FILESYSTEM; + + fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt); /* Number of root directory entries */ + if (fs->n_rootdir % (SS(fs) / SZ_DIR)) /* (Must be sector aligned) */ + return FR_NO_FILESYSTEM; + + tsect = LD_WORD(fs->win+BPB_TotSec16); /* Number of sectors on the volume */ + if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32); + + nrsv = LD_WORD(fs->win+BPB_RsvdSecCnt); /* Number of reserved sectors */ + if (!nrsv) return FR_NO_FILESYSTEM; /* (Must not be 0) */ + + /* Determine the FAT sub type */ + sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZ_DIR); /* RSV+FAT+DIR */ + if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + nclst = (tsect - sysect) / fs->csize; /* Number of clusters */ + if (!nclst) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + fmt = FS_FAT12; + if (nclst >= MIN_FAT16) fmt = FS_FAT16; + if (nclst >= MIN_FAT32) fmt = FS_FAT32; + + /* Boundaries and Limits */ + fs->n_fatent = nclst + 2; /* Number of FAT entries */ + fs->volbase = bsect; /* Volume start sector */ + fs->fatbase = bsect + nrsv; /* FAT start sector */ + fs->database = bsect + sysect; /* Data start sector */ + if (fmt == FS_FAT32) { + if (fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */ + fs->dirbase = LD_DWORD(fs->win+BPB_RootClus); /* Root directory start cluster */ + szbfat = fs->n_fatent * 4; /* (Required FAT size) */ + } else { + if (!fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */ + fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */ + szbfat = (fmt == FS_FAT16) ? /* (Required FAT size) */ + fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1); + } + if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) /* (BPB_FATSz must not be less than required) */ + return FR_NO_FILESYSTEM; + +#if !_FS_READONLY + /* Initialize cluster allocation information */ + fs->last_clust = fs->free_clust = 0xFFFFFFFF; + + /* Get fsinfo if available */ + fs->fsi_flag = 0x80; + if (fmt == FS_FAT32 /* Enable FSINFO only if FAT32 and BPB_FSInfo is 1 */ + && LD_WORD(fs->win+BPB_FSInfo) == 1 + && move_window(fs, bsect + 1) == FR_OK) + { + fs->fsi_flag = 0; + if (LD_WORD(fs->win+BS_55AA) == 0xAA55 /* Load FSINFO data if available */ + && LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 + && LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) + { +#if !_FS_NOFSINFO + fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count); +#endif + fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free); + } + } +#endif + fs->fs_type = fmt; /* FAT sub-type */ + fs->id = ++Fsid; /* File system mount ID */ +#if _FS_RPATH + fs->cdir = 0; /* Current directory (root dir) */ +#endif +#if _FS_LOCK /* Clear file lock semaphores */ + clear_lock(fs); +#endif + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Check if the file/directory object is valid or not */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT validate ( /* FR_OK(0): The object is valid, !=0: Invalid */ + void* obj /* Pointer to the object FIL/DIR to check validity */ +) +{ + FIL *fil = (FIL*)obj; /* Assuming offset of .fs and .id in the FIL/DIR structure is identical */ + + + if (!fil || !fil->fs || !fil->fs->fs_type || fil->fs->id != fil->id) + return FR_INVALID_OBJECT; + + ENTER_FF(fil->fs); /* Lock file system */ + + if (disk_status(fil->fs->drv) & STA_NOINIT) + return FR_NOT_READY; + + return FR_OK; +} + + + + +/*-------------------------------------------------------------------------- + + Public Functions + +--------------------------------------------------------------------------*/ + + + +/*-----------------------------------------------------------------------*/ +/* Mount/Unmount a Logical Drive */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mount ( + FATFS* fs, /* Pointer to the file system object (NULL:unmount)*/ + const TCHAR* path, /* Logical drive number to be mounted/unmounted */ + BYTE opt /* 0:Do not mount (delayed mount), 1:Mount immediately */ +) +{ + FATFS *cfs; + int vol; + FRESULT res; + const TCHAR *rp = path; + + + vol = get_ldnumber(&rp); + if (vol < 0) return FR_INVALID_DRIVE; + cfs = FatFs[vol]; /* Pointer to fs object */ + + if (cfs) { +#if _FS_LOCK + clear_lock(cfs); +#endif +#if _FS_REENTRANT /* Discard sync object of the current volume */ + if (!ff_del_syncobj(cfs->sobj)) return FR_INT_ERR; +#endif + cfs->fs_type = 0; /* Clear old fs object */ + } + + if (fs) { + fs->fs_type = 0; /* Clear new fs object */ +#if _FS_REENTRANT /* Create sync object for the new volume */ + if (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR; +#endif + } + FatFs[vol] = fs; /* Register new fs object */ + + if (!fs || opt != 1) return FR_OK; /* Do not mount now, it will be mounted later */ + + res = find_volume(&fs, &path, 0); /* Force mounted the volume */ + LEAVE_FF(fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Open or Create a File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_open ( + FIL* fp, /* Pointer to the blank file object */ + const TCHAR* path, /* Pointer to the file name */ + BYTE mode /* Access mode and file open mode flags */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + if (!fp) return FR_INVALID_OBJECT; + fp->fs = 0; /* Clear file object */ + + /* Get logical drive number */ +#if !_FS_READONLY + mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW; + res = find_volume(&dj.fs, &path, (BYTE)(mode & ~FA_READ)); +#else + mode &= FA_READ; + res = find_volume(&dj.fs, &path, 0); +#endif + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + dir = dj.dir; +#if !_FS_READONLY /* R/W configuration */ + if (res == FR_OK) { + if (!dir) /* Default directory itself */ + res = FR_INVALID_NAME; +#if _FS_LOCK + else + res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0); +#endif + } + /* Create or Open a file */ + if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) { + DWORD dw, cl; + + if (res != FR_OK) { /* No file, create new */ + if (res == FR_NO_FILE) /* There is no file to open, create a new entry */ +#if _FS_LOCK + res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES; +#else + res = dir_register(&dj); +#endif + mode |= FA_CREATE_ALWAYS; /* File is created */ + dir = dj.dir; /* New entry */ + } + else { /* Any object is already existing */ + if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) { /* Cannot overwrite it (R/O or DIR) */ + res = FR_DENIED; + } else { + if (mode & FA_CREATE_NEW) /* Cannot create as new file */ + res = FR_EXIST; + } + } + if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */ + dw = get_fattime(); /* Created time */ + ST_DWORD(dir+DIR_CrtTime, dw); + dir[DIR_Attr] = 0; /* Reset attribute */ + ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */ + cl = ld_clust(dj.fs, dir); /* Get start cluster */ + st_clust(dir, 0); /* cluster = 0 */ + dj.fs->wflag = 1; + if (cl) { /* Remove the cluster chain if exist */ + dw = dj.fs->winsect; + res = remove_chain(dj.fs, cl); + if (res == FR_OK) { + dj.fs->last_clust = cl - 1; /* Reuse the cluster hole */ + res = move_window(dj.fs, dw); + } + } + } + } + else { /* Open an existing file */ + if (res == FR_OK) { /* Follow succeeded */ + if (dir[DIR_Attr] & AM_DIR) { /* It is a directory */ + res = FR_NO_FILE; + } else { + if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */ + res = FR_DENIED; + } + } + } + if (res == FR_OK) { + if (mode & FA_CREATE_ALWAYS) /* Set file change flag if created or overwritten */ + mode |= FA__WRITTEN; + fp->dir_sect = dj.fs->winsect; /* Pointer to the directory entry */ + fp->dir_ptr = dir; +#if _FS_LOCK + fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0); + if (!fp->lockid) res = FR_INT_ERR; +#endif + } + +#else /* R/O configuration */ + if (res == FR_OK) { /* Follow succeeded */ + dir = dj.dir; + if (!dir) { /* Current directory itself */ + res = FR_INVALID_NAME; + } else { + if (dir[DIR_Attr] & AM_DIR) /* It is a directory */ + res = FR_NO_FILE; + } + } +#endif + FREE_BUF(); + + if (res == FR_OK) { + fp->flag = mode; /* File access mode */ + fp->err = 0; /* Clear error flag */ + fp->sclust = ld_clust(dj.fs, dir); /* File start cluster */ + fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */ + fp->fptr = 0; /* File pointer */ + fp->dsect = 0; +#if _USE_FASTSEEK + fp->cltbl = 0; /* Normal seek mode */ +#endif + fp->fs = dj.fs; /* Validate file object */ + fp->id = fp->fs->id; + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_read ( + FIL* fp, /* Pointer to the file object */ + void* buff, /* Pointer to data buffer */ + UINT btr, /* Number of bytes to read */ + UINT* br /* Pointer to number of bytes read */ +) +{ + FRESULT res; + DWORD clst, sect, remain; + UINT rcnt, cc; + BYTE csect, *rbuff = (BYTE*)buff; + + + *br = 0; /* Clear read byte counter */ + + res = validate(fp); /* Check validity */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->err) /* Check error */ + LEAVE_FF(fp->fs, (FRESULT)fp->err); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + remain = fp->fsize - fp->fptr; + if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ + + for ( ; btr; /* Repeat until all data read */ + rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if (!csect) { /* On the cluster boundary? */ + if (fp->fptr == 0) { /* On the top of the file? */ + clst = fp->sclust; /* Follow from the origin */ + } else { /* Middle or end of the file */ +#if _USE_FASTSEEK + if (fp->cltbl) + clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ + else +#endif + clst = get_fat(fp->fs, fp->clust); /* Follow cluster chain on the FAT */ + } + if (clst < 2) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->clust = clst; /* Update current cluster */ + } + sect = clust2sect(fp->fs, fp->clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + cc = btr / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Read maximum contiguous sectors directly */ + if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - csect; + if (disk_read(fp->fs->drv, rbuff, sect, cc)) + ABORT(fp->fs, FR_DISK_ERR); +#if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */ +#if _FS_TINY + if (fp->fs->wflag && fp->fs->winsect - sect < cc) + mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs)); +#else + if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc) + mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs)); +#endif +#endif + rcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if !_FS_TINY + if (fp->dsect != sect) { /* Load data sector if not in cache */ +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1)) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drv, fp->buf, sect, 1)) /* Fill sector cache */ + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + } + rcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */ + if (rcnt > btr) rcnt = btr; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#else + mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#endif + } + + LEAVE_FF(fp->fs, FR_OK); +} + + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Write File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_write ( + FIL* fp, /* Pointer to the file object */ + const void *buff, /* Pointer to the data to be written */ + UINT btw, /* Number of bytes to write */ + UINT* bw /* Pointer to number of bytes written */ +) +{ + FRESULT res; + DWORD clst, sect; + UINT wcnt, cc; + const BYTE *wbuff = (const BYTE*)buff; + BYTE csect; + + + *bw = 0; /* Clear write byte counter */ + + res = validate(fp); /* Check validity */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->err) /* Check error */ + LEAVE_FF(fp->fs, (FRESULT)fp->err); + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + if (fp->fptr + btw < fp->fptr) btw = 0; /* File size cannot reach 4GB */ + + for ( ; btw; /* Repeat until all data written */ + wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if (!csect) { /* On the cluster boundary? */ + if (fp->fptr == 0) { /* On the top of the file? */ + clst = fp->sclust; /* Follow from the origin */ + if (clst == 0) /* When no cluster is allocated, */ + fp->sclust = clst = create_chain(fp->fs, 0); /* Create a new cluster chain */ + } else { /* Middle or end of the file */ +#if _USE_FASTSEEK + if (fp->cltbl) + clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ + else +#endif + clst = create_chain(fp->fs, fp->clust); /* Follow or stretch cluster chain on the FAT */ + } + if (clst == 0) break; /* Could not allocate a new cluster (disk full) */ + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->clust = clst; /* Update current cluster */ + } +#if _FS_TINY + if (fp->fs->winsect == fp->dsect && sync_window(fp->fs)) /* Write-back sector cache */ + ABORT(fp->fs, FR_DISK_ERR); +#else + if (fp->flag & FA__DIRTY) { /* Write-back sector cache */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1)) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + sect = clust2sect(fp->fs, fp->clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + cc = btw / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Write maximum contiguous sectors directly */ + if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - csect; + if (disk_write(fp->fs->drv, wbuff, sect, cc)) + ABORT(fp->fs, FR_DISK_ERR); +#if _FS_MINIMIZE <= 2 +#if _FS_TINY + if (fp->fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */ + mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->fs->wflag = 0; + } +#else + if (fp->dsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */ + mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->flag &= ~FA__DIRTY; + } +#endif +#endif + wcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if _FS_TINY + if (fp->fptr >= fp->fsize) { /* Avoid silly cache filling at growing edge */ + if (sync_window(fp->fs)) ABORT(fp->fs, FR_DISK_ERR); + fp->fs->winsect = sect; + } +#else + if (fp->dsect != sect) { /* Fill sector cache with file data */ + if (fp->fptr < fp->fsize && + disk_read(fp->fs->drv, fp->buf, sect, 1)) + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + } + wcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs));/* Put partial sector into file I/O buffer */ + if (wcnt > btw) wcnt = btw; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->fs->wflag = 1; +#else + mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->flag |= FA__DIRTY; +#endif + } + + if (fp->fptr > fp->fsize) fp->fsize = fp->fptr; /* Update file size if needed */ + fp->flag |= FA__WRITTEN; /* Set file change flag */ + + LEAVE_FF(fp->fs, FR_OK); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Synchronize the File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_sync ( + FIL* fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD tm; + BYTE *dir; + + + res = validate(fp); /* Check validity of the object */ + if (res == FR_OK) { + if (fp->flag & FA__WRITTEN) { /* Has the file been written? */ + /* Write-back dirty buffer */ +#if !_FS_TINY + if (fp->flag & FA__DIRTY) { + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1)) + LEAVE_FF(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + /* Update the directory entry */ + res = move_window(fp->fs, fp->dir_sect); + if (res == FR_OK) { + dir = fp->dir_ptr; + dir[DIR_Attr] |= AM_ARC; /* Set archive bit */ + ST_DWORD(dir+DIR_FileSize, fp->fsize); /* Update file size */ + st_clust(dir, fp->sclust); /* Update start cluster */ + tm = get_fattime(); /* Update updated time */ + ST_DWORD(dir+DIR_WrtTime, tm); + ST_WORD(dir+DIR_LstAccDate, 0); + fp->flag &= ~FA__WRITTEN; + fp->fs->wflag = 1; + res = sync_fs(fp->fs); + } + } + } + + LEAVE_FF(fp->fs, res); +} + +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Close File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_close ( + FIL *fp /* Pointer to the file object to be closed */ +) +{ + FRESULT res; + + +#if !_FS_READONLY + res = f_sync(fp); /* Flush cached data */ + if (res == FR_OK) +#endif + { + res = validate(fp); /* Lock volume */ + if (res == FR_OK) { +#if _FS_REENTRANT + FATFS *fs = fp->fs; +#endif +#if _FS_LOCK + res = dec_lock(fp->lockid); /* Decrement file open counter */ + if (res == FR_OK) +#endif + fp->fs = 0; /* Invalidate file object */ +#if _FS_REENTRANT + unlock_fs(fs, FR_OK); /* Unlock volume */ +#endif + } + } + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Current Directory or Current Drive, Get Current Directory */ +/*-----------------------------------------------------------------------*/ + +#if _FS_RPATH >= 1 +#if _VOLUMES >= 2 +FRESULT f_chdrive ( + const TCHAR* path /* Drive number */ +) +{ + int vol; + + + vol = get_ldnumber(&path); + if (vol < 0) return FR_INVALID_DRIVE; + + CurrVol = (BYTE)vol; + + return FR_OK; +} +#endif + + +FRESULT f_chdir ( + const TCHAR* path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + DEF_NAMEBUF; + + + /* Get logical drive number */ + res = find_volume(&dj.fs, &path, 0); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the path */ + FREE_BUF(); + if (res == FR_OK) { /* Follow completed */ + if (!dj.dir) { + dj.fs->cdir = dj.sclust; /* Start directory itself */ + } else { + if (dj.dir[DIR_Attr] & AM_DIR) /* Reached to the directory */ + dj.fs->cdir = ld_clust(dj.fs, dj.dir); + else + res = FR_NO_PATH; /* Reached but a file */ + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + + LEAVE_FF(dj.fs, res); +} + + +#if _FS_RPATH >= 2 +FRESULT f_getcwd ( + TCHAR* buff, /* Pointer to the directory path */ + UINT len /* Size of path */ +) +{ + FRESULT res; + DIR dj; + UINT i, n; + DWORD ccl; + TCHAR *tp; + FILINFO fno; + DEF_NAMEBUF; + + + *buff = 0; + /* Get logical drive number */ + res = find_volume(&dj.fs, (const TCHAR**)&buff, 0); /* Get current volume */ + if (res == FR_OK) { + INIT_BUF(dj); + i = len; /* Bottom of buffer (directory stack base) */ + dj.sclust = dj.fs->cdir; /* Start to follow upper directory from current directory */ + while ((ccl = dj.sclust) != 0) { /* Repeat while current directory is a sub-directory */ + res = dir_sdi(&dj, 1); /* Get parent directory */ + if (res != FR_OK) break; + res = dir_read(&dj, 0); + if (res != FR_OK) break; + dj.sclust = ld_clust(dj.fs, dj.dir); /* Goto parent directory */ + res = dir_sdi(&dj, 0); + if (res != FR_OK) break; + do { /* Find the entry links to the child directory */ + res = dir_read(&dj, 0); + if (res != FR_OK) break; + if (ccl == ld_clust(dj.fs, dj.dir)) break; /* Found the entry */ + res = dir_next(&dj, 0); + } while (res == FR_OK); + if (res == FR_NO_FILE) res = FR_INT_ERR;/* It cannot be 'not found'. */ + if (res != FR_OK) break; +#if _USE_LFN + fno.lfname = buff; + fno.lfsize = i; +#endif + get_fileinfo(&dj, &fno); /* Get the directory name and push it to the buffer */ + tp = fno.fname; +#if _USE_LFN + if (*buff) tp = buff; +#endif + for (n = 0; tp[n]; n++) ; + if (i < n + 3) { + res = FR_NOT_ENOUGH_CORE; break; + } + while (n) buff[--i] = tp[--n]; + buff[--i] = '/'; + } + tp = buff; + if (res == FR_OK) { +#if _VOLUMES >= 2 + *tp++ = '0' + CurrVol; /* Put drive number */ + *tp++ = ':'; +#endif + if (i == len) { /* Root-directory */ + *tp++ = '/'; + } else { /* Sub-directroy */ + do /* Add stacked path str */ + *tp++ = buff[i++]; + while (i < len); + } + } + *tp = 0; + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} +#endif /* _FS_RPATH >= 2 */ +#endif /* _FS_RPATH >= 1 */ + + + +#if _FS_MINIMIZE <= 2 +/*-----------------------------------------------------------------------*/ +/* Seek File R/W Pointer */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_lseek ( + FIL* fp, /* Pointer to the file object */ + DWORD ofs /* File pointer from top of file */ +) +{ + FRESULT res; + + + res = validate(fp); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->err) /* Check error */ + LEAVE_FF(fp->fs, (FRESULT)fp->err); + +#if _USE_FASTSEEK + if (fp->cltbl) { /* Fast seek */ + DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl; + + if (ofs == CREATE_LINKMAP) { /* Create CLMT */ + tbl = fp->cltbl; + tlen = *tbl++; ulen = 2; /* Given table size and required table size */ + cl = fp->sclust; /* Top of the chain */ + if (cl) { + do { + /* Get a fragment */ + tcl = cl; ncl = 0; ulen += 2; /* Top, length and used items */ + do { + pcl = cl; ncl++; + cl = get_fat(fp->fs, cl); + if (cl <= 1) ABORT(fp->fs, FR_INT_ERR); + if (cl == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + } while (cl == pcl + 1); + if (ulen <= tlen) { /* Store the length and top of the fragment */ + *tbl++ = ncl; *tbl++ = tcl; + } + } while (cl < fp->fs->n_fatent); /* Repeat until end of chain */ + } + *fp->cltbl = ulen; /* Number of items used */ + if (ulen <= tlen) + *tbl = 0; /* Terminate table */ + else + res = FR_NOT_ENOUGH_CORE; /* Given table size is smaller than required */ + + } else { /* Fast seek */ + if (ofs > fp->fsize) /* Clip offset at the file size */ + ofs = fp->fsize; + fp->fptr = ofs; /* Set file pointer */ + if (ofs) { + fp->clust = clmt_clust(fp, ofs - 1); + dsc = clust2sect(fp->fs, fp->clust); + if (!dsc) ABORT(fp->fs, FR_INT_ERR); + dsc += (ofs - 1) / SS(fp->fs) & (fp->fs->csize - 1); + if (fp->fptr % SS(fp->fs) && dsc != fp->dsect) { /* Refill sector cache if needed */ +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1)) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drv, fp->buf, dsc, 1)) /* Load current sector */ + ABORT(fp->fs, FR_DISK_ERR); +#endif + fp->dsect = dsc; + } + } + } + } else +#endif + + /* Normal Seek */ + { + DWORD clst, bcs, nsect, ifptr; + + if (ofs > fp->fsize /* In read-only mode, clip offset with the file size */ +#if !_FS_READONLY + && !(fp->flag & FA_WRITE) +#endif + ) ofs = fp->fsize; + + ifptr = fp->fptr; + fp->fptr = nsect = 0; + if (ofs) { + bcs = (DWORD)fp->fs->csize * SS(fp->fs); /* Cluster size (byte) */ + if (ifptr > 0 && + (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */ + fp->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */ + ofs -= fp->fptr; + clst = fp->clust; + } else { /* When seek to back cluster, */ + clst = fp->sclust; /* start from the first cluster */ +#if !_FS_READONLY + if (clst == 0) { /* If no cluster chain, create a new chain */ + clst = create_chain(fp->fs, 0); + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->sclust = clst; + } +#endif + fp->clust = clst; + } + if (clst != 0) { + while (ofs > bcs) { /* Cluster following loop */ +#if !_FS_READONLY + if (fp->flag & FA_WRITE) { /* Check if in write mode or not */ + clst = create_chain(fp->fs, clst); /* Force stretch if in write mode */ + if (clst == 0) { /* When disk gets full, clip file size */ + ofs = bcs; break; + } + } else +#endif + clst = get_fat(fp->fs, clst); /* Follow cluster chain if not in write mode */ + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + if (clst <= 1 || clst >= fp->fs->n_fatent) ABORT(fp->fs, FR_INT_ERR); + fp->clust = clst; + fp->fptr += bcs; + ofs -= bcs; + } + fp->fptr += ofs; + if (ofs % SS(fp->fs)) { + nsect = clust2sect(fp->fs, clst); /* Current sector */ + if (!nsect) ABORT(fp->fs, FR_INT_ERR); + nsect += ofs / SS(fp->fs); + } + } + } + if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) { /* Fill sector cache if needed */ +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1)) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drv, fp->buf, nsect, 1)) /* Fill sector cache */ + ABORT(fp->fs, FR_DISK_ERR); +#endif + fp->dsect = nsect; + } +#if !_FS_READONLY + if (fp->fptr > fp->fsize) { /* Set file change flag if the file size is extended */ + fp->fsize = fp->fptr; + fp->flag |= FA__WRITTEN; + } +#endif + } + + LEAVE_FF(fp->fs, res); +} + + + +#if _FS_MINIMIZE <= 1 +/*-----------------------------------------------------------------------*/ +/* Create a Directory Object */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_opendir ( + DIR* dp, /* Pointer to directory object to create */ + const TCHAR* path /* Pointer to the directory path */ +) +{ + FRESULT res; + FATFS* fs; + DEF_NAMEBUF; + + + if (!dp) return FR_INVALID_OBJECT; + + /* Get logical drive number */ + res = find_volume(&fs, &path, 0); + if (res == FR_OK) { + dp->fs = fs; + INIT_BUF(*dp); + res = follow_path(dp, path); /* Follow the path to the directory */ + FREE_BUF(); + if (res == FR_OK) { /* Follow completed */ + if (dp->dir) { /* It is not the origin directory itself */ + if (dp->dir[DIR_Attr] & AM_DIR) /* The object is a sub directory */ + dp->sclust = ld_clust(fs, dp->dir); + else /* The object is a file */ + res = FR_NO_PATH; + } + if (res == FR_OK) { + dp->id = fs->id; + res = dir_sdi(dp, 0); /* Rewind directory */ +#if _FS_LOCK + if (res == FR_OK) { + if (dp->sclust) { + dp->lockid = inc_lock(dp, 0); /* Lock the sub directory */ + if (!dp->lockid) + res = FR_TOO_MANY_OPEN_FILES; + } else { + dp->lockid = 0; /* Root directory need not to be locked */ + } + } +#endif + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + if (res != FR_OK) dp->fs = 0; /* Invalidate the directory object if function faild */ + + LEAVE_FF(fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Close Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_closedir ( + DIR *dp /* Pointer to the directory object to be closed */ +) +{ + FRESULT res; + + + res = validate(dp); + if (res == FR_OK) { +#if _FS_REENTRANT + FATFS *fs = dp->fs; +#endif +#if _FS_LOCK + if (dp->lockid) /* Decrement sub-directory open counter */ + res = dec_lock(dp->lockid); + if (res == FR_OK) +#endif + dp->fs = 0; /* Invalidate directory object */ +#if _FS_REENTRANT + unlock_fs(fs, FR_OK); /* Unlock volume */ +#endif + } + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read Directory Entries in Sequence */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_readdir ( + DIR* dp, /* Pointer to the open directory object */ + FILINFO* fno /* Pointer to file information to return */ +) +{ + FRESULT res; + DEF_NAMEBUF; + + + res = validate(dp); /* Check validity of the object */ + if (res == FR_OK) { + if (!fno) { + res = dir_sdi(dp, 0); /* Rewind the directory object */ + } else { + INIT_BUF(*dp); + res = dir_read(dp, 0); /* Read an item */ + if (res == FR_NO_FILE) { /* Reached end of directory */ + dp->sect = 0; + res = FR_OK; + } + if (res == FR_OK) { /* A valid entry is found */ + get_fileinfo(dp, fno); /* Get the object information */ + res = dir_next(dp, 0); /* Increment index for next */ + if (res == FR_NO_FILE) { + dp->sect = 0; + res = FR_OK; + } + } + FREE_BUF(); + } + } + + LEAVE_FF(dp->fs, res); +} + + + +#if _FS_MINIMIZE == 0 +/*-----------------------------------------------------------------------*/ +/* Get File Status */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_stat ( + const TCHAR* path, /* Pointer to the file path */ + FILINFO* fno /* Pointer to file information to return */ +) +{ + FRESULT res; + DIR dj; + DEF_NAMEBUF; + + + /* Get logical drive number */ + res = find_volume(&dj.fs, &path, 0); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) { /* Follow completed */ + if (dj.dir) { /* Found an object */ + if (fno) get_fileinfo(&dj, fno); + } else { /* It is root directory */ + res = FR_INVALID_NAME; + } + } + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Get Number of Free Clusters */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_getfree ( + const TCHAR* path, /* Path name of the logical drive number */ + DWORD* nclst, /* Pointer to a variable to return number of free clusters */ + FATFS** fatfs /* Pointer to return pointer to corresponding file system object */ +) +{ + FRESULT res; + FATFS *fs; + DWORD n, clst, sect, stat; + UINT i; + BYTE fat, *p; + + + /* Get logical drive number */ + res = find_volume(fatfs, &path, 0); + fs = *fatfs; + if (res == FR_OK) { + /* If free_clust is valid, return it without full cluster scan */ + if (fs->free_clust <= fs->n_fatent - 2) { + *nclst = fs->free_clust; + } else { + /* Get number of free clusters */ + fat = fs->fs_type; + n = 0; + if (fat == FS_FAT12) { + clst = 2; + do { + stat = get_fat(fs, clst); + if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } + if (stat == 1) { res = FR_INT_ERR; break; } + if (stat == 0) n++; + } while (++clst < fs->n_fatent); + } else { + clst = fs->n_fatent; + sect = fs->fatbase; + i = 0; p = 0; + do { + if (!i) { + res = move_window(fs, sect++); + if (res != FR_OK) break; + p = fs->win; + i = SS(fs); + } + if (fat == FS_FAT16) { + if (LD_WORD(p) == 0) n++; + p += 2; i -= 2; + } else { + if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) n++; + p += 4; i -= 4; + } + } while (--clst); + } + fs->free_clust = n; + fs->fsi_flag |= 1; + *nclst = n; + } + } + LEAVE_FF(fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Truncate File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_truncate ( + FIL* fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD ncl; + + + res = validate(fp); /* Check validity of the object */ + if (res == FR_OK) { + if (fp->err) { /* Check error */ + res = (FRESULT)fp->err; + } else { + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + res = FR_DENIED; + } + } + if (res == FR_OK) { + if (fp->fsize > fp->fptr) { + fp->fsize = fp->fptr; /* Set file size to current R/W point */ + fp->flag |= FA__WRITTEN; + if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */ + res = remove_chain(fp->fs, fp->sclust); + fp->sclust = 0; + } else { /* When truncate a part of the file, remove remaining clusters */ + ncl = get_fat(fp->fs, fp->clust); + res = FR_OK; + if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (ncl == 1) res = FR_INT_ERR; + if (res == FR_OK && ncl < fp->fs->n_fatent) { + res = put_fat(fp->fs, fp->clust, 0x0FFFFFFF); + if (res == FR_OK) res = remove_chain(fp->fs, ncl); + } + } +#if !_FS_TINY + if (res == FR_OK && (fp->flag & FA__DIRTY)) { + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1)) + res = FR_DISK_ERR; + else + fp->flag &= ~FA__DIRTY; + } +#endif + } + if (res != FR_OK) fp->err = (FRESULT)res; + } + + LEAVE_FF(fp->fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Delete a File or Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_unlink ( + const TCHAR* path /* Pointer to the file or directory path */ +) +{ + FRESULT res; + DIR dj, sdj; + BYTE *dir; + DWORD dclst; + DEF_NAMEBUF; + + + /* Get logical drive number */ + res = find_volume(&dj.fs, &path, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; /* Cannot remove dot entry */ +#if _FS_LOCK + if (res == FR_OK) res = chk_lock(&dj, 2); /* Cannot remove open file */ +#endif + if (res == FR_OK) { /* The object is accessible */ + dir = dj.dir; + if (!dir) { + res = FR_INVALID_NAME; /* Cannot remove the start directory */ + } else { + if (dir[DIR_Attr] & AM_RDO) + res = FR_DENIED; /* Cannot remove R/O object */ + } + dclst = ld_clust(dj.fs, dir); + if (res == FR_OK && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-dir? */ + if (dclst < 2) { + res = FR_INT_ERR; + } else { + mem_cpy(&sdj, &dj, sizeof (DIR)); /* Check if the sub-directory is empty or not */ + sdj.sclust = dclst; + res = dir_sdi(&sdj, 2); /* Exclude dot entries */ + if (res == FR_OK) { + res = dir_read(&sdj, 0); /* Read an item */ + if (res == FR_OK /* Not empty directory */ +#if _FS_RPATH + || dclst == dj.fs->cdir /* Current directory */ +#endif + ) res = FR_DENIED; + if (res == FR_NO_FILE) res = FR_OK; /* Empty */ + } + } + } + if (res == FR_OK) { + res = dir_remove(&dj); /* Remove the directory entry */ + if (res == FR_OK) { + if (dclst) /* Remove the cluster chain if exist */ + res = remove_chain(dj.fs, dclst); + if (res == FR_OK) res = sync_fs(dj.fs); + } + } + } + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Create a Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mkdir ( + const TCHAR* path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir, n; + DWORD dsc, dcl, pcl, tm = get_fattime(); + DEF_NAMEBUF; + + + /* Get logical drive number */ + res = find_volume(&dj.fs, &path, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) res = FR_EXIST; /* Any object with same name is already existing */ + if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_NO_FILE) { /* Can create a new directory */ + dcl = create_chain(dj.fs, 0); /* Allocate a cluster for the new directory table */ + res = FR_OK; + if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster */ + if (dcl == 1) res = FR_INT_ERR; + if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (res == FR_OK) /* Flush FAT */ + res = sync_window(dj.fs); + if (res == FR_OK) { /* Initialize the new directory table */ + dsc = clust2sect(dj.fs, dcl); + dir = dj.fs->win; + mem_set(dir, 0, SS(dj.fs)); + mem_set(dir+DIR_Name, ' ', 11); /* Create "." entry */ + dir[DIR_Name] = '.'; + dir[DIR_Attr] = AM_DIR; + ST_DWORD(dir+DIR_WrtTime, tm); + st_clust(dir, dcl); + mem_cpy(dir+SZ_DIR, dir, SZ_DIR); /* Create ".." entry */ + dir[SZ_DIR+1] = '.'; pcl = dj.sclust; + if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase) + pcl = 0; + st_clust(dir+SZ_DIR, pcl); + for (n = dj.fs->csize; n; n--) { /* Write dot entries and clear following sectors */ + dj.fs->winsect = dsc++; + dj.fs->wflag = 1; + res = sync_window(dj.fs); + if (res != FR_OK) break; + mem_set(dir, 0, SS(dj.fs)); + } + } + if (res == FR_OK) res = dir_register(&dj); /* Register the object to the directoy */ + if (res != FR_OK) { + remove_chain(dj.fs, dcl); /* Could not register, remove cluster chain */ + } else { + dir = dj.dir; + dir[DIR_Attr] = AM_DIR; /* Attribute */ + ST_DWORD(dir+DIR_WrtTime, tm); /* Created time */ + st_clust(dir, dcl); /* Table start cluster */ + dj.fs->wflag = 1; + res = sync_fs(dj.fs); + } + } + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Attribute */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_chmod ( + const TCHAR* path, /* Pointer to the file path */ + BYTE value, /* Attribute bits */ + BYTE mask /* Attribute mask to change */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + /* Get logical drive number */ + res = find_volume(&dj.fs, &path, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + FREE_BUF(); + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Is it a root directory? */ + res = FR_INVALID_NAME; + } else { /* File or sub directory */ + mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */ + dir[DIR_Attr] = (value & mask) | (dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */ + dj.fs->wflag = 1; + res = sync_fs(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Timestamp */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_utime ( + const TCHAR* path, /* Pointer to the file/directory name */ + const FILINFO* fno /* Pointer to the time stamp to be set */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + /* Get logical drive number */ + res = find_volume(&dj.fs, &path, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + FREE_BUF(); + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Root directory */ + res = FR_INVALID_NAME; + } else { /* File or sub-directory */ + ST_WORD(dir+DIR_WrtTime, fno->ftime); + ST_WORD(dir+DIR_WrtDate, fno->fdate); + dj.fs->wflag = 1; + res = sync_fs(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Rename File/Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_rename ( + const TCHAR* path_old, /* Pointer to the old name */ + const TCHAR* path_new /* Pointer to the new name */ +) +{ + FRESULT res; + DIR djo, djn; + BYTE buf[21], *dir; + DWORD dw; + DEF_NAMEBUF; + + + /* Get logical drive number of the source object */ + res = find_volume(&djo.fs, &path_old, 1); + if (res == FR_OK) { + djn.fs = djo.fs; + INIT_BUF(djo); + res = follow_path(&djo, path_old); /* Check old object */ + if (_FS_RPATH && res == FR_OK && (djo.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; +#if _FS_LOCK + if (res == FR_OK) res = chk_lock(&djo, 2); +#endif + if (res == FR_OK) { /* Old object is found */ + if (!djo.dir) { /* Is root dir? */ + res = FR_NO_FILE; + } else { + mem_cpy(buf, djo.dir+DIR_Attr, 21); /* Save the object information except for name */ + mem_cpy(&djn, &djo, sizeof (DIR)); /* Check new object */ + res = follow_path(&djn, path_new); + if (res == FR_OK) res = FR_EXIST; /* The new object name is already existing */ + if (res == FR_NO_FILE) { /* Is it a valid path and no name collision? */ +/* Start critical section that any interruption can cause a cross-link */ + res = dir_register(&djn); /* Register the new entry */ + if (res == FR_OK) { + dir = djn.dir; /* Copy object information except for name */ + mem_cpy(dir+13, buf+2, 19); + dir[DIR_Attr] = buf[0] | AM_ARC; + djo.fs->wflag = 1; + if (djo.sclust != djn.sclust && (dir[DIR_Attr] & AM_DIR)) { /* Update .. entry in the directory if needed */ + dw = clust2sect(djo.fs, ld_clust(djo.fs, dir)); + if (!dw) { + res = FR_INT_ERR; + } else { + res = move_window(djo.fs, dw); + dir = djo.fs->win+SZ_DIR; /* .. entry */ + if (res == FR_OK && dir[1] == '.') { + dw = (djo.fs->fs_type == FS_FAT32 && djn.sclust == djo.fs->dirbase) ? 0 : djn.sclust; + st_clust(dir, dw); + djo.fs->wflag = 1; + } + } + } + if (res == FR_OK) { + res = dir_remove(&djo); /* Remove old entry */ + if (res == FR_OK) + res = sync_fs(djo.fs); + } + } +/* End critical section */ + } + } + } + FREE_BUF(); + } + + LEAVE_FF(djo.fs, res); +} + +#endif /* !_FS_READONLY */ +#endif /* _FS_MINIMIZE == 0 */ +#endif /* _FS_MINIMIZE <= 1 */ +#endif /* _FS_MINIMIZE <= 2 */ + + + +#if _USE_LABEL +/*-----------------------------------------------------------------------*/ +/* Get volume label */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_getlabel ( + const TCHAR* path, /* Path name of the logical drive number */ + TCHAR* label, /* Pointer to a buffer to return the volume label */ + DWORD* sn /* Pointer to a variable to return the volume serial number */ +) +{ + FRESULT res; + DIR dj; + UINT i, j; + + + /* Get logical drive number */ + res = find_volume(&dj.fs, &path, 0); + + /* Get volume label */ + if (res == FR_OK && label) { + dj.sclust = 0; /* Open root directory */ + res = dir_sdi(&dj, 0); + if (res == FR_OK) { + res = dir_read(&dj, 1); /* Get an entry with AM_VOL */ + if (res == FR_OK) { /* A volume label is exist */ +#if _LFN_UNICODE + WCHAR w; + i = j = 0; + do { + w = (i < 11) ? dj.dir[i++] : ' '; + if (IsDBCS1(w) && i < 11 && IsDBCS2(dj.dir[i])) + w = w << 8 | dj.dir[i++]; + label[j++] = ff_convert(w, 1); /* OEM -> Unicode */ + } while (j < 11); +#else + mem_cpy(label, dj.dir, 11); +#endif + j = 11; + do { + label[j] = 0; + if (!j) break; + } while (label[--j] == ' '); + } + if (res == FR_NO_FILE) { /* No label, return nul string */ + label[0] = 0; + res = FR_OK; + } + } + } + + /* Get volume serial number */ + if (res == FR_OK && sn) { + res = move_window(dj.fs, dj.fs->volbase); + if (res == FR_OK) { + i = dj.fs->fs_type == FS_FAT32 ? BS_VolID32 : BS_VolID; + *sn = LD_DWORD(&dj.fs->win[i]); + } + } + + LEAVE_FF(dj.fs, res); +} + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Set volume label */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_setlabel ( + const TCHAR* label /* Pointer to the volume label to set */ +) +{ + FRESULT res; + DIR dj; + BYTE vn[11]; + UINT i, j, sl; + WCHAR w; + DWORD tm; + + + /* Get logical drive number */ + res = find_volume(&dj.fs, &label, 1); + if (res) LEAVE_FF(dj.fs, res); + + /* Create a volume label in directory form */ + vn[0] = 0; + for (sl = 0; label[sl]; sl++) ; /* Get name length */ + for ( ; sl && label[sl-1] == ' '; sl--) ; /* Remove trailing spaces */ + if (sl) { /* Create volume label in directory form */ + i = j = 0; + do { +#if _LFN_UNICODE + w = ff_convert(ff_wtoupper(label[i++]), 0); +#else + w = (BYTE)label[i++]; + if (IsDBCS1(w)) + w = (j < 10 && i < sl && IsDBCS2(label[i])) ? w << 8 | (BYTE)label[i++] : 0; +#if _USE_LFN + w = ff_convert(ff_wtoupper(ff_convert(w, 1)), 0); +#else + if (IsLower(w)) w -= 0x20; /* To upper ASCII characters */ +#ifdef _EXCVT + if (w >= 0x80) w = ExCvt[w - 0x80]; /* To upper extended characters (SBCS cfg) */ +#else + if (!_DF1S && w >= 0x80) w = 0; /* Reject extended characters (ASCII cfg) */ +#endif +#endif +#endif + if (!w || chk_chr("\"*+,.:;<=>\?[]|\x7F", w) || j >= (UINT)((w >= 0x100) ? 10 : 11)) /* Reject invalid characters for volume label */ + LEAVE_FF(dj.fs, FR_INVALID_NAME); + if (w >= 0x100) vn[j++] = (BYTE)(w >> 8); + vn[j++] = (BYTE)w; + } while (i < sl); + while (j < 11) vn[j++] = ' '; + } + + /* Set volume label */ + dj.sclust = 0; /* Open root directory */ + res = dir_sdi(&dj, 0); + if (res == FR_OK) { + res = dir_read(&dj, 1); /* Get an entry with AM_VOL */ + if (res == FR_OK) { /* A volume label is found */ + if (vn[0]) { + mem_cpy(dj.dir, vn, 11); /* Change the volume label name */ + tm = get_fattime(); + ST_DWORD(dj.dir+DIR_WrtTime, tm); + } else { + dj.dir[0] = DDE; /* Remove the volume label */ + } + dj.fs->wflag = 1; + res = sync_fs(dj.fs); + } else { /* No volume label is found or error */ + if (res == FR_NO_FILE) { + res = FR_OK; + if (vn[0]) { /* Create volume label as new */ + res = dir_alloc(&dj, 1); /* Allocate an entry for volume label */ + if (res == FR_OK) { + mem_set(dj.dir, 0, SZ_DIR); /* Set volume label */ + mem_cpy(dj.dir, vn, 11); + dj.dir[DIR_Attr] = AM_VOL; + tm = get_fattime(); + ST_DWORD(dj.dir+DIR_WrtTime, tm); + dj.fs->wflag = 1; + res = sync_fs(dj.fs); + } + } + } + } + } + + LEAVE_FF(dj.fs, res); +} + +#endif /* !_FS_READONLY */ +#endif /* _USE_LABEL */ + + + +/*-----------------------------------------------------------------------*/ +/* Forward data to the stream directly (available on only tiny cfg) */ +/*-----------------------------------------------------------------------*/ +#if _USE_FORWARD && _FS_TINY + +FRESULT f_forward ( + FIL* fp, /* Pointer to the file object */ + UINT (*func)(const BYTE*,UINT), /* Pointer to the streaming function */ + UINT btf, /* Number of bytes to forward */ + UINT* bf /* Pointer to number of bytes forwarded */ +) +{ + FRESULT res; + DWORD remain, clst, sect; + UINT rcnt; + BYTE csect; + + + *bf = 0; /* Clear transfer byte counter */ + + res = validate(fp); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->err) /* Check error */ + LEAVE_FF(fp->fs, (FRESULT)fp->err); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + + remain = fp->fsize - fp->fptr; + if (btf > remain) btf = (UINT)remain; /* Truncate btf by remaining bytes */ + + for ( ; btf && (*func)(0, 0); /* Repeat until all data transferred or stream becomes busy */ + fp->fptr += rcnt, *bf += rcnt, btf -= rcnt) { + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + if (!csect) { /* On the cluster boundary? */ + clst = (fp->fptr == 0) ? /* On the top of the file? */ + fp->sclust : get_fat(fp->fs, fp->clust); + if (clst <= 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->clust = clst; /* Update current cluster */ + } + } + sect = clust2sect(fp->fs, fp->clust); /* Get current data sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + if (move_window(fp->fs, sect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + fp->dsect = sect; + rcnt = SS(fp->fs) - (WORD)(fp->fptr % SS(fp->fs)); /* Forward data from sector window */ + if (rcnt > btf) rcnt = btf; + rcnt = (*func)(&fp->fs->win[(WORD)fp->fptr % SS(fp->fs)], rcnt); + if (!rcnt) ABORT(fp->fs, FR_INT_ERR); + } + + LEAVE_FF(fp->fs, FR_OK); +} +#endif /* _USE_FORWARD */ + + + +#if _USE_MKFS && !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Create File System on the Drive */ +/*-----------------------------------------------------------------------*/ +#define N_ROOTDIR 512 /* Number of root directory entries for FAT12/16 */ +#define N_FATS 1 /* Number of FAT copies (1 or 2) */ + + +FRESULT f_mkfs ( + const TCHAR* path, /* Logical drive number */ + BYTE sfd, /* Partitioning rule 0:FDISK, 1:SFD */ + UINT au /* Allocation unit [bytes] */ +) +{ + static const WORD vst[] = { 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 0}; + static const WORD cst[] = {32768, 16384, 8192, 4096, 2048, 16384, 8192, 4096, 2048, 1024, 512}; + int vol; + BYTE fmt, md, sys, *tbl, pdrv, part; + DWORD n_clst, vs, n, wsect; + UINT i; + DWORD b_vol, b_fat, b_dir, b_data; /* LBA */ + DWORD n_vol, n_rsv, n_fat, n_dir; /* Size */ + FATFS *fs; + DSTATUS stat; + + + /* Check mounted drive and clear work area */ + vol = get_ldnumber(&path); + if (vol < 0) return FR_INVALID_DRIVE; + if (sfd > 1) return FR_INVALID_PARAMETER; + if (au & (au - 1)) return FR_INVALID_PARAMETER; + fs = FatFs[vol]; + if (!fs) return FR_NOT_ENABLED; + fs->fs_type = 0; + pdrv = LD2PD(vol); /* Physical drive */ + part = LD2PT(vol); /* Partition (0:auto detect, 1-4:get from partition table)*/ + + /* Get disk statics */ + stat = disk_initialize(pdrv); + if (stat & STA_NOINIT) return FR_NOT_READY; + if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; +#if _MAX_SS != 512 /* Get disk sector size */ + if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS) + return FR_DISK_ERR; +#endif + if (_MULTI_PARTITION && part) { + /* Get partition information from partition table in the MBR */ + if (disk_read(pdrv, fs->win, 0, 1)) return FR_DISK_ERR; + if (LD_WORD(fs->win+BS_55AA) != 0xAA55) return FR_MKFS_ABORTED; + tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE]; + if (!tbl[4]) return FR_MKFS_ABORTED; /* No partition? */ + b_vol = LD_DWORD(tbl+8); /* Volume start sector */ + n_vol = LD_DWORD(tbl+12); /* Volume size */ + } else { + /* Create a partition in this function */ + if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 128) + return FR_DISK_ERR; + b_vol = (sfd) ? 0 : 63; /* Volume start sector */ + n_vol -= b_vol; /* Volume size */ + } + + if (!au) { /* AU auto selection */ + vs = n_vol / (2000 / (SS(fs) / 512)); + for (i = 0; vs < vst[i]; i++) ; + au = cst[i]; + } + au /= SS(fs); /* Number of sectors per cluster */ + if (au == 0) au = 1; + if (au > 128) au = 128; + + /* Pre-compute number of clusters and FAT sub-type */ + n_clst = n_vol / au; + fmt = FS_FAT12; + if (n_clst >= MIN_FAT16) fmt = FS_FAT16; + if (n_clst >= MIN_FAT32) fmt = FS_FAT32; + + /* Determine offset and size of FAT structure */ + if (fmt == FS_FAT32) { + n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs); + n_rsv = 32; + n_dir = 0; + } else { + n_fat = (fmt == FS_FAT12) ? (n_clst * 3 + 1) / 2 + 3 : (n_clst * 2) + 4; + n_fat = (n_fat + SS(fs) - 1) / SS(fs); + n_rsv = 1; + n_dir = (DWORD)N_ROOTDIR * SZ_DIR / SS(fs); + } + b_fat = b_vol + n_rsv; /* FAT area start sector */ + b_dir = b_fat + n_fat * N_FATS; /* Directory area start sector */ + b_data = b_dir + n_dir; /* Data area start sector */ + if (n_vol < b_data + au - b_vol) return FR_MKFS_ABORTED; /* Too small volume */ + + /* Align data start sector to erase block boundary (for flash memory media) */ + if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &n) != RES_OK || !n || n > 32768) n = 1; + n = (b_data + n - 1) & ~(n - 1); /* Next nearest erase block from current data start */ + n = (n - b_data) / N_FATS; + if (fmt == FS_FAT32) { /* FAT32: Move FAT offset */ + n_rsv += n; + b_fat += n; + } else { /* FAT12/16: Expand FAT size */ + n_fat += n; + } + + /* Determine number of clusters and final check of validity of the FAT sub-type */ + n_clst = (n_vol - n_rsv - n_fat * N_FATS - n_dir) / au; + if ( (fmt == FS_FAT16 && n_clst < MIN_FAT16) + || (fmt == FS_FAT32 && n_clst < MIN_FAT32)) + return FR_MKFS_ABORTED; + + /* Determine system ID in the partition table */ + if (fmt == FS_FAT32) { + sys = 0x0C; /* FAT32X */ + } else { + if (fmt == FS_FAT12 && n_vol < 0x10000) { + sys = 0x01; /* FAT12(<65536) */ + } else { + sys = (n_vol < 0x10000) ? 0x04 : 0x06; /* FAT16(<65536) : FAT12/16(>=65536) */ + } + } + + if (_MULTI_PARTITION && part) { + /* Update system ID in the partition table */ + tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE]; + tbl[4] = sys; + if (disk_write(pdrv, fs->win, 0, 1)) /* Write it to teh MBR */ + return FR_DISK_ERR; + md = 0xF8; + } else { + if (sfd) { /* No partition table (SFD) */ + md = 0xF0; + } else { /* Create partition table (FDISK) */ + mem_set(fs->win, 0, SS(fs)); + tbl = fs->win+MBR_Table; /* Create partition table for single partition in the drive */ + tbl[1] = 1; /* Partition start head */ + tbl[2] = 1; /* Partition start sector */ + tbl[3] = 0; /* Partition start cylinder */ + tbl[4] = sys; /* System type */ + tbl[5] = 254; /* Partition end head */ + n = (b_vol + n_vol) / 63 / 255; + tbl[6] = (BYTE)(n >> 2 | 63); /* Partition end sector */ + tbl[7] = (BYTE)n; /* End cylinder */ + ST_DWORD(tbl+8, 63); /* Partition start in LBA */ + ST_DWORD(tbl+12, n_vol); /* Partition size in LBA */ + ST_WORD(fs->win+BS_55AA, 0xAA55); /* MBR signature */ + if (disk_write(pdrv, fs->win, 0, 1)) /* Write it to the MBR */ + return FR_DISK_ERR; + md = 0xF8; + } + } + + /* Create BPB in the VBR */ + tbl = fs->win; /* Clear sector */ + mem_set(tbl, 0, SS(fs)); + mem_cpy(tbl, "\xEB\xFE\x90" "MSDOS5.0", 11);/* Boot jump code, OEM name */ + i = SS(fs); /* Sector size */ + ST_WORD(tbl+BPB_BytsPerSec, i); + tbl[BPB_SecPerClus] = (BYTE)au; /* Sectors per cluster */ + ST_WORD(tbl+BPB_RsvdSecCnt, n_rsv); /* Reserved sectors */ + tbl[BPB_NumFATs] = N_FATS; /* Number of FATs */ + i = (fmt == FS_FAT32) ? 0 : N_ROOTDIR; /* Number of root directory entries */ + ST_WORD(tbl+BPB_RootEntCnt, i); + if (n_vol < 0x10000) { /* Number of total sectors */ + ST_WORD(tbl+BPB_TotSec16, n_vol); + } else { + ST_DWORD(tbl+BPB_TotSec32, n_vol); + } + tbl[BPB_Media] = md; /* Media descriptor */ + ST_WORD(tbl+BPB_SecPerTrk, 63); /* Number of sectors per track */ + ST_WORD(tbl+BPB_NumHeads, 255); /* Number of heads */ + ST_DWORD(tbl+BPB_HiddSec, b_vol); /* Hidden sectors */ + n = get_fattime(); /* Use current time as VSN */ + if (fmt == FS_FAT32) { + ST_DWORD(tbl+BS_VolID32, n); /* VSN */ + ST_DWORD(tbl+BPB_FATSz32, n_fat); /* Number of sectors per FAT */ + ST_DWORD(tbl+BPB_RootClus, 2); /* Root directory start cluster (2) */ + ST_WORD(tbl+BPB_FSInfo, 1); /* FSINFO record offset (VBR+1) */ + ST_WORD(tbl+BPB_BkBootSec, 6); /* Backup boot record offset (VBR+6) */ + tbl[BS_DrvNum32] = 0x80; /* Drive number */ + tbl[BS_BootSig32] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab32, "NO NAME " "FAT32 ", 19); /* Volume label, FAT signature */ + } else { + ST_DWORD(tbl+BS_VolID, n); /* VSN */ + ST_WORD(tbl+BPB_FATSz16, n_fat); /* Number of sectors per FAT */ + tbl[BS_DrvNum] = 0x80; /* Drive number */ + tbl[BS_BootSig] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */ + } + ST_WORD(tbl+BS_55AA, 0xAA55); /* Signature (Offset is fixed here regardless of sector size) */ + if (disk_write(pdrv, tbl, b_vol, 1)) /* Write it to the VBR sector */ + return FR_DISK_ERR; + if (fmt == FS_FAT32) /* Write backup VBR if needed (VBR+6) */ + disk_write(pdrv, tbl, b_vol + 6, 1); + + /* Initialize FAT area */ + wsect = b_fat; + for (i = 0; i < N_FATS; i++) { /* Initialize each FAT copy */ + mem_set(tbl, 0, SS(fs)); /* 1st sector of the FAT */ + n = md; /* Media descriptor byte */ + if (fmt != FS_FAT32) { + n |= (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00; + ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT12/16) */ + } else { + n |= 0xFFFFFF00; + ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT32) */ + ST_DWORD(tbl+4, 0xFFFFFFFF); + ST_DWORD(tbl+8, 0x0FFFFFFF); /* Reserve cluster #2 for root directory */ + } + if (disk_write(pdrv, tbl, wsect++, 1)) + return FR_DISK_ERR; + mem_set(tbl, 0, SS(fs)); /* Fill following FAT entries with zero */ + for (n = 1; n < n_fat; n++) { /* This loop may take a time on FAT32 volume due to many single sector writes */ + if (disk_write(pdrv, tbl, wsect++, 1)) + return FR_DISK_ERR; + } + } + + /* Initialize root directory */ + i = (fmt == FS_FAT32) ? au : n_dir; + do { + if (disk_write(pdrv, tbl, wsect++, 1)) + return FR_DISK_ERR; + } while (--i); + +#if _USE_ERASE /* Erase data area if needed */ + { + DWORD eb[2]; + + eb[0] = wsect; eb[1] = wsect + (n_clst - ((fmt == FS_FAT32) ? 1 : 0)) * au - 1; + disk_ioctl(pdrv, CTRL_ERASE_SECTOR, eb); + } +#endif + + /* Create FSINFO if needed */ + if (fmt == FS_FAT32) { + ST_DWORD(tbl+FSI_LeadSig, 0x41615252); + ST_DWORD(tbl+FSI_StrucSig, 0x61417272); + ST_DWORD(tbl+FSI_Free_Count, n_clst - 1); /* Number of free clusters */ + ST_DWORD(tbl+FSI_Nxt_Free, 2); /* Last allocated cluster# */ + ST_WORD(tbl+BS_55AA, 0xAA55); + disk_write(pdrv, tbl, b_vol + 1, 1); /* Write original (VBR+1) */ + disk_write(pdrv, tbl, b_vol + 7, 1); /* Write backup (VBR+7) */ + } + + return (disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR; +} + + + +#if _MULTI_PARTITION +/*-----------------------------------------------------------------------*/ +/* Divide Physical Drive */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_fdisk ( + BYTE pdrv, /* Physical drive number */ + const DWORD szt[], /* Pointer to the size table for each partitions */ + void* work /* Pointer to the working buffer */ +) +{ + UINT i, n, sz_cyl, tot_cyl, b_cyl, e_cyl, p_cyl; + BYTE s_hd, e_hd, *p, *buf = (BYTE*)work; + DSTATUS stat; + DWORD sz_disk, sz_part, s_part; + + + stat = disk_initialize(pdrv); + if (stat & STA_NOINIT) return FR_NOT_READY; + if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; + if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_disk)) return FR_DISK_ERR; + + /* Determine CHS in the table regardless of the drive geometry */ + for (n = 16; n < 256 && sz_disk / n / 63 > 1024; n *= 2) ; + if (n == 256) n--; + e_hd = n - 1; + sz_cyl = 63 * n; + tot_cyl = sz_disk / sz_cyl; + + /* Create partition table */ + mem_set(buf, 0, _MAX_SS); + p = buf + MBR_Table; b_cyl = 0; + for (i = 0; i < 4; i++, p += SZ_PTE) { + p_cyl = (szt[i] <= 100U) ? (DWORD)tot_cyl * szt[i] / 100 : szt[i] / sz_cyl; + if (!p_cyl) continue; + s_part = (DWORD)sz_cyl * b_cyl; + sz_part = (DWORD)sz_cyl * p_cyl; + if (i == 0) { /* Exclude first track of cylinder 0 */ + s_hd = 1; + s_part += 63; sz_part -= 63; + } else { + s_hd = 0; + } + e_cyl = b_cyl + p_cyl - 1; + if (e_cyl >= tot_cyl) return FR_INVALID_PARAMETER; + + /* Set partition table */ + p[1] = s_hd; /* Start head */ + p[2] = (BYTE)((b_cyl >> 2) + 1); /* Start sector */ + p[3] = (BYTE)b_cyl; /* Start cylinder */ + p[4] = 0x06; /* System type (temporary setting) */ + p[5] = e_hd; /* End head */ + p[6] = (BYTE)((e_cyl >> 2) + 63); /* End sector */ + p[7] = (BYTE)e_cyl; /* End cylinder */ + ST_DWORD(p + 8, s_part); /* Start sector in LBA */ + ST_DWORD(p + 12, sz_part); /* Partition size */ + + /* Next partition */ + b_cyl += p_cyl; + } + ST_WORD(p, 0xAA55); + + /* Write it to the MBR */ + return (disk_write(pdrv, buf, 0, 1) || disk_ioctl(pdrv, CTRL_SYNC, 0)) ? FR_DISK_ERR : FR_OK; +} + + +#endif /* _MULTI_PARTITION */ +#endif /* _USE_MKFS && !_FS_READONLY */ + + + + +#if _USE_STRFUNC +/*-----------------------------------------------------------------------*/ +/* Get a string from the file */ +/*-----------------------------------------------------------------------*/ + +TCHAR* f_gets ( + TCHAR* buff, /* Pointer to the string buffer to read */ + int len, /* Size of string buffer (characters) */ + FIL* fp /* Pointer to the file object */ +) +{ + int n = 0; + TCHAR c, *p = buff; + BYTE s[2]; + UINT rc; + + + while (n < len - 1) { /* Read characters until buffer gets filled */ +#if _LFN_UNICODE +#if _STRF_ENCODE == 3 /* Read a character in UTF-8 */ + f_read(fp, s, 1, &rc); + if (rc != 1) break; + c = s[0]; + if (c >= 0x80) { + if (c < 0xC0) continue; /* Skip stray trailer */ + if (c < 0xE0) { /* Two-byte sequence */ + f_read(fp, s, 1, &rc); + if (rc != 1) break; + c = (c & 0x1F) << 6 | (s[0] & 0x3F); + if (c < 0x80) c = '?'; + } else { + if (c < 0xF0) { /* Three-byte sequence */ + f_read(fp, s, 2, &rc); + if (rc != 2) break; + c = c << 12 | (s[0] & 0x3F) << 6 | (s[1] & 0x3F); + if (c < 0x800) c = '?'; + } else { /* Reject four-byte sequence */ + c = '?'; + } + } + } +#elif _STRF_ENCODE == 2 /* Read a character in UTF-16BE */ + f_read(fp, s, 2, &rc); + if (rc != 2) break; + c = s[1] + (s[0] << 8); +#elif _STRF_ENCODE == 1 /* Read a character in UTF-16LE */ + f_read(fp, s, 2, &rc); + if (rc != 2) break; + c = s[0] + (s[1] << 8); +#else /* Read a character in ANSI/OEM */ + f_read(fp, s, 1, &rc); + if (rc != 1) break; + c = s[0]; + if (IsDBCS1(c)) { + f_read(fp, s, 1, &rc); + if (rc != 1) break; + c = (c << 8) + s[0]; + } + c = ff_convert(c, 1); /* OEM -> Unicode */ + if (!c) c = '?'; +#endif +#else /* Read a character without conversion */ + f_read(fp, s, 1, &rc); + if (rc != 1) break; + c = s[0]; +#endif + if (_USE_STRFUNC == 2 && c == '\r') continue; /* Strip '\r' */ + *p++ = c; + n++; + if (c == '\n') break; /* Break on EOL */ + } + *p = 0; + return n ? buff : 0; /* When no data read (eof or error), return with error. */ +} + + + +#if !_FS_READONLY +#include +/*-----------------------------------------------------------------------*/ +/* Put a character to the file */ +/*-----------------------------------------------------------------------*/ + +typedef struct { + FIL* fp; + int idx, nchr; + BYTE buf[64]; +} putbuff; + + +static +void putc_bfd ( + putbuff* pb, + TCHAR c +) +{ + UINT bw; + int i; + + + if (_USE_STRFUNC == 2 && c == '\n') /* LF -> CRLF conversion */ + putc_bfd(pb, '\r'); + + i = pb->idx; /* Buffer write index (-1:error) */ + if (i < 0) return; + +#if _LFN_UNICODE +#if _STRF_ENCODE == 3 /* Write a character in UTF-8 */ + if (c < 0x80) { /* 7-bit */ + pb->buf[i++] = (BYTE)c; + } else { + if (c < 0x800) { /* 11-bit */ + pb->buf[i++] = (BYTE)(0xC0 | c >> 6); + } else { /* 16-bit */ + pb->buf[i++] = (BYTE)(0xE0 | c >> 12); + pb->buf[i++] = (BYTE)(0x80 | (c >> 6 & 0x3F)); + } + pb->buf[i++] = (BYTE)(0x80 | (c & 0x3F)); + } +#elif _STRF_ENCODE == 2 /* Write a character in UTF-16BE */ + pb->buf[i++] = (BYTE)(c >> 8); + pb->buf[i++] = (BYTE)c; +#elif _STRF_ENCODE == 1 /* Write a character in UTF-16LE */ + pb->buf[i++] = (BYTE)c; + pb->buf[i++] = (BYTE)(c >> 8); +#else /* Write a character in ANSI/OEM */ + c = ff_convert(c, 0); /* Unicode -> OEM */ + if (!c) c = '?'; + if (c >= 0x100) + pb->buf[i++] = (BYTE)(c >> 8); + pb->buf[i++] = (BYTE)c; +#endif +#else /* Write a character without conversion */ + pb->buf[i++] = (BYTE)c; +#endif + + if (i >= (int)(sizeof pb->buf) - 3) { /* Write buffered characters to the file */ + f_write(pb->fp, pb->buf, (UINT)i, &bw); + i = (bw == (UINT)i) ? 0 : -1; + } + pb->idx = i; + pb->nchr++; +} + + + +int f_putc ( + TCHAR c, /* A character to be output */ + FIL* fp /* Pointer to the file object */ +) +{ + putbuff pb; + UINT nw; + + + pb.fp = fp; /* Initialize output buffer */ + pb.nchr = pb.idx = 0; + + putc_bfd(&pb, c); /* Put a character */ + + if ( pb.idx >= 0 /* Flush buffered characters to the file */ + && f_write(pb.fp, pb.buf, (UINT)pb.idx, &nw) == FR_OK + && (UINT)pb.idx == nw) return pb.nchr; + return EOF; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a string to the file */ +/*-----------------------------------------------------------------------*/ + +int f_puts ( + const TCHAR* str, /* Pointer to the string to be output */ + FIL* fp /* Pointer to the file object */ +) +{ + putbuff pb; + UINT nw; + + + pb.fp = fp; /* Initialize output buffer */ + pb.nchr = pb.idx = 0; + + while (*str) /* Put the string */ + putc_bfd(&pb, *str++); + + if ( pb.idx >= 0 /* Flush buffered characters to the file */ + && f_write(pb.fp, pb.buf, (UINT)pb.idx, &nw) == FR_OK + && (UINT)pb.idx == nw) return pb.nchr; + return EOF; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a formatted string to the file */ +/*-----------------------------------------------------------------------*/ + +int f_printf ( + FIL* fp, /* Pointer to the file object */ + const TCHAR* fmt, /* Pointer to the format string */ + ... /* Optional arguments... */ +) +{ + va_list arp; + BYTE f, r; + UINT nw, i, j, w; + DWORD v; + TCHAR c, d, s[16], *p; + putbuff pb; + + + pb.fp = fp; /* Initialize output buffer */ + pb.nchr = pb.idx = 0; + + va_start(arp, fmt); + + for (;;) { + c = *fmt++; + if (c == 0) break; /* End of string */ + if (c != '%') { /* Non escape character */ + putc_bfd(&pb, c); + continue; + } + w = f = 0; + c = *fmt++; + if (c == '0') { /* Flag: '0' padding */ + f = 1; c = *fmt++; + } else { + if (c == '-') { /* Flag: left justified */ + f = 2; c = *fmt++; + } + } + while (IsDigit(c)) { /* Precision */ + w = w * 10 + c - '0'; + c = *fmt++; + } + if (c == 'l' || c == 'L') { /* Prefix: Size is long int */ + f |= 4; c = *fmt++; + } + if (!c) break; + d = c; + if (IsLower(d)) d -= 0x20; + switch (d) { /* Type is... */ + case 'S' : /* String */ + p = va_arg(arp, TCHAR*); + for (j = 0; p[j]; j++) ; + if (!(f & 2)) { + while (j++ < w) putc_bfd(&pb, ' '); + } + while (*p) putc_bfd(&pb, *p++); + while (j++ < w) putc_bfd(&pb, ' '); + continue; + case 'C' : /* Character */ + putc_bfd(&pb, (TCHAR)va_arg(arp, int)); continue; + case 'B' : /* Binary */ + r = 2; break; + case 'O' : /* Octal */ + r = 8; break; + case 'D' : /* Signed decimal */ + case 'U' : /* Unsigned decimal */ + r = 10; break; + case 'X' : /* Hexdecimal */ + r = 16; break; + default: /* Unknown type (pass-through) */ + putc_bfd(&pb, c); continue; + } + + /* Get an argument and put it in numeral */ + v = (f & 4) ? (DWORD)va_arg(arp, long) : ((d == 'D') ? (DWORD)(long)va_arg(arp, int) : (DWORD)va_arg(arp, unsigned int)); + if (d == 'D' && (v & 0x80000000)) { + v = 0 - v; + f |= 8; + } + i = 0; + do { + d = (TCHAR)(v % r); v /= r; + if (d > 9) d += (c == 'x') ? 0x27 : 0x07; + s[i++] = d + '0'; + } while (v && i < sizeof s / sizeof s[0]); + if (f & 8) s[i++] = '-'; + j = i; d = (f & 1) ? '0' : ' '; + while (!(f & 2) && j++ < w) putc_bfd(&pb, d); + do putc_bfd(&pb, s[--i]); while (i); + while (j++ < w) putc_bfd(&pb, d); + } + + va_end(arp); + + if ( pb.idx >= 0 /* Flush buffered characters to the file */ + && f_write(pb.fp, pb.buf, (UINT)pb.idx, &nw) == FR_OK + && (UINT)pb.idx == nw) return pb.nchr; + return EOF; +} + +#endif /* !_FS_READONLY */ +#endif /* _USE_STRFUNC */ diff --git a/source/GenericDrivers/ff.h b/source/GenericDrivers/ff.h new file mode 100644 index 0000000..70cb299 --- /dev/null +++ b/source/GenericDrivers/ff.h @@ -0,0 +1,342 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module include file R0.10 (C)ChaN, 2013 +/----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following terms. +/ +/ Copyright (C) 2013, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/----------------------------------------------------------------------------*/ + +#ifndef _FATFS +#define _FATFS 80960 /* Revision ID */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "integer.h" /* Basic integer types */ +#include "ffconf.h" /* FatFs configuration options */ + +#if _FATFS != _FFCONF +#error Wrong configuration file (ffconf.h). +#endif + + + +/* Definitions of volume management */ + +#if _MULTI_PARTITION /* Multiple partition configuration */ +typedef struct { + BYTE pd; /* Physical drive number */ + BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */ +} PARTITION; +extern PARTITION VolToPart[]; /* Volume - Partition resolution table */ +#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */ +#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */ + +#else /* Single partition configuration */ +#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */ +#define LD2PT(vol) 0 /* Find first valid partition or in SFD */ + +#endif + + + +/* Type of path name strings on FatFs API */ + +#if _LFN_UNICODE /* Unicode string */ +#if !_USE_LFN +#error _LFN_UNICODE must be 0 in non-LFN cfg. +#endif +#ifndef _INC_TCHAR +typedef WCHAR TCHAR; +#define _T(x) L ## x +#define _TEXT(x) L ## x +#endif + +#else /* ANSI/OEM string */ +#ifndef _INC_TCHAR +typedef char TCHAR; +#define _T(x) x +#define _TEXT(x) x +#endif + +#endif + + + +/* File system object structure (FATFS) */ + +typedef struct { + BYTE fs_type; /* FAT sub-type (0:Not mounted) */ + BYTE drv; /* Physical drive number */ + BYTE csize; /* Sectors per cluster (1,2,4...128) */ + BYTE n_fats; /* Number of FAT copies (1 or 2) */ + BYTE wflag; /* win[] flag (b0:dirty) */ + BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */ + WORD id; /* File system mount ID */ + WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ +#if _MAX_SS != 512 + WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */ +#endif +#if _FS_REENTRANT + _SYNC_t sobj; /* Identifier of sync object */ +#endif +#if !_FS_READONLY + DWORD last_clust; /* Last allocated cluster */ + DWORD free_clust; /* Number of free clusters */ +#endif +#if _FS_RPATH + DWORD cdir; /* Current directory start cluster (0:root) */ +#endif + DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */ + DWORD fsize; /* Sectors per FAT */ + DWORD volbase; /* Volume start sector */ + DWORD fatbase; /* FAT start sector */ + DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */ + DWORD database; /* Data start sector */ + DWORD winsect; /* Current sector appearing in the win[] */ + BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ +} FATFS; + + + +/* File object structure (FIL) */ + +typedef struct { + FATFS* fs; /* Pointer to the related file system object (**do not change order**) */ + WORD id; /* Owner file system mount ID (**do not change order**) */ + BYTE flag; /* File status flags */ + BYTE err; /* Abort flag (error code) */ + DWORD fptr; /* File read/write pointer (Zeroed on file open) */ + DWORD fsize; /* File size */ + DWORD sclust; /* File data start cluster (0:no data cluster, always 0 when fsize is 0) */ + DWORD clust; /* Current cluster of fpter */ + DWORD dsect; /* Current data sector of fpter */ +#if !_FS_READONLY + DWORD dir_sect; /* Sector containing the directory entry */ + BYTE* dir_ptr; /* Pointer to the directory entry in the window */ +#endif +#if _USE_FASTSEEK + DWORD* cltbl; /* Pointer to the cluster link map table (Nulled on file open) */ +#endif +#if _FS_LOCK + UINT lockid; /* File lock ID (index of file semaphore table Files[]) */ +#endif +#if !_FS_TINY + BYTE buf[_MAX_SS]; /* File data read/write buffer */ +#endif +} FIL; + + + +/* Directory object structure (DIR) */ + +typedef struct { + FATFS* fs; /* Pointer to the owner file system object (**do not change order**) */ + WORD id; /* Owner file system mount ID (**do not change order**) */ + WORD index; /* Current read/write index number */ + DWORD sclust; /* Table start cluster (0:Root dir) */ + DWORD clust; /* Current cluster */ + DWORD sect; /* Current sector */ + BYTE* dir; /* Pointer to the current SFN entry in the win[] */ + BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */ +#if _FS_LOCK + UINT lockid; /* File lock ID (index of file semaphore table Files[]) */ +#endif +#if _USE_LFN + WCHAR* lfn; /* Pointer to the LFN working buffer */ + WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */ +#endif +} DIR; + + + +/* File status structure (FILINFO) */ + +typedef struct { + DWORD fsize; /* File size */ + WORD fdate; /* Last modified date */ + WORD ftime; /* Last modified time */ + BYTE fattrib; /* Attribute */ + TCHAR fname[13]; /* Short file name (8.3 format) */ +#if _USE_LFN + TCHAR* lfname; /* Pointer to the LFN buffer */ + UINT lfsize; /* Size of LFN buffer in TCHAR */ +#endif +} FILINFO; + + + +/* File function return code (FRESULT) */ + +typedef enum { + FR_OK = 0, /* (0) Succeeded */ + FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */ + FR_INT_ERR, /* (2) Assertion failed */ + FR_NOT_READY, /* (3) The physical drive cannot work */ + FR_NO_FILE, /* (4) Could not find the file */ + FR_NO_PATH, /* (5) Could not find the path */ + FR_INVALID_NAME, /* (6) The path name format is invalid */ + FR_DENIED, /* (7) Access denied due to prohibited access or directory full */ + FR_EXIST, /* (8) Access denied due to prohibited access */ + FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ + FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ + FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ + FR_NOT_ENABLED, /* (12) The volume has no work area */ + FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */ + FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */ + FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ + FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */ + FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ + FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */ + FR_INVALID_PARAMETER /* (19) Given parameter is invalid */ +} FRESULT; + + + +/*--------------------------------------------------------------*/ +/* FatFs module application interface */ + +FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */ +FRESULT f_close (FIL* fp); /* Close an open file object */ +FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from a file */ +FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to a file */ +FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */ +FRESULT f_lseek (FIL* fp, DWORD ofs); /* Move file pointer of a file object */ +FRESULT f_truncate (FIL* fp); /* Truncate file */ +FRESULT f_sync (FIL* fp); /* Flush cached data of a writing file */ +FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */ +FRESULT f_closedir (DIR* dp); /* Close an open directory */ +FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */ +FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */ +FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */ +FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */ +FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */ +FRESULT f_chmod (const TCHAR* path, BYTE value, BYTE mask); /* Change attribute of the file/dir */ +FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change times-tamp of the file/dir */ +FRESULT f_chdir (const TCHAR* path); /* Change current directory */ +FRESULT f_chdrive (const TCHAR* path); /* Change current drive */ +FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */ +FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */ +FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* sn); /* Get volume label */ +FRESULT f_setlabel (const TCHAR* label); /* Set volume label */ +FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ +FRESULT f_mkfs (const TCHAR* path, BYTE sfd, UINT au); /* Create a file system on the volume */ +FRESULT f_fdisk (BYTE pdrv, const DWORD szt[], void* work); /* Divide a physical drive into some partitions */ +int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */ +int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */ +int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */ +TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */ + +#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0) +#define f_error(fp) ((fp)->err) +#define f_tell(fp) ((fp)->fptr) +#define f_size(fp) ((fp)->fsize) + +#ifndef EOF +#define EOF (-1) +#endif + + + + +/*--------------------------------------------------------------*/ +/* Additional user defined functions */ + +/* RTC function */ +#if !_FS_READONLY +DWORD get_fattime (void); +#endif + +/* Unicode support functions */ +#if _USE_LFN /* Unicode - OEM code conversion */ +WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */ +WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */ +#if _USE_LFN == 3 /* Memory functions */ +void* ff_memalloc (UINT msize); /* Allocate memory block */ +void ff_memfree (void* mblock); /* Free memory block */ +#endif +#endif + +/* Sync functions */ +#if _FS_REENTRANT +int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj); /* Create a sync object */ +int ff_req_grant (_SYNC_t sobj); /* Lock sync object */ +void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */ +int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */ +#endif + + + + +/*--------------------------------------------------------------*/ +/* Flags and offset address */ + + +/* File access control and file status flags (FIL.flag) */ + +#define FA_READ 0x01 +#define FA_OPEN_EXISTING 0x00 + +#if !_FS_READONLY +#define FA_WRITE 0x02 +#define FA_CREATE_NEW 0x04 +#define FA_CREATE_ALWAYS 0x08 +#define FA_OPEN_ALWAYS 0x10 +#define FA__WRITTEN 0x20 +#define FA__DIRTY 0x40 +#endif + + +/* FAT sub type (FATFS.fs_type) */ + +#define FS_FAT12 1 +#define FS_FAT16 2 +#define FS_FAT32 3 + + +/* File attribute bits for directory entry */ + +#define AM_RDO 0x01 /* Read only */ +#define AM_HID 0x02 /* Hidden */ +#define AM_SYS 0x04 /* System */ +#define AM_VOL 0x08 /* Volume label */ +#define AM_LFN 0x0F /* LFN entry */ +#define AM_DIR 0x10 /* Directory */ +#define AM_ARC 0x20 /* Archive */ +#define AM_MASK 0x3F /* Mask of defined bits */ + + +/* Fast seek feature */ +#define CREATE_LINKMAP 0xFFFFFFFF + + + +/*--------------------------------*/ +/* Multi-byte word access macros */ + +#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val) +#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val) +#else /* Use byte-by-byte access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8) +#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _FATFS */ diff --git a/source/KernelServices/CBYTEQUEUE.h b/source/KernelServices/CBYTEQUEUE.h new file mode 100644 index 0000000..a9c9dad --- /dev/null +++ b/source/KernelServices/CBYTEQUEUE.h @@ -0,0 +1,31 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#include +#ifdef KERNEL + +#ifndef CBYTEQUEUE_H +#define CBYTEQUEUE_H + +typedef struct +{ + uint32 u32Head; + uint32 u32Tail; + uint32 u32Size; + puint8 pu8Data; +} CBYTEQUEUE_tstQueue; + + +#endif // CBYTEQUEUE_H + +#endif // KERNEL + diff --git a/source/KernelServices/COMMONNL.h b/source/KernelServices/COMMONNL.h new file mode 100644 index 0000000..7feec32 --- /dev/null +++ b/source/KernelServices/COMMONNL.h @@ -0,0 +1,65 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef COMMONNL_H +#define COMMONNL_H + +#include "types.h" + +#define COMMONNL_RX_BUFF_LARGE_SIZE 1030u +#define COMMONNL_TX_BUFF_LARGE_SIZE 258u +#define COMMONNL_RX_BUFF_SMALL_SIZE 128u +#define COMMONNL_TX_BUFF_SMALL_SIZE 128u + +typedef struct +{ + uint8 u8Data[COMMONNL_RX_BUFF_LARGE_SIZE]; + uint8* pu8RX; + uint16 u16RXRequestedCount; + uint16 u16RXReceivedCount; + uint8 u8SeqNumber; + uint8 u8RXBlock; + uint8 biRXErr : 1; + uint8 biRXOK : 1; + uint8 biSpare : 6; +} COMMONNL_tstRXLargeBuffer; + +typedef struct +{ + uint8 u8Data[COMMONNL_TX_BUFF_LARGE_SIZE]; + uint8* pu8TX; + uint16 u16TXRequestedCount; + uint16 u16TXTransmittedCount; + uint8 u8SeqNumber; + uint8 u8TXBlock; + uint8 biTXErr : 1; + uint8 biTXOK : 1; + uint8 biSpare : 6; +} COMMONNL_tstTXLargeBuffer; + +typedef struct +{ + uint8 u8Data[COMMONNL_RX_BUFF_SMALL_SIZE]; + uint8* pu8RX; + uint8 u8RXRequestedCount; + uint8 u8RXReceivedCount; +} COMMONNL_tstRXSmallBuffer; + +typedef struct +{ + uint8 u8Data[COMMONNL_TX_BUFF_SMALL_SIZE]; + uint8* pu8TX; + uint8 u8TXRequestedCount; + uint8 u8TXReceivedCount; +} COMMONNL_tstTXSmallBuffer; + +#endif //COMMONNL_H + diff --git a/source/KernelServices/DISK.c b/source/KernelServices/DISK.c new file mode 100644 index 0000000..bf814ac --- /dev/null +++ b/source/KernelServices/DISK.c @@ -0,0 +1,70 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: DISK */ +/* DESCRIPTION: This code provides functions to support NVM disk */ +/* functionality with a FATFS */ +/* FILE NAME: DISK.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include +#include "types.h" +#include "CPUAbstract.h" +#include "regset.h" +#include "declarations.h" +#include "OS.h" +#include "disk.h" +#include "diskio.h" +#include "types.h" +#include "sdhc.h" + +#ifdef BUILD_MK60 +#include "sdhc1.h" +#endif //BUILD_MK60 + + + +void DISK_vStart(uint32* const u32Stat) +{ + /* TODO */ +} + +void DISK_vRun(uint32* const u32Stat) +{ + /* TODO */ +} + +void DISK_vTerminate(uint32* const u32Stat) +{ + +} + +DSTATUS disk_initialize(BYTE pdrv) +{ + return 0; +} + +DSTATUS disk_status(BYTE pdrv) +{ + return 0; +} + +DRESULT disk_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) +{ + return SDHC_u8DiskRead(buff, sector, count); +} + +DRESULT disk_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) +{ + return SDHC_u8DiskWrite((uint8* const)buff, sector, count); +} + +DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff) +{ + return 0; +} + diff --git a/source/KernelServices/DISK.h b/source/KernelServices/DISK.h new file mode 100644 index 0000000..e70c233 --- /dev/null +++ b/source/KernelServices/DISK.h @@ -0,0 +1,34 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: DISK Header File */ +/* DESCRIPTION: This code provides enum definitions for disk support */ +/* */ +/* FILE NAME: DISK.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef DISK_H +#define DISK_H + +#include +#include +#include + +#define DISK_nDISKS 1 + +typedef enum +{ + enDiskSDCard, + enDiskFlash, + enDiskEEPROM +} DISK_tenDiskIndex; + +void DISK_vStart(uint32* const); +void DISK_vRun(uint32* const); +void DISK_vTerminate(uint32* const); + +#endif //DSCRIO_H + diff --git a/source/KernelServices/DLL.c b/source/KernelServices/DLL.c new file mode 100644 index 0000000..75cd80e --- /dev/null +++ b/source/KernelServices/DLL.c @@ -0,0 +1,1290 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#include +#include +#include +#include "peruart.h" +#include "PROTAPI.h" +#include "IOAPI.h" +#include "OS.h" +#include "DLL.h" +#include "perCAN.h" +#include "PACKEDDLL.h" +#include "UDSNL.h" +#include "CBYTEQUEUE.h" +#include "USERMATH.h" +#include "RESM.h" + +extern void VCOMHA_vSend(IOAPI_tenEHIOResource, puint8, uint32); + +#ifdef BUILD_ENET +const uint32 ETH_ru32SourceIPAddress = ETH_nSourceIPAddress; +const uint32 ETH_ru32DestinationIPAddress = ETH_nDestinationIPAddress; +#endif //BUILD_ENET +const uint16 DLL_rau16TXFrameMaxBytes[] = DLL_nMaxTXFrameBytes; + +IOAPI_tstPortConfigCB DLL_astPortConfigCB[DLL_nVirtualChannelCount]; +DLL_tstRXDLLData DLL_stRXDLLData[DLL_nVirtualChannelCount]; +uint16 DLL_au16PacketSeq[DLL_nVirtualChannelCount]; + +/* Circular TX queues */ +uint8 DLL_au8ByteIICByteQueue[DLL_nIICVirtualChannelCount][DLL_nIICTXQueueByteCount]; +uint8 DLL_au8ByteSPIByteQueue[DLL_nSPIVirtualChannelCount][DLL_nSPITXQueueByteCount]; +uint8 DLL_au8ByteUARTByteQueue[DLL_nUARTVirtualChannelCount][DLL_nUARTTXQueueByteCount]; +uint8 DLL_au8ByteCANByteQueue[DLL_nCANVirtualChannelCount][DLL_nCANTXQueueByteCount]; +uint8 DLL_au8ByteUSBByteQueue[DLL_nUSBVirtualChannelCount][DLL_nUSBTXQueueByteCount]; +uint8 DLL_au8ByteENETByteQueue[DLL_nENETVirtualChannelCount][DLL_nENETTXQueueByteCount]; + +/* Temp TX buff to build response and to dequeue byte-queue to for TX */ +uint8 DLL_au8TXIICBuffBuild[DLL_nIICTXWorkBuffCount][DLL_nIICTXWorkBuffMaxBytes]; +uint8 DLL_au8TXSPIBuffBuild[DLL_nSPITXWorkBuffCount][DLL_nSPITXWorkBuffMaxBytes]; +uint8 DLL_au8TXUARTBuffBuild[DLL_nUARTTXWorkBuffCount][DLL_nUARTTXWorkBuffMaxBytes]; +uint8 DLL_au8TXCANBuffBuild[DLL_nCANTXWorkBuffCount][DLL_nCANTXWorkBuffMaxBytes]; +uint8 DLL_au8TXUSBBuffBuild[DLL_nUSBTXWorkBuffCount][DLL_nUSBTXWorkBuffMaxBytes]; +uint8 DLL_au8TXENETBuffBuild[DLL_nENETTXWorkBuffCount][DLL_nENETTXWorkBuffMaxBytes]; + +/* Bytequeue struct array */ +CBYTEQUEUE_tstQueue DLL_astTXDLLByteQueue[DLL_nIICVirtualChannelCount + + DLL_nSPIVirtualChannelCount + + DLL_nUARTVirtualChannelCount + + DLL_nCANVirtualChannelCount + + DLL_nUSBVirtualChannelCount + + DLL_nENETVirtualChannelCount]; + +/* Build buffer client array */ +IOAPI_tenEHIOResource DLL_aenDLLTXBufferClient[ DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount + + DLL_nUARTTXWorkBuffCount + + DLL_nCANTXWorkBuffCount + + DLL_nUSBTXWorkBuffCount + + DLL_nENETTXWorkBuffCount]; + +/* Transmit control structure array */ +DLL_tstTXCB DLL_astTXCB[ DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount + + DLL_nUARTTXWorkBuffCount + + DLL_nCANTXWorkBuffCount + + DLL_nENETTXWorkBuffCount]; + + + +static void DLL_vInsertCANIDAndDLC(puint8, puint32, uint32); +static IOAPI_tenEHIOResource DLL_tGetEHIOResource(DLL_tDLLVirtualChannel); +static bool DLL_boSendFrame(IOAPI_tenEHIOResource, puint8, uint32); + +static void DLLBYTEQUEUE_vInit(CBYTEQUEUE_tstQueue*, uint32, void*); +static uint32 DLLBYTEQUEUE_u32GetVacantCount(CBYTEQUEUE_tstQueue*); +static uint32 DLLBYTEQUEUE_u32GetQueuedCount(CBYTEQUEUE_tstQueue*); +static bool DLLBYTEQUEUE_vQueueBytes(CBYTEQUEUE_tstQueue*, puint8, uint32); +static void DLLBYTEQUEUE_vDequeueBytes(CBYTEQUEUE_tstQueue*, puint8, puint32); +static puint8 DLL_pu8GetTXClientBuffer(IOAPI_tenEHIOResource, puint32 pu32TXBufferCap); +static void DLL_vReleaseTXClientBuffer(puint8); +uint32 DLL_au32CANData[8]; + +DLL_tstRXDLLData* DLL_pstGetRXBuffer(IOAPI_tenEHIOResource enEHIOResource) +{ + return &DLL_stRXDLLData[enEHIOResource - EH_VIO_IIC1]; +} + +//void DLL_vIPBufferRXCB(ENE_tstETHUnionFrame* pstETHUnionFrame) +//{ + //uint8 u8ENEChannelIDX; + //uint16 u16Temp; + //puint8 pu8FrameData; + // + //IOAPI_tenEHIOResource enEHIOResource = EH_IO_Invalid; + //DLL_tDLLVirtualChannel DLLVirtualChannelIDX = DLL_tGetVirtualChannel(EH_VIO_ENET_CH1); + // + //for (u8ENEChannelIDX = 0; u8ENEChannelIDX < (EH_ENET_LAST_CH - EH_ENET_FIRST_CH + 1); u8ENEChannelIDX++) + //{ + //if ((EH_ENET_FIRST_CH <= + //DLL_astPortConfigCB[DLLVirtualChannelIDX + u8ENEChannelIDX].enVIOResource) + //&&(EH_ENET_LAST_CH >= + //DLL_astPortConfigCB[DLLVirtualChannelIDX + u8ENEChannelIDX].enVIOResource)) + //{ +//#if (COMMS_ETH_WIFI) + //if(NTOHS(DLL_astPortConfigCB[DLLVirtualChannelIDX + u8ENEChannelIDX].stNetConfig.uNetInfo.stLANNetInfo.u16RPCREQSourcePort) == + //(pstETHUnionFrame -> uIPData.stUDPHeader.u16SourcePort)) +//#endif + //{ + //if(NTOHS(DLL_astPortConfigCB[DLLVirtualChannelIDX + u8ENEChannelIDX].stNetConfig.uNetInfo.stLANNetInfo.u16RPCREQDestPort) == + //(pstETHUnionFrame -> uIPData.stUDPHeader.u16DestinationPort)) + //{ + //enEHIOResource = (IOAPI_tenEHIOResource)(EH_VIO_ENET_CH1 + u8ENEChannelIDX); + //break; + //} + //} + //} + //} + // + //if (EH_IO_Invalid != enEHIOResource) + //{ + //DLLVirtualChannelIDX = DLL_tGetVirtualChannel(enEHIOResource); + //DLL_au16PacketSeq[DLLVirtualChannelIDX] = NTOHS(pstETHUnionFrame->uETHData.stIPHeader.u16ID); + //u16Temp = NTOHS(pstETHUnionFrame->uIPData.stUDPHeader.u16UDPLength); + //u16Temp = MIN(u16Temp, (uint16)RX_BUFF_SIZE); //matthew + //pu8FrameData = &pstETHUnionFrame->au8UDPData[0]; + // + //DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount = u16Temp; + //memcpy((void*)&DLL_stRXDLLData[DLLVirtualChannelIDX].u8Data, + //(void*)pu8FrameData, u16Temp); +// + //DLL_vFrameRXCB(enEHIOResource, (puint8)&DLL_stRXDLLData[DLLVirtualChannelIDX].u8Data[0]); + //} +//} + +void DLL_vIPBufferTX(IOAPI_tenEHIOResource enEHIOResource, puint8 pu8TXData, uint32 u32TXByteCount) +{ + +} + +/* pu8RXData receive frame could be various frame format, hardware mailbox etc */ +void DLL_vFrameRXCB(IOAPI_tenEHIOResource enEHIOResource, puint8 pu8RXData) +{ + puint8 pu8TXData; + puint8 pu8TXBuffer = NULL; + uint32 u32TXByteCount = 0; + uint32 u32TXByteCountOld; + uint32 u32TXBufferCap; + uint32 u32Temp; + CANHA_tstCANMB* pstCANMB; + bool boQueuedOK; + + DLL_tDLLVirtualChannel DLLVirtualChannelIDX = DLL_tGetVirtualChannel(enEHIOResource); + + /* Get a response buffer */ + pu8TXBuffer = DLL_pu8GetTXClientBuffer(enEHIOResource, &u32TXBufferCap); + + if (NULL != pu8TXBuffer) + { + pu8TXData = pu8TXBuffer; + } + else + { + /* No TX response buffer is available */ + DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount = 0; + return; + } + + + switch (DLL_astPortConfigCB[DLLVirtualChannelIDX].enLLProtocol) + { + case PROTAPI_enLLUARTSZDelim: + { + while((nASCII_CR == *pu8RXData) || (nASCII_LF == *pu8RXData)) + { + pu8RXData++; + } + break; + } + default: + { + break; + } + } + + switch (DLL_astPortConfigCB[DLLVirtualChannelIDX].enNLProtocol) + { + case PROTAPI_enNLNone: + { + /* Invoke callback to USER NL RX handler */ + if ((NULL != DLL_astPortConfigCB[DLLVirtualChannelIDX].pfRXTransferCB) + && (NULL != pu8RXData)) + { + DLL_astPortConfigCB[DLLVirtualChannelIDX].pfRXTransferCB(enEHIOResource, + pu8RXData, + (uint32)(DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount), + IOAPI_IO_RX); + } + break; + } + case PROTAPI_enISO15765: + { + switch (DLL_astPortConfigCB[DLLVirtualChannelIDX].enTLProtocol) + { + case PROTAPI_enTLUDS: + { + switch (DLL_astPortConfigCB[DLLVirtualChannelIDX].enLLProtocol) + { + case PROTAPI_enLLCAN11: + case PROTAPI_enLLCAN29: + { + /* Get message ID */ + pstCANMB = (CANHA_tstCANMB*)pu8RXData; + + u32Temp = (pstCANMB -> u32ID) >> CANHA_nCANIDSTDSHIFT; + //u32Temp = pstCANMB -> u32ID; + + /* Is the message ID for diagnostics? */ + if ((DLL_astPortConfigCB[DLLVirtualChannelIDX].stNetConfig.uNetInfo.stCANNetInfo.u32GlobalCANDiagAddress + == u32Temp) || + (DLL_astPortConfigCB[DLLVirtualChannelIDX].stNetConfig.uNetInfo.stCANNetInfo.u32CANDiagAddress + == u32Temp)) + { + DLL_stRXDLLData[DLLVirtualChannelIDX].u8Data[0] = (uint8)(pstCANMB -> u32DWH >> 24); + DLL_stRXDLLData[DLLVirtualChannelIDX].u8Data[1] = (uint8)(pstCANMB -> u32DWH >> 16); + DLL_stRXDLLData[DLLVirtualChannelIDX].u8Data[2] = (uint8)(pstCANMB -> u32DWH >> 8); + DLL_stRXDLLData[DLLVirtualChannelIDX].u8Data[3] = (uint8)(pstCANMB -> u32DWH >> 0); + DLL_stRXDLLData[DLLVirtualChannelIDX].u8Data[4] = (uint8)(pstCANMB -> u32DWL >> 24); + DLL_stRXDLLData[DLLVirtualChannelIDX].u8Data[5] = (uint8)(pstCANMB -> u32DWL >> 16); + DLL_stRXDLLData[DLLVirtualChannelIDX].u8Data[6] = (uint8)(pstCANMB -> u32DWL >> 8); + DLL_stRXDLLData[DLLVirtualChannelIDX].u8Data[7] = (uint8)(pstCANMB -> u32DWL >> 0); + DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount = (uint8)((pstCANMB -> u32CS & 0x000f0000) >> 16); + + pu8RXData = &DLL_stRXDLLData[DLLVirtualChannelIDX].u8Data[0]; + UDSNL_vReceiveFrame(enEHIOResource, pu8RXData, pu8TXData, &u32TXByteCount, u32TXBufferCap); + + if (0 < u32TXByteCount) + { + /* Insert the CANIDs and DLC */ + DLL_vInsertCANIDAndDLC(pu8TXBuffer, &u32TXByteCount, + DLL_astPortConfigCB[DLLVirtualChannelIDX].stNetConfig.uNetInfo.stCANNetInfo.u32CANDiagAddress + 8); + } + } + /* Is this a priority monitored address? */ + else if (u32Temp == DLL_astPortConfigCB[DLLVirtualChannelIDX].stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityAddress[0]) + { + DLL_au32CANData[0] = pstCANMB -> u32DWH; + DLL_au32CANData[1] = pstCANMB -> u32DWL; + } + /* Is this a priority monitored address? */ + else if (u32Temp == DLL_astPortConfigCB[DLLVirtualChannelIDX].stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityAddress[1]) + { + DLL_au32CANData[2] = pstCANMB -> u32DWH; + DLL_au32CANData[3] = pstCANMB -> u32DWL; + } + /* Is this a priority monitored address? */ + else if (u32Temp == DLL_astPortConfigCB[DLLVirtualChannelIDX].stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityAddress[2]) + { + DLL_au32CANData[4] = pstCANMB -> u32DWH; + DLL_au32CANData[5] = pstCANMB -> u32DWL; + } + /* Is this a priority monitored address? */ + else if (u32Temp == DLL_astPortConfigCB[DLLVirtualChannelIDX].stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityAddress[3]) + { + DLL_au32CANData[6] = pstCANMB -> u32DWH; + DLL_au32CANData[7] = pstCANMB -> u32DWL; + } + break; + } + + case PROTAPI_enUSB: + { + while (0 < DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount) + { + u32TXByteCountOld = u32TXByteCount; + UDSNL_vReceiveFrame(enEHIOResource, pu8RXData, pu8TXData, &u32TXByteCount, u32TXBufferCap); + DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount = 7 < DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount ? + DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount - 8 : 0; + pu8RXData = 0 < DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount ? pu8RXData + 8 : NULL; + pu8TXData += (u32TXByteCount - u32TXByteCountOld); + DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount = 0 == *pu8RXData ? + 0 : DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount; + } + + break; + } + + default: + { + break; + } + } + break; + } + default: + { + break; + } + } + break; + } + case PROTAPI_enISO15765_IP: + { + switch (DLL_astPortConfigCB[DLLVirtualChannelIDX].enTLProtocol) + { + case PROTAPI_enTLUDS_UDP: + { + while (0 < DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount) + { + u32TXByteCountOld = u32TXByteCount; + UDSNL_vReceiveFrame(enEHIOResource, pu8RXData, pu8TXData, &u32TXByteCount, u32TXBufferCap); + DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount = 7 < DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount ? + DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount - 8 : 0; + pu8RXData = 0 < DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount ? pu8RXData + 8 : NULL; + pu8TXData += (u32TXByteCount - u32TXByteCountOld); + DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount = 0 == *pu8RXData ? + 0 : DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount; + } + + break; + } + default: + { + break; + } + } + } + default: + { + break; + } + } + + if (0 == u32TXByteCount) + { + /* Release the buffer if no response generated */ + DLL_vReleaseTXClientBuffer(pu8TXData); + } + else + { + uint32 u32TXByteCountBoundary = u32TXByteCount; + + if ((u32TXByteCount % 8) != 0) + { + u32TXByteCountBoundary = 8 * (u32TXByteCount / 8) + 8; + } + + /* Enqueue the response */ + boQueuedOK = DLLBYTEQUEUE_vQueueBytes(&DLL_astTXDLLByteQueue[DLLVirtualChannelIDX], pu8TXBuffer, u32TXByteCountBoundary); + + /* Release the buffer */ + DLL_vReleaseTXClientBuffer(pu8TXBuffer); + } + + /* TODO warning suppressed */ + (void)boQueuedOK; +} + +void DLL_vStart(uint32* const u32Stat) +{ + uint32 u32QueueIDX = 0; + uint32 u32IDX; + + /* Initialise IIC byte queue structs */ + for (u32IDX = 0; u32IDX < DLL_nIICVirtualChannelCount; u32IDX++) + { + DLLBYTEQUEUE_vInit(&DLL_astTXDLLByteQueue[u32QueueIDX++], + DLL_nIICTXQueueByteCount, (puint8)&DLL_au8ByteIICByteQueue[u32IDX][0]); + } + + /* Initialise SPI byte queue structs */ + for (u32IDX = 0; u32IDX < DLL_nSPIVirtualChannelCount; u32IDX++) + { + DLLBYTEQUEUE_vInit(&DLL_astTXDLLByteQueue[u32QueueIDX++], + DLL_nSPITXQueueByteCount, (puint8)&DLL_au8ByteSPIByteQueue[u32IDX][0]); + } + + /* Initialise UART byte queue structs */ + for (u32IDX = 0; u32IDX < DLL_nUARTVirtualChannelCount; u32IDX++) + { + DLLBYTEQUEUE_vInit(&DLL_astTXDLLByteQueue[u32QueueIDX++], + DLL_nUARTTXQueueByteCount, (puint8)&DLL_au8ByteUARTByteQueue[u32IDX][0]); + } + + /* Initialise CAN byte queue structs */ + for (u32IDX = 0; u32IDX < DLL_nCANVirtualChannelCount; u32IDX++) + { + DLLBYTEQUEUE_vInit(&DLL_astTXDLLByteQueue[u32QueueIDX++], + DLL_nCANTXQueueByteCount, (puint8)&DLL_au8ByteCANByteQueue[u32IDX][0]); + } + + /* Initialise USB byte queue structs */ + for (u32IDX = 0; u32IDX < DLL_nUSBVirtualChannelCount; u32IDX++) + { + DLLBYTEQUEUE_vInit(&DLL_astTXDLLByteQueue[u32QueueIDX++], + DLL_nUSBTXQueueByteCount, (puint8)&DLL_au8ByteUSBByteQueue[u32IDX][0]); + } + + /* Initialise ENET byte queue structs */ + for (u32IDX = 0; u32IDX < DLL_nENETVirtualChannelCount; u32IDX++) + { + DLLBYTEQUEUE_vInit(&DLL_astTXDLLByteQueue[u32QueueIDX++], + DLL_nENETTXQueueByteCount, (puint8)&DLL_au8ByteENETByteQueue[u32IDX][0]); + } + + /* Initialise the buffer client array */ + for (u32IDX = 0; u32IDX < DLL_nClientTXBufferCount; u32IDX++) + { + DLL_aenDLLTXBufferClient[u32IDX] = EH_IO_Invalid; + } + + /* Initialise the TX control blocks */ + for (u32IDX = 0; u32IDX < (DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount + + DLL_nUARTTXWorkBuffCount + + DLL_nCANTXWorkBuffCount + + DLL_nUSBTXWorkBuffCount + + DLL_nENETTXWorkBuffCount); u32IDX++) + { + DLL_astTXCB[u32IDX].pu8TXData = NULL; + } + + DLL_au32CANData[0] = ~0; + DLL_au32CANData[1] = ~0; + DLL_au32CANData[2] = ~0; + DLL_au32CANData[3] = ~0; + DLL_au32CANData[4] = ~0; + DLL_au32CANData[5] = ~0; + DLL_au32CANData[6] = ~0; + DLL_au32CANData[7] = ~0; + + OS_xModuleStartOK(*u32Stat); +} + +void DLL_vRun(uint32* const u32Stat) +{ + DLL_tDLLVirtualChannel DLLVirtualChannelIDX; + IOAPI_tenEHIOResource enEHIOResource; + uint32 u32TXBytesMaxDequeued; + uint32 u32TXBufferCap; + puint8 pu8TXData; + bool boReleaseImmediate; + + for (DLLVirtualChannelIDX = 0; DLLVirtualChannelIDX < DLL_nVirtualChannelCount; DLLVirtualChannelIDX++) + { + if (0 < DLLBYTEQUEUE_u32GetQueuedCount(&DLL_astTXDLLByteQueue[DLLVirtualChannelIDX])) + { + enEHIOResource = DLL_tGetEHIOResource(DLLVirtualChannelIDX); + + if (DLL_astPortConfigCB[DLLVirtualChannelIDX].enVIOResource == enEHIOResource) + { + u32TXBytesMaxDequeued = DLL_rau16TXFrameMaxBytes[DLLVirtualChannelIDX]; + + /* Get a TX buffer */ + pu8TXData = DLL_pu8GetTXClientBuffer(enEHIOResource, &u32TXBufferCap); + + if (NULL != pu8TXData) + { + /* Uh oh really need to check if channel is available here first */ + DLLBYTEQUEUE_vDequeueBytes(&DLL_astTXDLLByteQueue[DLLVirtualChannelIDX], + pu8TXData, &u32TXBytesMaxDequeued); + + boReleaseImmediate = DLL_boSendFrame(enEHIOResource, pu8TXData, u32TXBytesMaxDequeued); + + if (true == boReleaseImmediate) + /* Some TX channel such as ENET rebuffer so release is OK, others + such as UART transit more bytes by CB, so no immediate release */ + { + DLL_vReleaseTXClientBuffer(pu8TXData); + } + } + } + } + } +} + +void DLL_vTerminate(uint32* const u32Stat) +{ + +} + +bool DLL_boInitDLLChannel(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tstPortConfigCB* pstCommsConfig) +{ + bool boRetVal = false; + SYSAPI_ttClientHandle tClientHandleReq; + SYSAPI_ttClientHandle tClientHandle; + DLL_tDLLVirtualChannel DLLVirtualChannelIDX = DLL_tGetVirtualChannel(enEHIOResource); + + if (-1 != DLLVirtualChannelIDX) + { + switch (pstCommsConfig->enVIOResource) + { + case EH_VIO_UART1: + case EH_VIO_UART2: + case EH_VIO_UART3: + case EH_VIO_UART4: + case EH_VIO_UART5: + case EH_VIO_UART6: + { + tClientHandleReq = DLL_xGetClientHandle(); + tClientHandle = (SYSAPI_ttClientHandle)RESM_u32RequestEHIOResource(pstCommsConfig->stPinConfig.uPinInfo.stUARTPinInfo.enRXPin, tClientHandleReq); + tClientHandle &= (SYSAPI_ttClientHandle)RESM_u32RequestEHIOResource(pstCommsConfig->stPinConfig.uPinInfo.stUARTPinInfo.enTXPin, tClientHandleReq); + tClientHandle &= (SYSAPI_ttClientHandle)RESM_u32RequestEHIOResource(pstCommsConfig->stPinConfig.uPinInfo.stUARTPinInfo.enRTSPin, tClientHandleReq); + tClientHandle &= (SYSAPI_ttClientHandle)RESM_u32RequestEHIOResource(pstCommsConfig->stPinConfig.uPinInfo.stUARTPinInfo.enCTSPin, tClientHandleReq); + break; + } + case EH_VIO_IIC1: + case EH_VIO_IIC2: + { + tClientHandleReq = DLL_xGetClientHandle(); + tClientHandle = (SYSAPI_ttClientHandle)RESM_u32RequestEHIOResource(pstCommsConfig->stPinConfig.uPinInfo.stIICPinInfo.enSDAPin, tClientHandleReq); + tClientHandle &= (SYSAPI_ttClientHandle)RESM_u32RequestEHIOResource(pstCommsConfig->stPinConfig.uPinInfo.stIICPinInfo.enSCLPin, tClientHandleReq); + break; + } + case EH_VIO_SPI1: + { + tClientHandleReq = DLL_xGetClientHandle(); + tClientHandle = (SYSAPI_ttClientHandle)RESM_u32RequestEHIOResource(pstCommsConfig->stPinConfig.uPinInfo.stSPIPinInfo.enMISOPin, tClientHandleReq); + tClientHandle &= (SYSAPI_ttClientHandle)RESM_u32RequestEHIOResource(pstCommsConfig->stPinConfig.uPinInfo.stSPIPinInfo.enMOSIPin, tClientHandleReq); + tClientHandle &= (SYSAPI_ttClientHandle)RESM_u32RequestEHIOResource(pstCommsConfig->stPinConfig.uPinInfo.stSPIPinInfo.enSCKPin, tClientHandleReq); + break; + } + case EH_VIO_USB: + { + tClientHandleReq = DLL_xGetClientHandle(); + tClientHandle = tClientHandleReq; + break; + } + case EH_VIO_ENET_CH1: + case EH_VIO_ENET_CH2: + case EH_VIO_ENET_CH3: + case EH_VIO_ENET_CH4: + { + /* No additional pin resources are required for ENET - Kernel managed resource*/ + tClientHandleReq = DLL_xGetClientHandle(); + tClientHandle = tClientHandleReq; + break; + } + case EH_VIO_CAN1: + { + tClientHandleReq = DLL_xGetClientHandle(); + tClientHandle = (SYSAPI_ttClientHandle)RESM_u32RequestEHIOResource(pstCommsConfig->stPinConfig.uPinInfo.stCANPinInfo.enTXPin, tClientHandleReq); + tClientHandle &= (SYSAPI_ttClientHandle)RESM_u32RequestEHIOResource(pstCommsConfig->stPinConfig.uPinInfo.stCANPinInfo.enRXPin, tClientHandleReq); + break; + } +#ifdef EH_VIO_CAN2 + case EH_VIO_CAN2: + { + tClientHandleReq = DLL_xGetClientHandle(); + tClientHandle = (SYSAPI_ttClientHandle)RESM_RequestEHIOResource(pstCommsConfig->stPinConfig.uPinInfo.stCANPinInfo.enTXPin, tClientHandleReq); + tClientHandle &= (SYSAPI_ttClientHandle)RESM_RequestEHIOResource(pstCommsConfig->stPinConfig.uPinInfo.stCANPinInfo.enRXPin, tClientHandleReq); + break; + } +#endif //EH_VIO_CAN2 + default: + { + tClientHandleReq = 0xffffffff; + tClientHandle = 0; + break; + } + } + + + if (tClientHandleReq == tClientHandle) + { + memcpy(&DLL_astPortConfigCB[DLLVirtualChannelIDX], pstCommsConfig, sizeof(IOAPI_tstPortConfigCB)); + boRetVal = true; + } + } + + return boRetVal; +} + +void DLL_vReceiveUARTBytes(IOAPI_tenEHIOResource enEHIOResource, DLL_tstRXDLLData* pRXFrame) +{ + DLL_tDLLVirtualChannel DLLVirtualChannelIDX = DLL_tGetVirtualChannel(enEHIOResource); + + DLL_stRXDLLData[DLLVirtualChannelIDX].biRXFull = false; + + while(pRXFrame->u8DataCount-- > 0) + { + switch(DLL_astPortConfigCB[DLLVirtualChannelIDX].enLLProtocol) + { + case PROTAPI_enLLUARTPacked: + if((0x80 & pRXFrame->u8Data[0]) == 0x80) + { + if((0xC0 & pRXFrame->u8Data[0]) == 0xC0) + { + DLL_stRXDLLData[DLLVirtualChannelIDX].u8RXByteIDX = 0; + } + else + { + if(DLL_stRXDLLData[DLLVirtualChannelIDX].u8RXByteIDX == (TXRX_MSB_DELIM_SIZE - 1)) + DLL_stRXDLLData[DLLVirtualChannelIDX].biRXFull = true; + } + } + DLL_stRXDLLData[DLLVirtualChannelIDX].u8Data[ + DLL_stRXDLLData[DLLVirtualChannelIDX].u8RXByteIDX++] = + pRXFrame->u8Data[pRXFrame->u8RXByteIDX++]; + break; + + case PROTAPI_enLLUARTSZDelim: + if((NULL != pRXFrame -> u8Data[0]) + && (nASCII_LF != pRXFrame -> u8Data[0])) + { + DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount++; + DLL_stRXDLLData[DLLVirtualChannelIDX].u8Data[ + DLL_stRXDLLData[DLLVirtualChannelIDX].u8RXByteIDX++] = + pRXFrame->u8Data[pRXFrame->u8RXByteIDX]; + + if(nASCII_CR == pRXFrame -> u8Data[0]) + { + DLL_stRXDLLData[DLLVirtualChannelIDX].biRXFull = true; + } + } + break; + + default: + break; + } + } + + if(DLL_stRXDLLData[DLLVirtualChannelIDX].biRXFull == true) + { + if(PROTAPI_enLLUARTPacked == DLL_astPortConfigCB[DLLVirtualChannelIDX].enLLProtocol) + { + PACKEDDLL_vUnpack(&DLL_stRXDLLData[DLLVirtualChannelIDX]); + } + + if(PROTAPI_enLLUARTSZDelim == DLL_astPortConfigCB[DLLVirtualChannelIDX].enLLProtocol) + { + DLL_stRXDLLData[DLLVirtualChannelIDX].u8Data[DLL_stRXDLLData[DLLVirtualChannelIDX].u8RXByteIDX] = 0; + DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount++; + } + + DLL_stRXDLLData[DLLVirtualChannelIDX].u8RXByteIDX = 0; + DLL_stRXDLLData[DLLVirtualChannelIDX].u8DataCount = 8; + pRXFrame->biRXFull = false; + + DLL_vFrameRXCB(enEHIOResource, &DLL_stRXDLLData[DLLVirtualChannelIDX].u8Data[0]); + } +} + +void DLL_vTransmitUARTBytesCB(IOAPI_tenEHIOResource enEHIOResource) +{ + DLL_tDLLVirtualChannel DLLVirtualChannelIDX = DLL_tGetVirtualChannel(enEHIOResource); + + if (NULL != DLL_astTXCB[DLLVirtualChannelIDX].pu8TXData) + { + if (0 < DLL_astTXCB[DLLVirtualChannelIDX].u8ByteCount) + { + DLL_astTXCB[DLLVirtualChannelIDX].pu8TXData++; + DLL_astTXCB[DLLVirtualChannelIDX].u8ByteCount--; + UART_vSendChar(enEHIOResource, + *DLL_astTXCB[DLLVirtualChannelIDX].pu8TXData); + } + else + { + UART_vDisableTXInterrupt(enEHIOResource); + DLL_vReleaseTXClientBuffer(DLL_astTXCB[DLLVirtualChannelIDX].pu8TXData); + DLL_astTXCB[DLLVirtualChannelIDX].pu8TXData = NULL; + } + } +} + + +static bool DLL_boSendFrame(IOAPI_tenEHIOResource enEHIOResource, puint8 pu8TXData, uint32 u32TXByteCount) +{ + DLL_tDLLVirtualChannel DLLVirtualChannelIDX = DLL_tGetVirtualChannel(enEHIOResource); + IOAPI_tstTransferCB stTransferCB; + PROTAPI_tstCANMsg stCANMsg; + bool boSyncSent = false; + + switch(enEHIOResource) + { + case EH_VIO_UART1: + case EH_VIO_UART2: + case EH_VIO_UART3: + case EH_VIO_UART4: + case EH_VIO_UART5: + case EH_VIO_UART6: + { + switch (DLL_astPortConfigCB[DLLVirtualChannelIDX].enLLProtocol) + { + case PROTAPI_enLLUARTPacked: + { + if (9 > u32TXByteCount) + { + /* TODO */ + } + break; + } + case PROTAPI_enLLUARTSZDelim: + { + u32TXByteCount = DLL_nTXBytesBufferSize >= u32TXByteCount ? u32TXByteCount : DLL_nTXBytesBufferSize; + + if (NULL == DLL_astTXCB[DLLVirtualChannelIDX].pu8TXData) + { + DLL_astTXCB[DLLVirtualChannelIDX].pu8TXData = pu8TXData; + DLL_astTXCB[DLLVirtualChannelIDX].u8ByteCount = u32TXByteCount; + UART_vSendChar(enEHIOResource, *(DLL_astTXCB[DLLVirtualChannelIDX].pu8TXData)); + } + + break; + } + default: + { + break; + } + } + break; + } + case EH_VIO_ENET_CH1: + case EH_VIO_ENET_CH2: + case EH_VIO_ENET_CH3: + case EH_VIO_ENET_CH4: + { + switch (DLL_astPortConfigCB[DLLVirtualChannelIDX].enLLProtocol) + { + case PROTAPI_enLL802_3: + { + DLL_vIPBufferTX(enEHIOResource, pu8TXData, u32TXByteCount); + boSyncSent = true; + break; + } + default: + { + break; + } + } + break; + } + + case EH_VIO_CAN1: +#ifdef EH_VIO_CAN2 + case EH_VIO_CAN2: +#endif + { + stCANMsg.u32ID = ((*(pu8TXData) & 0x1f) << 24) + + (*(pu8TXData + 1) << 16) + + (*(pu8TXData + 2) << 8) + + (*(pu8TXData + 3) << 0); + stCANMsg.u32DWH = (*(pu8TXData + 4) << 24) + + (*(pu8TXData + 5) << 16) + + (*(pu8TXData + 6) << 8) + + (*(pu8TXData + 7) << 0); + stCANMsg.u32DWL = (*(pu8TXData + 8) << 24) + + (*(pu8TXData + 9) << 16) + + (*(pu8TXData + 10) << 8) + + (*(pu8TXData + 11) << 0); + stCANMsg.u8DLC = ((*pu8TXData) >> 5) + 1; + + stTransferCB.enEHIOResource = enEHIOResource; + stTransferCB.enTransferType = IOAPI_IO_TX; + stTransferCB.pfCB = NULL; + stTransferCB.pvData = (void*)&stCANMsg; + stTransferCB.u32ByteCount = u32TXByteCount; + + CAN_vInitTransfer(&stTransferCB); + boSyncSent = true; + break; + } + + case EH_VIO_USB: + { + switch (DLL_astPortConfigCB[DLLVirtualChannelIDX].enLLProtocol) + { + case PROTAPI_enUSB: + { + VCOMHA_vSend(enEHIOResource, pu8TXData, u32TXByteCount); + boSyncSent = true; + break; + } + default: + { + break; + } + } + } + + default: + { + break; + } + } + + return boSyncSent; +} + +bool DLL_vQueueCANMessage(IOAPI_tenEHIOResource enEHIOResource, PROTAPI_tstCANMsg* pstCANMsg) +{ + bool boRetVal; + uint8 au8TXData[12]; + uint32 u32TXByteCount = 12;//pstCANMsg->u8DLC + 4; + + au8TXData[0] = (pstCANMsg->u8DLC - 1) << 5; + au8TXData[0] += ((pstCANMsg->u32ID & 0x1f000000) >> 24); + au8TXData[1] = (pstCANMsg->u32ID >> 16) & 0xff; + au8TXData[2] = (pstCANMsg->u32ID >> 8) & 0xff; + au8TXData[3] = pstCANMsg->u32ID & 0xff; + au8TXData[4] = (pstCANMsg->u32DWH >> 24) & 0xff; + au8TXData[5] = (pstCANMsg->u32DWH >> 16) & 0xff; + au8TXData[6] = (pstCANMsg->u32DWH >> 8) & 0xff; + au8TXData[7] = pstCANMsg->u32DWH & 0xff; + au8TXData[8] = (pstCANMsg->u32DWL >> 24) & 0xff; + au8TXData[9] = (pstCANMsg->u32DWL >> 16) & 0xff; + au8TXData[10] = (pstCANMsg->u32DWL >> 8) & 0xff; + au8TXData[11] = pstCANMsg->u32DWL & 0xff; + + boRetVal = DLL_boQueueMessage(enEHIOResource, &au8TXData[0], u32TXByteCount); + + return boRetVal; +} + +bool DLL_boQueueMessage(IOAPI_tenEHIOResource enEHIOResource, puint8 pu8TXBuffer, uint32 u32TXByteCount) +{ + DLL_tDLLVirtualChannel DLLVirtualChannelIDX = DLL_tGetVirtualChannel(enEHIOResource); + bool boQueueOK = false; + + if (0 <= DLLVirtualChannelIDX) + { + boQueueOK = DLLBYTEQUEUE_vQueueBytes(&DLL_astTXDLLByteQueue[DLLVirtualChannelIDX], pu8TXBuffer, u32TXByteCount); + } + + return boQueueOK; +} + + +DLL_tDLLVirtualChannel DLL_tGetVirtualChannel(IOAPI_tenEHIOResource enEHIOResource) +{ + DLL_tDLLVirtualChannel DLLVirtualChannel = -1; + + if ((EH_VIO_IIC1 <= enEHIOResource) && (EH_VIO_ENET_CH4 >= enEHIOResource)) + { + DLLVirtualChannel = enEHIOResource - EH_VIO_IIC1; + } + + return DLLVirtualChannel; +} + +static IOAPI_tenEHIOResource DLL_tGetEHIOResource(DLL_tDLLVirtualChannel DLLVirtualChannel) +{ + return (IOAPI_tenEHIOResource)(EH_VIO_IIC1 + DLLVirtualChannel); +} + +IOAPI_tenPortMode DLL_enGetChannelMode(IOAPI_tenEHIOResource enEHIOResource) +{ + IOAPI_tenPortMode enMode = IOAPI_enPortNone; + DLL_tDLLVirtualChannel DLLVirtualChannelIDX = DLL_tGetVirtualChannel(enEHIOResource); + + if (-1 != DLLVirtualChannelIDX) + { + enMode = DLL_astPortConfigCB[DLLVirtualChannelIDX].enPortMode; + } + + return enMode; +} + + +static void DLLBYTEQUEUE_vInit(CBYTEQUEUE_tstQueue* pstQueue, uint32 u32Size, void* pu8Data) +{ + pstQueue->u32Head = 0; + pstQueue->u32Tail = 0; + pstQueue->u32Size = u32Size; + pstQueue->pu8Data = pu8Data; +} + + +static uint32 DLLBYTEQUEUE_u32GetVacantCount(CBYTEQUEUE_tstQueue* pstQueue) +{ + uint32 u32VacantCount; + + if (pstQueue->u32Head <= pstQueue->u32Tail) + { + u32VacantCount = pstQueue->u32Size - (pstQueue->u32Tail - pstQueue->u32Head) - 1; + } + else + { + u32VacantCount = pstQueue->u32Head - pstQueue->u32Tail - 1; + } + + return u32VacantCount; +} + +static uint32 DLLBYTEQUEUE_u32GetQueuedCount(CBYTEQUEUE_tstQueue* pstQueue) +{ + return (pstQueue->u32Size - DLLBYTEQUEUE_u32GetVacantCount(pstQueue) - 1); +} + +static bool DLLBYTEQUEUE_vQueueBytes(CBYTEQUEUE_tstQueue* pstQueue, puint8 pu8TXData, uint32 u32TXByteCount) +{ + bool boRetVal = FALSE; + uint32 u32Temp; + + + + + if (u32TXByteCount <= DLLBYTEQUEUE_u32GetVacantCount(pstQueue)) + { + if (pstQueue->u32Head <= pstQueue->u32Tail) + { + u32Temp = pstQueue->u32Size - pstQueue->u32Tail; + memcpy(pstQueue->pu8Data + pstQueue->u32Tail, pu8TXData, MIN(u32Temp, u32TXByteCount)); + + if (u32Temp < u32TXByteCount) + { + memcpy(pstQueue->pu8Data, pu8TXData + u32Temp, u32TXByteCount - u32Temp); + } + } + else + { + memcpy(pstQueue->pu8Data + pstQueue->u32Tail, pu8TXData, u32TXByteCount); + } + + boRetVal = TRUE; + pstQueue->u32Tail = (pstQueue->u32Tail + u32TXByteCount) % pstQueue->u32Size; + } + + return boRetVal; +} + +static void DLLBYTEQUEUE_vDequeueBytes(CBYTEQUEUE_tstQueue* pstQueue, puint8 pu8Data, puint32 pu32ByteCount) +{ + uint32 u32Temp; + uint32 u32BytesQueued = DLLBYTEQUEUE_u32GetQueuedCount(pstQueue); + + *pu32ByteCount = MIN(*pu32ByteCount , u32BytesQueued); + + if (pstQueue->u32Head < pstQueue->u32Tail) + { + memcpy(pu8Data, pstQueue->pu8Data + pstQueue->u32Head, *pu32ByteCount); + } + else + { + u32Temp = pstQueue->u32Size - pstQueue->u32Head; + u32Temp = MIN(*pu32ByteCount, u32Temp); + memcpy(pu8Data, pstQueue->pu8Data + pstQueue->u32Head, u32Temp); + + if (*pu32ByteCount > u32Temp) + { + memcpy(pu8Data + u32Temp, pstQueue->pu8Data, *pu32ByteCount - u32Temp); + } + } + + pstQueue->u32Head = (pstQueue->u32Head + *pu32ByteCount) % pstQueue->u32Size; +} + +static puint8 DLL_pu8GetTXClientBuffer(IOAPI_tenEHIOResource enEHIOResource, puint32 pu32TXBufferCap) +{ + uint8 u8BufferIDXStart; + uint8 u8BufferIDXEnd; + uint8 u8BufferIDX; + puint8 pu8Buffer; + uint32 u32BufferBytes; + bool boVacantBuff = false; + + switch (enEHIOResource) + { + case EH_VIO_IIC1: + case EH_VIO_IIC2: + { + u8BufferIDXStart = 0; + u8BufferIDXEnd = DLL_nIICTXWorkBuffCount; + pu8Buffer = &DLL_au8TXIICBuffBuild[0][0]; + u32BufferBytes = DLL_nIICTXWorkBuffMaxBytes; + break; + } + + case EH_VIO_SPI1: + case EH_VIO_SPI2: + { + u8BufferIDXStart = DLL_nIICTXWorkBuffCount; + u8BufferIDXEnd = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount; + pu8Buffer = &DLL_au8TXSPIBuffBuild[0][0]; + u32BufferBytes = DLL_nSPITXWorkBuffMaxBytes; + break; + } + + case EH_VIO_UART1: + case EH_VIO_UART2: + case EH_VIO_UART3: + case EH_VIO_UART4: + case EH_VIO_UART5: + case EH_VIO_UART6: + { + u8BufferIDXStart = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount; + u8BufferIDXEnd = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount + + DLL_nUARTTXWorkBuffCount; + pu8Buffer = &DLL_au8TXUARTBuffBuild[0][0]; + u32BufferBytes = DLL_nUARTTXWorkBuffMaxBytes; + break; + } + + case EH_VIO_CAN1: + { + u8BufferIDXStart = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount + + DLL_nUARTTXWorkBuffCount; + u8BufferIDXEnd = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount + + DLL_nUARTTXWorkBuffCount + + DLL_nCANTXWorkBuffCount; + pu8Buffer = &DLL_au8TXCANBuffBuild[0][0]; + u32BufferBytes = DLL_nCANTXWorkBuffMaxBytes; + break; + } + + case EH_VIO_USB: + { + u8BufferIDXStart = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount + + DLL_nUARTTXWorkBuffCount + + DLL_nCANTXWorkBuffCount; + u8BufferIDXEnd = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount + + DLL_nUARTTXWorkBuffCount + + DLL_nCANTXWorkBuffCount + + DLL_nUSBTXWorkBuffCount; + pu8Buffer = &DLL_au8TXUSBBuffBuild[0][0]; + u32BufferBytes = DLL_nUSBTXWorkBuffMaxBytes; + break; + } + + case EH_VIO_ENET_CH1: + case EH_VIO_ENET_CH2: + case EH_VIO_ENET_CH3: + case EH_VIO_ENET_CH4: + { + u8BufferIDXStart = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount + + DLL_nUARTTXWorkBuffCount + + DLL_nCANTXWorkBuffCount + + DLL_nUSBTXWorkBuffCount; + u8BufferIDXEnd = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount + + DLL_nUARTTXWorkBuffCount + + DLL_nCANTXWorkBuffCount + + DLL_nUSBTXWorkBuffCount + + DLL_nENETTXWorkBuffCount; + pu8Buffer = &DLL_au8TXENETBuffBuild[0][0]; + u32BufferBytes = DLL_nENETTXWorkBuffMaxBytes; + break; + } + + default: + { + u8BufferIDXStart = 0; + u8BufferIDXStart = 0; + break; + } + } + + for (u8BufferIDX = u8BufferIDXStart; u8BufferIDX < u8BufferIDXEnd; u8BufferIDX++) + { + if(EH_IO_Invalid == DLL_aenDLLTXBufferClient[u8BufferIDX]) + { + DLL_aenDLLTXBufferClient[u8BufferIDX] = enEHIOResource; + boVacantBuff = true; + break; + } + pu8Buffer += u32BufferBytes; + } + + pu8Buffer = (true == boVacantBuff) ? pu8Buffer : NULL; + *pu32TXBufferCap = u32BufferBytes; + + return pu8Buffer; +} + +static void DLL_vInsertCANIDAndDLC(puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32CANID) +{ + uint32 u32TXByteCount = *pu32TXByteCount; + uint32 u32TXByteCountNew = 0; + uint32 u32FrameCount = u32TXByteCount / 8; + uint32 u32FrameBytes; + puint8 pu8Dest; + puint8 pu8Source; + + if (0 != (u32TXByteCount % 8)) + { + u32FrameCount++; + } + + while (0 < u32FrameCount--) + { + pu8Dest = pu8TXBuffer + (12 * u32FrameCount) + 4; + pu8Source = pu8TXBuffer + (8 * u32FrameCount); + + if (0 != (u32TXByteCount % 8)) + { + u32FrameBytes = u32TXByteCount % 8; + u32TXByteCount -= (u32TXByteCount % 8); + } + else + { + u32FrameBytes = 8; + u32TXByteCount -= 8; + } + + u32TXByteCountNew += u32FrameBytes; + u32TXByteCountNew += 4; + + while (0 < u32FrameBytes) + { + u32FrameBytes--; + *(pu8Dest + u32FrameBytes) = *(pu8Source + u32FrameBytes); + } + + pu8Dest -= 4; + *pu8Dest++ = (((u32FrameBytes - 1) & 0xff) << 5) + ((u32CANID & 0x1f000000) >> 24); + *pu8Dest++ = (u32CANID & 0xff0000) >> 16; + *pu8Dest++ = (u32CANID & 0xff00) >> 8; + *pu8Dest = (u32CANID & 0xff); + + + } + + *pu32TXByteCount = u32TXByteCountNew; +} + +static void DLL_vReleaseTXClientBuffer(puint8 pu8TXBuffer) +{ + uint8 u8BufferIDXStart; + uint8 u8BufferIDXEnd; + uint8 u8BufferIDX; + puint8 pu8Buffer; + uint32 u32BufferBytes; + bool boBufferReleased = false; + + /* Try release a IIC client working buffer */ + u8BufferIDXStart = 0; + u8BufferIDXEnd = DLL_nIICTXWorkBuffCount; + pu8Buffer = &DLL_au8TXIICBuffBuild[0][0]; + u32BufferBytes = DLL_nIICTXWorkBuffMaxBytes; + + for (u8BufferIDX = u8BufferIDXStart; u8BufferIDX < u8BufferIDXEnd; u8BufferIDX++) + { + if ((pu8Buffer <= pu8TXBuffer) && ((pu8Buffer + u32BufferBytes) > pu8TXBuffer)) + { + DLL_aenDLLTXBufferClient[u8BufferIDX] = EH_IO_Invalid; + boBufferReleased = true; + } + pu8Buffer += u32BufferBytes; + } + if (true == boBufferReleased) return; + + /* Try release a SPI client working buffer */ + u8BufferIDXStart = DLL_nIICTXWorkBuffCount; + u8BufferIDXEnd = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount; + pu8Buffer = &DLL_au8TXSPIBuffBuild[0][0]; + u32BufferBytes = DLL_nSPITXWorkBuffMaxBytes; + + for (u8BufferIDX = u8BufferIDXStart; u8BufferIDX < u8BufferIDXEnd; u8BufferIDX++) + { + if ((pu8Buffer <= pu8TXBuffer) && ((pu8Buffer + u32BufferBytes) > pu8TXBuffer)) + { + DLL_aenDLLTXBufferClient[u8BufferIDX] = EH_IO_Invalid; + boBufferReleased = true; + } + pu8Buffer += u32BufferBytes; + } + if (true == boBufferReleased) return; + + /* Try release a UART client working buffer */ + u8BufferIDXStart = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount; + u8BufferIDXEnd = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount + + DLL_nUARTTXWorkBuffCount; + pu8Buffer = &DLL_au8TXUARTBuffBuild[0][0]; + u32BufferBytes = DLL_nUARTTXWorkBuffMaxBytes; + + for (u8BufferIDX = u8BufferIDXStart; u8BufferIDX < u8BufferIDXEnd; u8BufferIDX++) + { + if ((pu8Buffer <= pu8TXBuffer) && ((pu8Buffer + u32BufferBytes) > pu8TXBuffer)) + { + DLL_aenDLLTXBufferClient[u8BufferIDX] = EH_IO_Invalid; + boBufferReleased = true; + } + pu8Buffer += u32BufferBytes; + } + if (true == boBufferReleased) return; + + /* Try release an IIC client working buffer */ + u8BufferIDXStart = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount + + DLL_nUARTTXWorkBuffCount; + u8BufferIDXEnd = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount + + DLL_nUARTTXWorkBuffCount + + DLL_nCANTXWorkBuffCount; + pu8Buffer = &DLL_au8TXCANBuffBuild[0][0]; + + for (u8BufferIDX = u8BufferIDXStart; u8BufferIDX < u8BufferIDXEnd; u8BufferIDX++) + { + if ((pu8Buffer <= pu8TXBuffer) && ((pu8Buffer + u32BufferBytes) > pu8TXBuffer)) + { + DLL_aenDLLTXBufferClient[u8BufferIDX] = EH_IO_Invalid; + boBufferReleased = true; + } + pu8Buffer += u32BufferBytes; + } + if (true == boBufferReleased) return; + + + /* Try release a USB client working buffer */ + u8BufferIDXStart = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount + + DLL_nUARTTXWorkBuffCount + + DLL_nCANTXWorkBuffCount; + u8BufferIDXEnd = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount + + DLL_nUARTTXWorkBuffCount + + DLL_nCANTXWorkBuffCount + + DLL_nENETTXWorkBuffCount; + pu8Buffer = &DLL_au8TXUSBBuffBuild[0][0]; + u32BufferBytes = DLL_nUSBTXWorkBuffMaxBytes; + + for (u8BufferIDX = u8BufferIDXStart; u8BufferIDX < u8BufferIDXEnd; u8BufferIDX++) + { + if ((pu8Buffer <= pu8TXBuffer) && ((pu8Buffer + u32BufferBytes) > pu8TXBuffer)) + { + DLL_aenDLLTXBufferClient[u8BufferIDX] = EH_IO_Invalid; + boBufferReleased = true; + } + pu8Buffer += u32BufferBytes; + } + if (true == boBufferReleased) return; + + /* Try release a ENET client working buffer */ + u8BufferIDXStart = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount + + DLL_nUARTTXWorkBuffCount + + DLL_nCANTXWorkBuffCount + + DLL_nUSBTXWorkBuffCount; + u8BufferIDXEnd = DLL_nIICTXWorkBuffCount + + DLL_nSPITXWorkBuffCount + + DLL_nUARTTXWorkBuffCount + + DLL_nCANTXWorkBuffCount + + DLL_nUSBTXWorkBuffCount + + DLL_nENETTXWorkBuffCount; + pu8Buffer = &DLL_au8TXENETBuffBuild[0][0]; + u32BufferBytes = DLL_nENETTXWorkBuffMaxBytes; + + for (u8BufferIDX = u8BufferIDXStart; u8BufferIDX < u8BufferIDXEnd; u8BufferIDX++) + { + if ((pu8Buffer <= pu8TXBuffer) && ((pu8Buffer + u32BufferBytes) > pu8TXBuffer)) + { + DLL_aenDLLTXBufferClient[u8BufferIDX] = EH_IO_Invalid; + boBufferReleased = true; + } + pu8Buffer += u32BufferBytes; + } +} + +void* DLL_pvGetBuffered(IOAPI_tenEHIOResource enEHIOResource) +{ + void* pvData = NULL; + + switch (enEHIOResource) + { + case EH_VIO_CAN1: + { + pvData = (void*)&DLL_au32CANData; + break; + } + default: + { + + break; + } + } + + return pvData; +} + diff --git a/source/KernelServices/DSCRIO.c b/source/KernelServices/DSCRIO.c new file mode 100644 index 0000000..6ad1070 --- /dev/null +++ b/source/KernelServices/DSCRIO.c @@ -0,0 +1,34 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: DSCRIO */ +/* DESCRIPTION: This code provides support for kernel managed resource */ +/* discrete I/O only (e.g. Ethernet controller) */ +/* FILE NAME: DSCRIO.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include "DSCRIO.h" + + +void DSCRIO_vStart(uint32* const pu32Stat) +{ + DSCRIOHA_vStart(pu32Stat); +} + +void DSCRIO_vRun(uint32* const pu32Stat) +{ + +} + +void DSCRIO_vTerminate(uint32* const pu32Stat) +{ + +} + +void DSCRIO_vSetDiscrete(DSCRIO_tenIOFunction enIOFunction, DSCRIO_tenLogicLevel enLogicLevel) +{ + DSCRIOHA_vSetDiscrete(enIOFunction, enLogicLevel); +} diff --git a/source/KernelServices/DSCRIO.h b/source/KernelServices/DSCRIO.h new file mode 100644 index 0000000..b60f2be --- /dev/null +++ b/source/KernelServices/DSCRIO.h @@ -0,0 +1,56 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: DSCRIO Header File */ +/* DESCRIPTION: This code provides macros for discrete I/O setup */ +/* and enum definitions */ +/* FILE NAME: DSCRIO.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef DSCRIO_H +#define DSCRIO_H + +#include +#include "CPUAbstract.h" +#include "declarations.h" +#include "DSCRIOHA.h" +#include "OS.h" +#include "regset.h" +#include "types.h" + + +typedef struct +{ + tstGPIOModule* pstGPIO; + uint32 u32Bit; +} DSCRIO_tstIOFunctionPortConfig; + + +typedef enum +{ + enCOMSRESET, + enSYSTELLTALE, + enFIFOPRS, + enWIFIMS, + enIOFunctionCount +} DSCRIO_tenIOFunction; + +typedef enum +{ + enLow, + enHigh, + enToggle, + enHighZ +} DSCRIO_tenLogicLevel; + +void DSCRIO_vStart(uint32* const); +void DSCRIO_vRun(uint32* const); +void DSCRIO_vTerminate(uint32* const); +void DSCRIO_vSetDiscrete(DSCRIO_tenIOFunction, DSCRIO_tenLogicLevel); +void DSCRIOHA_vSetDiscrete(DSCRIO_tenIOFunction, DSCRIO_tenLogicLevel); + +#endif //DSCRIO_H + diff --git a/source/KernelServices/DSCRIOHA.c b/source/KernelServices/DSCRIOHA.c new file mode 100644 index 0000000..c29d971 --- /dev/null +++ b/source/KernelServices/DSCRIOHA.c @@ -0,0 +1,79 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: DSCRIO Hardware Adaption */ +/* DESCRIPTION: This code provides support for kernel managed resource */ +/* discrete I/O only (e.g. Ethernet controller) */ +/* FILE NAME: DSCRIOHA.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include "declarations.h" +#include "dscrio.h" +#include "CPUAbstract.h" + +const REGSET_tstReg32Val DSCRIOHA_rastDSCRIOReg32Val[] = DSCRIOHA_nReg32Set; +const DSCRIO_tstIOFunctionPortConfig DSCRIO_stIOFunctionPortConfig[enIOFunctionCount] + = DSCRIOHA_nIOFunctionConfig; + +void DSCRIOHA_vStart(uint32* const u32Stat) +{ +#ifdef BUILD_MK60 + REGSET_vInitReg32(&DSCRIOHA_rastDSCRIOReg32Val[0]); +#endif //BUILD_MK60 + OS_xModuleStartOK(*u32Stat); +} + +void DSCRIOHA_vRun(uint32* const u32Stat) +{ + +} + +void DSCRIOHA_vTerminate(uint32* const u32Stat) +{ + +} + +void DSCRIOHA_vSetDiscrete(DSCRIO_tenIOFunction enIOFunction, DSCRIO_tenLogicLevel enLogicLevel) +{ + switch (enLogicLevel) + { + case enLow: +#ifdef BUILD_MK60 + DSCRIO_stIOFunctionPortConfig[enIOFunction].pstGPIO->PCOR = + DSCRIO_stIOFunctionPortConfig[enIOFunction].u32Bit; +#endif + break; + + case enHigh: +#ifdef BUILD_MK60 + DSCRIO_stIOFunctionPortConfig[enIOFunction].pstGPIO->PSOR = + DSCRIO_stIOFunctionPortConfig[enIOFunction].u32Bit; +#endif + break; + + case enToggle: +#ifdef BUILD_MK60 + DSCRIO_stIOFunctionPortConfig[enIOFunction].pstGPIO->PTOR = + DSCRIO_stIOFunctionPortConfig[enIOFunction].u32Bit; +#endif + break; + + case enHighZ: +#ifdef BUILD_MK60 + DSCRIO_stIOFunctionPortConfig[enIOFunction].pstGPIO->PDDR &= + ~DSCRIO_stIOFunctionPortConfig[enIOFunction].u32Bit; +#endif + break; + } + + if(enHighZ != enLogicLevel) + { +#ifdef BUILD_MK60 + DSCRIO_stIOFunctionPortConfig[enIOFunction].pstGPIO->PDDR |= + DSCRIO_stIOFunctionPortConfig[enIOFunction].u32Bit; +#endif + } +} diff --git a/source/KernelServices/DSCRIOHA.h b/source/KernelServices/DSCRIOHA.h new file mode 100644 index 0000000..1e3b63c --- /dev/null +++ b/source/KernelServices/DSCRIOHA.h @@ -0,0 +1,73 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: DSCRIO Header File */ +/* DESCRIPTION: This code provides macros for discrete I/O setup */ +/* and enum definitions */ +/* FILE NAME: DSCRIO.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef DSCRIOHA_H +#define DSCRIOHA_H + +#include "build.h" + +#if defined(BUILD_MK60) +#include "mk60f12.h" +typedef GPIO_Type tstGPIOModule; +#endif //BUILD_MK60 + +#if defined(BUILD_MK64) +#include "mk64f12.h" +typedef GPIO_Type tstGPIOModule; +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +#include "sam3x8e.h" +typedef Pio tstGPIOModule; +#endif + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +#define DSCRIOHA_nReg32Set \ +{ \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[6])), (uint32)PORT_PCR_MUX(1), REGSET_enOverwrite }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[7])), (uint32)PORT_PCR_MUX(1), REGSET_enOverwrite }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[8])), (uint32)PORT_PCR_MUX(1), REGSET_enOverwrite }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[26])), (uint32)PORT_PCR_MUX(1), REGSET_enOverwrite }, \ + { NULL, 0, REGSET_enOverwrite } \ +}; +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E +#define DSCRIOHA_nReg32Set \ +{ \ + { NULL, 0, REGSET_enOverwrite } \ +}; +#endif //BUILD_MK60 + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +#define DSCRIOHA_nIOFunctionConfig \ +{ \ + { PTE, 0x00000040 }, \ + { PTE, 0x00000100 }, \ + { PTE, 0x00000040 }, \ + { PTE, 0x04000000 } \ +}; +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E +#define DSCRIOHA_nIOFunctionConfig \ +{ \ + { NULL, 0x00000000 } \ +}; +#endif //BUILD_SAM3X8E + +void DSCRIOHA_vStart(uint32* const); +void DSCRIOHA_vRun(uint32* const); +void DSCRIOHA_vTerminate(uint32* const); + +#endif //DSCRIOHA_H + diff --git a/source/KernelServices/KERNELDIAG.c b/source/KernelServices/KERNELDIAG.c new file mode 100644 index 0000000..913b653 --- /dev/null +++ b/source/KernelServices/KERNELDIAG.c @@ -0,0 +1,104 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _DIAG_C + +#include +#include +#include +#include "OS.h" +#include "DAC.h" +#include "DIAGAPI.h" +#include "KERNELDIAG.h" + +void DIAG_vStart(void) +{ + uint32 u32IDX; + + DIAG_DataWriteCB = NULL; + DIAG_ReadWriteCB = NULL; + DIAG_RoutineCB = NULL; + + for (u32IDX = 0; u32IDX < DIAG_DDDI_COUNT; u32IDX++) + { + memset((void*)&DIAG_astDDDI[u32IDX], 0, sizeof(DIAG_tstDDDI)); + } +} + +void DIAG_vSetCallBack(DIAGAPI_tenCallBackType enCallBackType, void* pfFunction) +{ +// #if BUILD_SBL +// OS_stSVCDataStruct.enSVCResult = SYSAPI_enOK; +// +// switch (enCallBackType) +// { +// case DIAGAPI_enDataWriteCB: +// { +// DIAG_DataWriteCB = (DIAGAPI_tDataWriteCB)pfFunction; +// break; +// } +// +// case DIAGAPI_enDataReadCB: +// { +// break; +// } +// +// case DIAGAPI_enRoutineCB: +// { +// break; +// } +// +// default: +// { +// OS_stSVCDataStruct.enSVCResult = SYSAPI_enBadCallback; +// break; +// } +// } +// #endif +#if defined BUILD_KERNEL + OS_stSVCDataStruct.enSVCResult = SYSAPI_enOK; + + switch (enCallBackType) + { + case DIAGAPI_enDataWriteCB: + { + DIAG_DataWriteCB = (DIAGAPI_tDataWriteCB)pfFunction; + break; + } + + case DIAGAPI_enDataReadCB: + { + break; + } + + case DIAGAPI_enRoutineCB: + { + break; + } + + default: + { + OS_stSVCDataStruct.enSVCResult = SYSAPI_enBadCallback; + break; + } + } +#endif +} + + + + + + + + + + diff --git a/source/KernelServices/KERNELDIAG.h b/source/KernelServices/KERNELDIAG.h new file mode 100644 index 0000000..d3ea7af --- /dev/null +++ b/source/KernelServices/KERNELDIAG.h @@ -0,0 +1,48 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef DIAG_H +#define DIAG_H + +#include + +#define DIAG_DDDI_COUNT 10 +#define DIAG_DDDI_DATA_COUNT 200 + +typedef struct BUILD_PACKING +{ + uint16 u16DDI; + uint8 u8AddressAndLength; + uint8 u8RecsCount; + uint8 u8ByteCount; + uint8 u8Data[DIAG_DDDI_DATA_COUNT]; +} DIAG_tstDDDI; + + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _DIAG_C + #define EXTERN +#else + #define EXTERN extern +#endif + +EXTERN DIAG_tstDDDI DIAG_astDDDI[DIAG_DDDI_COUNT]; +EXTERN DIAGAPI_tDataWriteCB DIAG_DataWriteCB; +EXTERN DIAGAPI_tReadWriteCB DIAG_ReadWriteCB; +EXTERN DIAGAPI_tRoutineCB DIAG_RoutineCB; + +void DIAG_vStart(void); +void DIAG_vSetCallBack(DIAGAPI_tenCallBackType, void*); + +#endif // DIAG_H + diff --git a/source/KernelServices/KERNELIO.c b/source/KernelServices/KERNELIO.c new file mode 100644 index 0000000..31fd903 --- /dev/null +++ b/source/KernelServices/KERNELIO.c @@ -0,0 +1,257 @@ +/******************************************************************************/ +/* Copyright (c) 2018 MD Automotive Controls. Original Work. */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 20-06-2018 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#include +#include "mk64f12.h" +#include "OS.h" +#include "DAC.h" +#include "PERCAN.h" +#include "PERUART.h" +#include "IIC.h" +#include "PIM.h" +#include "ADCAPI.h" +#include "DACAPI.h" +#include "IOAPI.h" +#include "IICAPI.h" +#include "PERADC.h" +#include "TEPM.h" +#include "RESM.h" + +extern SYSAPI_tenSVCResult VCOM_enInitBus(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tstPortConfigCB* pstPortConfigCB); +const IO_tstEHPadResource IO_rastEHPadResource[IO_Total_Discrete_Count + KERNEL_DISCRETE_HIDDEN] = IO_nPadResourceMap; +IOAPI_tenEHIOResource IO_aenEHIOMasterList[RESM_nMastersMax]; + +static void IO_vSetIOMux(IOAPI_tenEHIOResource, IOAPI_tenEHIOType, uint32); +static void IO_vClearMasterList(void); + +void IO_vInitDIOResource(IOAPI_tenEHIOResource enIOResource, IOAPI_tenEHIOType enIOType, IOAPI_tenDriveStrength enDriveStrength) +{ + if (0u != IO_rastEHPadResource[enIOResource].u32PortBit) + /* Init DIO only if port bit non zero signifies DIO supported */ + { + PIM_vInitPortBit(IO_rastEHPadResource[enIOResource].enPort, enIOType, IO_rastEHPadResource[enIOResource].u32PortBit); + } +} + +void IO_vInitADCResource(IOAPI_tenEHIOResource enIOResource, IOAPI_tenEHIOType enEHIOType, ADCAPI_tstADCCB* pstADCCB) +{ + if (((0u != IO_rastEHPadResource[enIOResource].boIsADSE) && (IOAPI_enADSE == enEHIOType)) + || ((0u != IO_rastEHPadResource[enIOResource].boIsADD) && (IOAPI_enADD == enEHIOType))) + /* Init DIO only if port bit non zero signifies DIO supported */ + { +#if defined(BUILD_KERNEL) || defined(BUILD_KERNEL_APP) + ADC_vInitADCResource(enIOResource, enEHIOType, pstADCCB); +#endif + } +} + +void IO_vInitDACResource(IOAPI_tenEHIOResource enIOResource, IOAPI_tenEHIOType enEHIOType, DACAPI_tstDACCB* pstDACCB) +{ + if ((0u != IO_rastEHPadResource[enIOResource].boIsDAC) && (IOAPI_enDAC == enEHIOType)) + + /* Init DIO only if port bit non zero signifies DIO supported */ + { +#if defined(BUILD_KERNEL) || defined(BUILD_KERNEL_APP) + DAC_vInitDACResource(enIOResource, pstDACCB); +#endif + } +} + + +SYSAPI_tenSVCResult IO_enInitCommsResource(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tstPortConfigCB* pstPortConfigCB) +{ + SYSAPI_tenSVCResult enSVCResult; + uint32 u32MuxSel; + + if ((EH_VIO_IIC1 == enEHIOResource) || (EH_VIO_IIC2 == enEHIOResource)) + { +#ifdef BUILD_PBL +#elif defined(BUILD_SBL) +#elif defined(BUILD_KERNEL) + enSVCResult = IIC_enInitBus(enEHIOResource, pstPortConfigCB); +#elif defined(BUILD_KERNEL_APP) + enSVCResult = IIC_enInitBus(enEHIOResource, pstPortConfigCB); + IO_vSetIOMux(pstPortConfigCB->stPinConfig.uPinInfo.stIICPinInfo.enSDAPin, IOAPI_enIICBus, 5u); + IO_vSetIOMux(pstPortConfigCB->stPinConfig.uPinInfo.stIICPinInfo.enSCLPin, IOAPI_enIICBus, 5u); +#endif + } + + else if ((EH_VIO_UART1 == enEHIOResource) + || (EH_VIO_UART2 == enEHIOResource) + || (EH_VIO_UART3 == enEHIOResource) + || (EH_VIO_UART4 == enEHIOResource) + || (EH_VIO_UART5 == enEHIOResource) + || (EH_VIO_UART6 == enEHIOResource)) + { + enSVCResult = UART_enInitBus(enEHIOResource, pstPortConfigCB); + IO_vSetIOMux(pstPortConfigCB->stPinConfig.uPinInfo.stUARTPinInfo.enRXPin, IOAPI_enUARTBus, 3u); + IO_vSetIOMux(pstPortConfigCB->stPinConfig.uPinInfo.stUARTPinInfo.enTXPin, IOAPI_enUARTBus, 3u); + } + +#ifdef EH_VIO_CAN2 + else if ((EH_VIO_CAN1 == enEHIOResource) + || (EH_VIO_CAN2 == enEHIOResource)) +#endif +#ifndef EH_VIO_CAN2 + else if (EH_VIO_CAN1 == enEHIOResource) +#endif + + { + u32MuxSel = CAN_enInitBus(enEHIOResource, pstPortConfigCB); + + if (~0 != u32MuxSel) + { + IO_vSetIOMux(pstPortConfigCB->stPinConfig.uPinInfo.stCANPinInfo.enRXPin, IOAPI_enCANBus, u32MuxSel); + IO_vSetIOMux(pstPortConfigCB->stPinConfig.uPinInfo.stCANPinInfo.enTXPin, IOAPI_enCANBus, u32MuxSel); + enSVCResult = SYSAPI_enOK; + } + else + { + enSVCResult = SYSAPI_enFail; + } + } + +#ifdef BUILD_ENET + else if ((EH_VIO_ENET_CH1 == enEHIOResource) + || (EH_VIO_ENET_CH2 == enEHIOResource) + || (EH_VIO_ENET_CH3 == enEHIOResource) + || (EH_VIO_ENET_CH4 == enEHIOResource)) + { + enSVCResult = ENE_enInitChannel(enEHIOResource, pstPortConfigCB); + } +#endif + + else if (EH_VIO_USB == enEHIOResource) + { + enSVCResult = VCOM_enInitBus(enEHIOResource, pstPortConfigCB); + } + + return enSVCResult; +} + +SYSAPI_tenSVCResult IO_enInitTEPMChannel(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_tstTEPMChannelCB* pstTEPMChannelCB, bool boPWMMode) +{ + SYSAPI_tenSVCResult enSVCResult = SYSAPI_enOK; + uint32 u32MuxSel; + uint32 u32Masters; + uint32 u32MasterIDX = 0; + bool boMasterOK = FALSE; + SYSAPI_ttClientHandle tMasterClientHandle; + + IO_vClearMasterList(); + u32Masters = RESM_u32GetMasterEHIOResourceList(enEHIOResource, (IOAPI_tenEHIOResource*)&IO_aenEHIOMasterList); + +#if defined(BUILD_PBL) || defined(BUILD_SBL) || defined (BUILD_KERNEL) + while (u32Masters > u32MasterIDX) + { + tMasterClientHandle = RESM_u32GetMasterEHIOResource(IO_aenEHIOMasterList[u32MasterIDX]); + if (OS_stSVCDataStruct.tClientHandle != tMasterClientHandle) + { + if (0 == tMasterClientHandle) + { + enSVCResult = SYSAPI_enMasterResourceUninitialised; + } + else + { + enSVCResult = SYSAPI_enMasterResourceMismatch; + } + boMasterOK = FALSE; + OS_stSVCDataStruct.pvData = (void*)&IO_aenEHIOMasterList; + } + u32MasterIDX++; + } + + u32MuxSel = TEPM_u32InitTEPMChannel(enEHIOResource, pstTEPMChannelCB); +#endif + +#ifdef BUILD_KERNEL_APP + while (u32Masters > u32MasterIDX) + { + tMasterClientHandle = RESM_u32GetMasterEHIOResource(IO_aenEHIOMasterList[u32MasterIDX]); + if (OS_stSVCDataStruct.tClientHandle != tMasterClientHandle) + { + if (0 == tMasterClientHandle) + { + enSVCResult = SYSAPI_enMasterResourceUninitialised; + } + else + { + enSVCResult = SYSAPI_enMasterResourceMismatch; + } + boMasterOK = FALSE; + OS_stSVCDataStruct.pvData = (void*)&IO_aenEHIOMasterList; + } + u32MasterIDX++; + } + + u32MuxSel = TEPM_u32InitTEPMChannel(enEHIOResource, pstTEPMChannelCB, boPWMMode); +#endif + IO_vSetIOMux(enEHIOResource, IOAPI_enTEPM, u32MuxSel); + + /* TODO suppress warning */ + (void)boMasterOK; + return enSVCResult; +} + +void IO_vAssertDIOResource(IOAPI_tenEHIOResource enIOResource, IOAPI_tenTriState enTriState) +{ + if (0u != IO_rastEHPadResource[enIOResource].u32PortBit) + /* Assert DIO only if port bit non zero signifies DIO supported */ + { + PIM_vAssertPortBit(IO_rastEHPadResource[enIOResource].enPort, IO_rastEHPadResource[enIOResource].u32PortBit, enTriState); + } +} + +bool IO_boGetDIOResource(IOAPI_tenEHIOResource enIOResource) +{ + bool boPinState; + + if (0u != IO_rastEHPadResource[enIOResource].u32PortBit) + /* Assert DIO only if port bit non zero signifies DIO supported */ + { + boPinState = PIM_boGetPortBitState(IO_rastEHPadResource[enIOResource].enPort, IO_rastEHPadResource[enIOResource].u32PortBit); + } + + return boPinState; +} + +IOAPI_tenTriState IO_enGetDIOResourceState(IOAPI_tenEHIOResource enIOResource) +{ + IOAPI_tenTriState enTriState = IOAPI_enError; + bool boBitStateHigh; + + if (0u != IO_rastEHPadResource[enIOResource].u32PortBit) + /* Assert DIO only if port bit non zero signifies DIO supported */ + { + boBitStateHigh = PIM_boGetPortBitState(IO_rastEHPadResource[enIOResource].enPort, IO_rastEHPadResource[enIOResource].u32PortBit); + enTriState = TRUE == boBitStateHigh ? IOAPI_enHigh : IOAPI_enLow; + } + + return enTriState; +} + +static void IO_vSetIOMux(IOAPI_tenEHIOResource enIOResource, IOAPI_tenEHIOType enIOType, uint32 u32MuxSel) +{ + uint32 u32PortBit = IO_rastEHPadResource[enIOResource].u32PortBit; + PIMAPI_tenPort enPort = IO_rastEHPadResource[enIOResource].enPort; + + PIM_vSetPortMux(enPort, enIOType, u32PortBit, u32MuxSel); +} + +static void IO_vClearMasterList(void) +{ + uint32 u32MasterIDX; + + for (u32MasterIDX = 0; u32MasterIDX < RESM_nMastersMax; u32MasterIDX++) + { + IO_aenEHIOMasterList[u32MasterIDX] = EH_IO_Invalid; + } +} diff --git a/source/KernelServices/KERNELIO.h b/source/KernelServices/KERNELIO.h new file mode 100644 index 0000000..33356e2 --- /dev/null +++ b/source/KernelServices/KERNELIO.h @@ -0,0 +1,213 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef KERNELIO_H +#define KERNELIO_H + +#include +#include "SYSAPI.h" +#include "IOAPI.h" +#include "PIMAPI.h" +#include "ADCAPI.h" +#include "DACAPI.h" +#include "TEPMAPI.h" + +#define KERNEL_RXD1 71 +#define KERNEL_RXD0 72 +#define KERNEL_RXDV 73 +#define KERNEL_TXEN 74 +#define KERNEL_TXD0 75 +#define KERNEL_TXD1 76 +#define KERNEL_MDIO 77 +#define KERNEL_MDC 78 +#define KERNEL_CPURX 79 +#define KERNEL_CPUTX 80 +#define KERNEL_DISCRETE_HIDDEN 11 + +typedef struct +{ + IOAPI_tenEHIOResource enEHIO; + PIMAPI_tenPort enPort; + uint32 u32PortBit; + bool boIsADSE; + bool boIsADD; + bool boIsDAC; +} IO_tstEHPadResource; + +#ifdef BUILD_MK60 +#define IO_nPadResourceMap { \ + {EH_IO_ADSE1, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_7, TRUE, FALSE, FALSE}, \ + {EH_IO_ADSE2, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_6, TRUE, FALSE, FALSE}, \ + {EH_IO_ADSE3, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_5, TRUE, FALSE, FALSE}, \ + {EH_IO_ADSE4, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_4, TRUE, FALSE, FALSE}, \ + {EH_IO_ADSE5, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_11, TRUE, FALSE, FALSE}, \ + {EH_IO_ADSE6, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_10, TRUE, FALSE, FALSE}, \ + {EH_IO_ADSE7, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_IO_ADSE8, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_IO_ADSE9, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_IO_ADSE10, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_IO_ADSE11, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_IO_ADSE12, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_IO_GPSE1, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_3, TRUE, FALSE, FALSE}, \ + {EH_IO_GPSE2, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_2, TRUE, FALSE, FALSE}, \ + {EH_IO_GPSE5, PIMAPI_enPHYS_PORT_E, PIMAPI_PORT_BIT_27, TRUE, FALSE, FALSE}, \ + {EH_IO_GPSE6, PIMAPI_enPHYS_PORT_E, PIMAPI_PORT_BIT_28, TRUE, FALSE, FALSE}, \ + {EH_IO_GPSE7, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_10, TRUE, FALSE, FALSE}, \ + {EH_IO_GPSE8, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_9, TRUE, FALSE, FALSE}, \ + {EH_IO_GPSE9, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_8, TRUE, FALSE, FALSE}, \ + {EH_IO_GPSE10, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_7, TRUE, FALSE, FALSE}, \ + {EH_I_ADD1, PIMAPI_enPortInvalid, 0u, TRUE, TRUE, FALSE}, \ + {EH_I_ADD2, PIMAPI_enPortInvalid, 0u, TRUE, TRUE, FALSE}, \ + {EH_I_ADD3, PIMAPI_enPortInvalid, 0u, TRUE, TRUE, FALSE}, \ + {EH_I_ADD4, PIMAPI_enPortInvalid, 0u, TRUE, TRUE, FALSE}, \ + {EH_I_ADD5, PIMAPI_enPortInvalid, 0u, TRUE, TRUE, FALSE}, \ + {EH_I_ADD6, PIMAPI_enPortInvalid, 0u, TRUE, TRUE, FALSE}, \ + {EH_I_ADD7, PIMAPI_enPortInvalid, 0u, TRUE, TRUE, FALSE}, \ + {EH_I_ADD8, PIMAPI_enPortInvalid, 0u, TRUE, TRUE, FALSE}, \ + {EH_IO_CAN2T, PIMAPI_enPHYS_PORT_E, PIMAPI_PORT_BIT_24, TRUE, FALSE, FALSE}, \ + {EH_IO_CAN2R, PIMAPI_enPHYS_PORT_E, PIMAPI_PORT_BIT_25, TRUE, FALSE, FALSE}, \ + {EH_I_CMP1, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_I_CMP2, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_I_CMP3, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {IO_AD_Count, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_IO_UART1_TX, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_19, TRUE, FALSE, FALSE}, \ + {EH_IO_UART1_RX, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_18, TRUE, FALSE, FALSE}, \ + {EH_IO_UART1_CTS, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_17, TRUE, FALSE, FALSE}, \ + {EH_IO_UART1_RTS, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_16, TRUE, FALSE, FALSE}, \ + {EH_IO_UART2_TX, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_15, TRUE, FALSE, FALSE}, \ + {EH_IO_UART2_RX, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_14, TRUE, FALSE, FALSE}, \ + {EH_IO_UART2_CTS, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_13, TRUE, FALSE, FALSE}, \ + {EH_IO_UART2_RTS, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_12, TRUE, FALSE, FALSE}, \ + {EH_IO_CAN1T, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_IO_CAN1R, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR1, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_7, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR2, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_6, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR3, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_5, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR4, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_4, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR5, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_3, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR6, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_2, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR7, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_1, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR8, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_0, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR9, PIMAPI_enPHYS_PORT_E, PIMAPI_PORT_BIT_9, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR10, PIMAPI_enPHYS_PORT_E, PIMAPI_PORT_BIT_10, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR11, PIMAPI_enPHYS_PORT_E, PIMAPI_PORT_BIT_11, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR12, PIMAPI_enPHYS_PORT_E, PIMAPI_PORT_BIT_12, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR13, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_4, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR14, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_3, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR15, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_2, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR16, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_1, TRUE, FALSE, FALSE}, \ + {EH_IO_IIC1_SCL, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_IO_IIC1_SDA, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_I_CMP4, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_I_CMP5, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_O_DAC1, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, TRUE}, \ + {EH_O_DAC2, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, TRUE}, \ + {EH_IO_GP3, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_8, TRUE, FALSE, FALSE}, \ + {EH_IO_GP4, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_9, TRUE, FALSE, FALSE}, \ + {EH_IO_K33A, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_IO_USB5V, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {IO_Total_Discrete_Count, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {KERNEL_RXD1, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_12, FALSE, FALSE, FALSE}, \ + {KERNEL_RXD0, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_13, FALSE, FALSE, FALSE}, \ + {KERNEL_RXDV, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_14, FALSE, FALSE, FALSE}, \ + {KERNEL_TXEN, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_15, FALSE, FALSE, FALSE}, \ + {KERNEL_TXD0, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_16, FALSE, FALSE, FALSE}, \ + {KERNEL_TXD1, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_17, FALSE, FALSE, FALSE}, \ + {KERNEL_MDIO, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_0, FALSE, FALSE, FALSE}, \ + {KERNEL_MDC, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_1, FALSE, FALSE, FALSE}, \ + {KERNEL_CPURX, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_16, FALSE, FALSE, FALSE}, \ + {KERNEL_CPUTX, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_17, FALSE, FALSE, FALSE} \ +} +#endif + +#ifdef BUILD_MK64 +#define IO_nPadResourceMap {\ + {EH_IO_GPSE1, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_17, TRUE, FALSE, FALSE}, \ + {EH_IO_GPSE2, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_0, TRUE, FALSE, FALSE}, \ + {EH_IO_GPSE3, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_0, TRUE, FALSE, FALSE}, \ + {EH_IO_GPSE4, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_1, TRUE, FALSE, FALSE}, \ + {EH_IO_GPSE5, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_3, TRUE, FALSE, FALSE}, \ + {EH_IO_GPSE6, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_2, TRUE, FALSE, FALSE}, \ + {EH_IO_GPSE7, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_4, TRUE, FALSE, FALSE}, \ + {EH_IO_GPSE8, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_5, TRUE, FALSE, FALSE}, \ + {EH_I_ADD1, PIMAPI_enPortInvalid, 0u, TRUE, TRUE, FALSE}, \ + {EH_I_ADD2, PIMAPI_enPortInvalid, 0u, TRUE, TRUE, FALSE}, \ + {EH_I_CMP1, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_6, TRUE, FALSE, FALSE}, \ + {EH_I_CMP2, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_7, TRUE, FALSE, FALSE}, \ + {IO_AD_Count, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_IO_CAN1T, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_12, FALSE, FALSE, FALSE}, \ + {EH_IO_CAN1R, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_13, FALSE, FALSE, FALSE}, \ + {EH_IO_UART1_TX, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_16, FALSE, FALSE, FALSE}, \ + {EH_IO_UART1_RX, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_17, FALSE, FALSE, FALSE}, \ + {EH_IO_UART1_CTS, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_11, TRUE, FALSE, FALSE}, \ + {EH_IO_UART1_RTS, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_10, TRUE, FALSE, FALSE}, \ + {EH_IO_UART2_TX, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_8, FALSE, FALSE, FALSE}, \ + {EH_IO_UART2_RX, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_9, FALSE, FALSE, FALSE}, \ + {EH_IO_SPI1_MISO, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_22, FALSE, FALSE, FALSE}, \ + {EH_IO_SPI1_MOSI, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_23, FALSE, FALSE, FALSE}, \ + {EH_IO_SPI1_CLK, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_21, FALSE, FALSE, FALSE}, \ + {EH_IO_SPI1_CS, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_20, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR1, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_0, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR2, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_7, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR3, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_4, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR4, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_2, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR5, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_3, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR6, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_3, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR7, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_4, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR8, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_18, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR9, PIMAPI_enPHYS_PORT_B, PIMAPI_PORT_BIT_19, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR10, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_8, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR11, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_9, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR12, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_10, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR13, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_11, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR14, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_1, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR15, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_5, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR16, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_6, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR17, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_1, TRUE, FALSE, FALSE}, \ + {EH_IO_TMR18, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_2, TRUE, FALSE, FALSE}, \ + {EH_IO_IIC1_SCL, PIMAPI_enPHYS_PORT_E, PIMAPI_PORT_BIT_24, TRUE, FALSE, FALSE}, \ + {EH_IO_IIC1_SDA, PIMAPI_enPHYS_PORT_E, PIMAPI_PORT_BIT_25, TRUE, FALSE, FALSE}, \ + {EH_O_DAC1, PIMAPI_enPortInvalid, 0u, FALSE, FALSE, TRUE}, \ + {EH_O_DAC2, PIMAPI_enPortInvalid, 0u, FALSE, FALSE, TRUE}, \ + {EH_IO_GP1, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_12, FALSE, FALSE, FALSE}, \ + {EH_IO_GP2, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_15, FALSE, FALSE, FALSE}, \ + {EH_IO_GP3, PIMAPI_enPHYS_PORT_E, PIMAPI_PORT_BIT_10, FALSE, FALSE, FALSE}, \ + {EH_IO_GP4, PIMAPI_enPHYS_PORT_E, PIMAPI_PORT_BIT_11, FALSE, FALSE, FALSE}, \ + {EH_IO_GP5, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_5, FALSE, FALSE, FALSE}, \ + {EH_IO_GP6, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_14, FALSE, FALSE, FALSE}, \ + {EH_IO_GP7, PIMAPI_enPHYS_PORT_D, PIMAPI_PORT_BIT_13, FALSE, FALSE, FALSE}, \ + {EH_IO_GP8, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_14, FALSE, FALSE, FALSE}, \ + {EH_IO_GP9, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_15, FALSE, FALSE, FALSE}, \ + {EH_IO_GP10, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_16, FALSE, FALSE, FALSE}, \ + {EH_IO_GP11, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_28, FALSE, FALSE, FALSE}, \ + {EH_IO_GP12, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_29, FALSE, FALSE, FALSE}, \ + {EH_IO_GP13, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_26, FALSE, FALSE, FALSE}, \ + {EH_IO_GP14, PIMAPI_enPHYS_PORT_C, PIMAPI_PORT_BIT_5, FALSE, FALSE, FALSE}, \ + {EH_IO_K33A, PIMAPI_enPHYS_PORT_E, PIMAPI_PORT_BIT_26, FALSE, FALSE, FALSE}, \ + {EH_IO_USB5V, PIMAPI_enPHYS_PORT_A, PIMAPI_PORT_BIT_5, FALSE, FALSE, FALSE}, \ + {IO_Total_Discrete_Count, PIMAPI_enPortInvalid, 0u, TRUE, FALSE, FALSE}, \ +} +#endif + + + + +bool IO_boGetDIOResource(IOAPI_tenEHIOResource); +IOAPI_tenTriState IO_enGetDIOResourceState(IOAPI_tenEHIOResource); +void IO_vInitDIOResource(IOAPI_tenEHIOResource, IOAPI_tenEHIOType, IOAPI_tenDriveStrength); +void IO_vAssertDIOResource(IOAPI_tenEHIOResource, IOAPI_tenTriState); +void IO_vInitADCResource(IOAPI_tenEHIOResource, IOAPI_tenEHIOType, ADCAPI_tstADCCB*); +void IO_vInitDACResource(IOAPI_tenEHIOResource, IOAPI_tenEHIOType, DACAPI_tstDACCB*); +SYSAPI_tenSVCResult IO_enInitCommsResource(IOAPI_tenEHIOResource, IOAPI_tstPortConfigCB*); +SYSAPI_tenSVCResult IO_enInitTEPMChannel(IOAPI_tenEHIOResource, TEPMAPI_tstTEPMChannelCB*, bool boPWMMode); + +#endif //KERNELIO_H + diff --git a/source/KernelServices/PACKEDDLL.c b/source/KernelServices/PACKEDDLL.c new file mode 100644 index 0000000..9095953 --- /dev/null +++ b/source/KernelServices/PACKEDDLL.c @@ -0,0 +1,53 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include "DLL.h" + +void PACKEDDLL_vUnpack(DLL_tstRXDLLData* pRXFrame) +{ + pRXFrame->u8Data[0] = pRXFrame->u8Data[0] << 4 | pRXFrame->u8Data[1] >> 3; + pRXFrame->u8Data[1] = pRXFrame->u8Data[1] << 5 | pRXFrame->u8Data[2] >> 2; + pRXFrame->u8Data[2] = pRXFrame->u8Data[2] << 6 | pRXFrame->u8Data[3] >> 1; + pRXFrame->u8Data[3] = pRXFrame->u8Data[3] << 7 | pRXFrame->u8Data[4]; + pRXFrame->u8Data[4] = pRXFrame->u8Data[5] << 1 | pRXFrame->u8Data[6] >> 6; + pRXFrame->u8Data[5] = pRXFrame->u8Data[6] << 2 | pRXFrame->u8Data[7] >> 5; + pRXFrame->u8Data[6] = pRXFrame->u8Data[7] << 3 | pRXFrame->u8Data[8] >> 4; + pRXFrame->u8Data[7] = pRXFrame->u8Data[8] << 4 | pRXFrame->u8Data[9] >> 3; + pRXFrame->u8Data[8] = pRXFrame->u8Data[9] << 5 | pRXFrame->u8Data[10] >> 2; + pRXFrame->u8Data[9] = 0x7f & (pRXFrame->u8Data[10] << 6 | pRXFrame->u8Data[11]); + pRXFrame->u8DataCount = 10; +} + +void PACKEDDLL_vPack(puint8 pu8TXData) +{ + uint8 u8IDX; + + for(u8IDX = 11; u8IDX > 1; u8IDX--) + { + pu8TXData[u8IDX] = pu8TXData[u8IDX - 2]; + } + + pu8TXData[0] = 0xc0 | pu8TXData[2] >> 4; + pu8TXData[1] = 0x7f & (pu8TXData[2] << 3 | pu8TXData[3] >> 5); + pu8TXData[2] = 0x7f & (pu8TXData[3] << 2 | pu8TXData[4] >> 6); + pu8TXData[3] = 0x7f & (pu8TXData[4] << 1 | pu8TXData[5] >> 7); + pu8TXData[4] = 0x7f & (pu8TXData[5]); + pu8TXData[5] = 0x7f & (pu8TXData[6] >> 1); + pu8TXData[6] = 0x7f & (pu8TXData[6] << 6 | pu8TXData[7] >> 2); + pu8TXData[7] = 0x7f & (pu8TXData[7] << 5 | pu8TXData[8] >> 3); + pu8TXData[8] = 0x7f & (pu8TXData[8] << 4 | pu8TXData[9] >> 4); + pu8TXData[9] = 0x7f & (pu8TXData[9] << 3 | pu8TXData[10] >> 5); + pu8TXData[10] = 0x7f & (pu8TXData[10] << 2 | pu8TXData[11] >> 6); + pu8TXData[11] = 0xbf & (pu8TXData[11] | 0x80); + +} + diff --git a/source/KernelServices/PACKEDDLL.h b/source/KernelServices/PACKEDDLL.h new file mode 100644 index 0000000..7927019 --- /dev/null +++ b/source/KernelServices/PACKEDDLL.h @@ -0,0 +1,21 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef PACKEDDLL_H +#define PACKEDDLL_H + +#define TXRX_MSB_DELIM_SIZE 12u + +void PACKEDDLL_vPack(puint8); +void PACKEDDLL_vUnpack(DLL_tstRXDLLData*); + +#endif //PACKEDDLL_H + diff --git a/source/KernelServices/PIM.c b/source/KernelServices/PIM.c new file mode 100644 index 0000000..6ca1863 --- /dev/null +++ b/source/KernelServices/PIM.c @@ -0,0 +1,59 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: PIM Port Integration Module purpose is to provide */ +/* bit I/O service to the application layer */ +/* DESCRIPTION: */ +/* FILE NAME: PIM.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include "OS.h" +#include "PIM.h" +#include "PIMHA.h" + + +void PIM_vStart(uint32* const u32Stat) +{ + PIMHA_vStart(u32Stat); + OS_xModuleStartOK(*u32Stat); +} + +void PIM_vRun(uint32* const u32Stat) +{ + +} + +void PIM_vTerminate(uint32* const u32Stat) +{ + +} + +void PIM_vInitPortBit(PIMAPI_tenPort enPort, IOAPI_tenEHIOType enIOType, uint32 u32PortBit) +{ + PIMHA_vInitPortBit(enPort, enIOType, u32PortBit); +} + +void PIM_vAssertPortBit(PIMAPI_tenPort enPort, uint32 u32PortBit, IOAPI_tenTriState enTriState) +{ + PIMHA_vAssertPortBit(enPort, u32PortBit, enTriState); +} + + +bool PIM_boGetPortBitState(PIMAPI_tenPort enPort, uint32 u32PortBit) +{ + return PIMHA_boGetPortBitState(enPort, u32PortBit); +} + +void PIM_vSetPortMux(PIMAPI_tenPort enPort, IOAPI_tenEHIOType enIOType, uint32 u32PortBit, uint32 u32MuxSel) +{ + PIMHA_vSetPortMux(enPort, enIOType, u32PortBit, u32MuxSel); +} + + + + + + diff --git a/source/KernelServices/PIM.h b/source/KernelServices/PIM.h new file mode 100644 index 0000000..12706d6 --- /dev/null +++ b/source/KernelServices/PIM.h @@ -0,0 +1,28 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: PIM Header File */ +/* DESCRIPTION: Port Integration Module */ +/* FILE NAME: PIM.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef PIM_H +#define PIM_H + +#include "types.h" +#include "PIMAPI.h" +#include "IOAPI.h" + +void PIM_vStart(uint32* const); +void PIM_vRun(uint32* const); +void PIM_vTerminate(uint32* const); +void PIM_vInitPortBit(PIMAPI_tenPort, IOAPI_tenEHIOType, uint32); +void PIM_vAssertPortBit(PIMAPI_tenPort, uint32, IOAPI_tenTriState); +void PIM_vSetPortMux(PIMAPI_tenPort, IOAPI_tenEHIOType, uint32, uint32); +bool PIM_boGetPortBitState(PIMAPI_tenPort, uint32); + +#endif //PIM_H + diff --git a/source/KernelServices/PIMHA.c b/source/KernelServices/PIMHA.c new file mode 100644 index 0000000..f488bde --- /dev/null +++ b/source/KernelServices/PIMHA.c @@ -0,0 +1,213 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include +#include "CPUAbstract.h" +#include "regset.h" +#include "sys.h" +#include "declarations.h" +#include "os.h" +#include "PIMHA.h" +#include "SIM.h" +#include "PIMAPI.h" +#include "regset.h" +#include "MATH.h" +#include "IOAPI.h" + +const REGSET_tstReg32Val PIMHA_rastPIMReg32Val[] = PIMHA_nReg32Set; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +tstPortModule* PIMHA_rapstPIMPortTypeMap[] = PIMHA_nPortPointerMap; +tstGPIOModule* PIMHA_rapstPIMGPIOTypeMap[] = PIMHA_nGPIOPointerMap; +uint32 PIM_u32PortClockRequested; +#endif //BUILD_MK60 + +#ifdef BUILD_SAM3X8E + +#endif //SAM3X8E + +#if defined BUILD_MK60 +#include "mk60f12.h" +typedef GPIO_Type tstGPIOModule; +#endif + +#if defined BUILD_MK64 +#include "mk64f12.h" +typedef GPIO_Type tstGPIOModule; +#endif + + +#if defined(BUILD_SAM3X8E) +#include "sam3x8e.h" +typedef struct Pio tstGPIOModule; +#endif + +const uint32 PIMHA_rau32PIMClockMasks[] = PIMHA_nPortClockMasks; + + +void PIMHA_vStart(uint32* const u32Stat) +{ +#if defined(BUILD_MK60) || defined(BUILD_MK64) + /* Request Kernel required port clocks */ + PIMHA_xRequestPortClock(SIM_SCGC5_PORTA_MASK); + PIMHA_xRequestPortClock(SIM_SCGC5_PORTB_MASK); + PIMHA_xRequestPortClock(SIM_SCGC5_PORTC_MASK); + PIMHA_xRequestPortClock(SIM_SCGC5_PORTD_MASK); /* TODO not kernel required! */ + PIMHA_xRequestPortClock(SIM_SCGC5_PORTE_MASK); +#endif + +#ifdef BUILD_SAM3X8E + PIMHA_xRequestPortClock(PIOA_IRQn); + PIMHA_xRequestPortClock(PIOB_IRQn); + PIMHA_xRequestPortClock(PIOC_IRQn); + PIMHA_xRequestPortClock(PIOD_IRQn); +#endif //BUILD_SAM3X8E + +#ifdef BUILD_MK60 + REGSET_vInitReg32(&PIMHA_rastPIMReg32Val[0]); +#endif //BUILD_MK60 +} + + +void PIMHA_vInitPortBit(PIMAPI_tenPort enPort, IOAPI_tenEHIOType enIOType, uint32 u32PortBit) +{ + //if (0 == (PIMHA_rau32PIMClockMasks[enPort] & PIM_u32PortClockRequested)) + /* Request the port clock if not yet requested */ + //{ + // PIMHA_xRequestPortClock(PIM_rau32PIMClockMasks[enPort]); + //} + + PIMHA_vSetPortMux(enPort, enIOType, u32PortBit, 1); +} + +void PIMHA_vAssertPortBit(PIMAPI_tenPort enPort, uint32 u32PortBit, IOAPI_tenTriState enTriState) +{ + switch (enTriState) + { + case IOAPI_enLow: + { +#if defined(BUILD_MK60) || defined(BUILD_MK64) + tstGPIOModule* pstGPIO = PIMHA_rapstPIMGPIOTypeMap[enPort]; + pstGPIO->PDDR |= u32PortBit; + pstGPIO->PCOR = u32PortBit; +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + tstGPIOModule* pstGPIO = (tstGPIOModule*)PIMHA_rapstPIMGPIOTypeMap[enPort]; + pstGPIO->PIO_CODR = u32PortBit; +#endif //BUILD_SAM3X8E + break; + } + case IOAPI_enHigh: + { +#if defined(BUILD_MK60) || defined(BUILD_MK64) + tstGPIOModule* pstGPIO = PIMHA_rapstPIMGPIOTypeMap[enPort]; + pstGPIO->PDDR |= u32PortBit; + pstGPIO->PSOR = u32PortBit; +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + tstGPIOModule* pstGPIO = PIMHA_rapstPIMPortTypeMap[enPort]; + pstGPIO->PIO_SODR = u32PortBit; +#endif //BUILD_SAM3X8E + break; + } + case IOAPI_enToggle: + { +#if defined(BUILD_MK60) || defined(BUILD_MK64) + volatile tstGPIOModule* pstGPIO = PIMHA_rapstPIMGPIOTypeMap[enPort]; + pstGPIO->PDDR |= u32PortBit; + pstGPIO->PTOR = u32PortBit; +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + tstGPIOModule* pstGPIO = (tstGPIOModule*)PIMHA_rapstPIMGPIOTypeMap[enPort]; + if (0 < (u32PortBit & pstGPIO->PIO_ODSR)) + { + pstGPIO->PIO_CODR = u32PortBit; + } + else + { + pstGPIO->PIO_SODR = u32PortBit; + } +#endif //BUILD_SAM3X8E + break; + } + case IOAPI_enHiZ: + { +#if defined(BUILD_MK60) || defined(BUILD_MK64) + tstGPIOModule* pstGPIO = PIMHA_rapstPIMGPIOTypeMap[enPort]; + pstGPIO->PDDR &= ~u32PortBit; + pstGPIO->PCOR = u32PortBit; +#endif //BUILD_MK6X + break; + } + default: + { + + } + } +} + +bool PIMHA_boGetPortBitState(PIMAPI_tenPort enPort, uint32 u32PortBit) +{ + bool boBitHigh = false; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + volatile tstGPIOModule* pstGPIO = (tstGPIOModule*)PIMHA_rapstPIMGPIOTypeMap[enPort]; + boBitHigh = 0 < ((pstGPIO->PDIR) & u32PortBit); +#endif //BUILD_MK6X + + +#ifdef BUILD_SAM3X8E + tstGPIOModule* pstGPIO = (tstGPIOModule*)PIMHA_rapstPIMGPIOTypeMap[enPort]; + boBitHigh = (0 < (pstGPIO->PIO_PDSR & u32PortBit)) ? TRUE : FALSE; +#endif //BUILD_SAM3X8E + + + + return boBitHigh; +} + +void PIMHA_vSetPortMux(PIMAPI_tenPort enPort, IOAPI_tenEHIOType enIOType, uint32 u32PortBit, uint32 u32MuxSel) +{ +#if defined(BUILD_MK60) || defined(BUILD_MK64) + uint16 u16PortBit = MATH_u32MaskToIDX(u32PortBit); + volatile tstPortModule* pstPort = (tstPortModule*)PIMHA_rapstPIMPortTypeMap[enPort]; + uint16 u16RegOffset = offsetof(tstPortModule, PCR[u16PortBit]); + *(puint32)((uint32)pstPort + (uint32)u16RegOffset) &= ~PORT_PCR_MUX_MASK; + *(puint32)((uint32)pstPort + (uint32)u16RegOffset) |= PORT_PCR_MUX(u32MuxSel); +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + tstGPIOModule* pstPort = (tstGPIOModule*)PIMHA_rapstPIMGPIOTypeMap[enPort]; + pio_type_t pio_type; + + switch (enIOType) + { + case IOAPI_enDIOOutput: pio_type = PIO_OUTPUT_0; break; + case IOAPI_enDIOInput: pio_type = PIO_INPUT; break; + case IOAPI_enTEPM: pio_type = u32MuxSel == 0 ? PIO_PERIPH_A : PIO_PERIPH_B; break; + case IOAPI_enSPIBus: pio_type = u32MuxSel == 0 ? PIO_PERIPH_A : PIO_PERIPH_B; break; + case IOAPI_enCANBus: pio_type = u32MuxSel == 0 ? PIO_PERIPH_A : PIO_PERIPH_B; break; + default: pio_type = PIO_INPUT; break; + } + + pio_configure(pstPort, pio_type, u32PortBit, PIO_DEFAULT); +#endif //BUILD_SAM3X8E +} + + + + + + diff --git a/source/KernelServices/PIMHA.h b/source/KernelServices/PIMHA.h new file mode 100644 index 0000000..3d87f0d --- /dev/null +++ b/source/KernelServices/PIMHA.h @@ -0,0 +1,170 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef PIMHA_H +#define PIMHA_H + +#include +#include "CPUAbstract.h" +#include "declarations.h" +#include "PIMAPI.h" +#include "build.h" + +#ifdef BUILD_SAM3X8E +#include "pio.h" +#endif + +#include "IOAPI.h" +#include "types.h" + +#if defined(BUILD_MK60) +typedef PORT_Type tstPortModule; +typedef GPIO_Type tstGPIOModule; +#endif //BUILD_MK60 + +#if defined(BUILD_MK64) +typedef PORT_Type tstPortModule; +typedef GPIO_Type tstGPIOModule; +#include "mk64f12.h" +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +typedef Pio tstGPIOModule; +#endif + +#ifdef BUILD_MK60 +#define PIMHA_nReg32Set \ +{ \ + { (volatile uint32*)(PORTB_BASE + offsetof(PORT_Type, PCR[16])), (uint32)PORT_PCR_MUX(3), REGSET_enOr }, \ + { (volatile uint32*)(PORTB_BASE + offsetof(PORT_Type, PCR[17])), (uint32)PORT_PCR_MUX(3), REGSET_enOr }, \ + { (volatile uint32*)(PORTC_BASE + offsetof(PORT_Type, PCR[16])), (uint32)PORT_PCR_MUX(3), REGSET_enOverwrite }, \ + { (volatile uint32*)(PORTC_BASE + offsetof(PORT_Type, PCR[17])), (uint32)PORT_PCR_MUX(3), REGSET_enOverwrite }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[24])), (uint32)PORT_PCR_MUX(2), REGSET_enOverwrite }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[25])), (uint32)PORT_PCR_MUX(2), REGSET_enOverwrite }, \ + { NULL, 0, REGSET_enOverwrite} \ +}; +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +#define PIMHA_nReg32Set \ +{ \ + { (volatile uint32*)(PORTB_BASE + offsetof(PORT_Type, PCR[16])), (uint32)PORT_PCR_MUX(3), REGSET_enOr }, \ + { (volatile uint32*)(PORTB_BASE + offsetof(PORT_Type, PCR[17])), (uint32)PORT_PCR_MUX(3), REGSET_enOr }, \ + { (volatile uint32*)(PORTC_BASE + offsetof(PORT_Type, PCR[16])), (uint32)PORT_PCR_MUX(3), REGSET_enOverwrite }, \ + { (volatile uint32*)(PORTC_BASE + offsetof(PORT_Type, PCR[17])), (uint32)PORT_PCR_MUX(3), REGSET_enOverwrite }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[24])), (uint32)PORT_PCR_MUX(2), REGSET_enOverwrite }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[25])), (uint32)PORT_PCR_MUX(2), REGSET_enOverwrite }, \ + { NULL, 0, REGSET_enOverwrite} \ +}; +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +#define PIMHA_nReg32Set \ +{ \ + { NULL, 0, REGSET_enOverwrite} \ +}; +#endif //BUILD_SAM3X8E + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +#define PIMHA_nPortPointerMap \ +{ \ + PORTA, \ + PORTB, \ + PORTC, \ + PORTD, \ + PORTE \ +} +#endif //BUILD_MK60 + +#ifdef BUILD_SAM3X8E +#define PIMHA_nPortPointerMap \ +{ \ + {PIOA}, \ + {PIOB}, \ + {PIOC}, \ + {PIOD} \ +} +#endif //BUILD_SAM3X8E + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +#define PIMHA_nGPIOPointerMap \ +{ \ + PTA, \ + PTB, \ + PTC, \ + PTD, \ + PTE \ +} +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E +#define PIMHA_nGPIOPointerMap \ +{ \ + {PIOA}, \ + {PIOB}, \ + {PIOC}, \ + {PIOD}, \ + {PIOD} \ +} +#endif + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +#define PIMHA_nPortClockMasks \ +{ \ + SIM_SCGC5_PORTA_MASK, \ + SIM_SCGC5_PORTB_MASK, \ + SIM_SCGC5_PORTC_MASK, \ + SIM_SCGC5_PORTD_MASK, \ + SIM_SCGC5_PORTE_MASK \ +} +#endif //BUILD_MK6X + +/* The clock bit is borrowed from the IRQ# */ +#ifdef BUILD_SAM3X8E +#define PIMHA_nPortClockMasks \ +{ \ + PIOA_IRQn, \ + PIOB_IRQn, \ + PIOC_IRQn, \ + PIOD_IRQn \ +} +#endif //BUILD_MK60 + +#ifdef BUILD_MK60 +#define PIMHA_xRequestPortClock(x) \ +/* turn on PORTA clock */ \ +SIM_vSetReg32(SIM_SCGC5, x); \ +PIM_u32PortClockRequested |= x +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +#define PIMHA_xRequestPortClock(x) \ +/* turn on PORTA clock */ \ +SIM_vSetReg32(SIM_SCGC5, x); \ +PIM_u32PortClockRequested |= x +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +#define PIMHA_xRequestPortClock(x) SIMHA_boEnablePeripheralClock(x) +#endif //BUILD_SAM3X8E + + +void PIMHA_vStart(uint32* const); +void PIMHA_vRun(uint32* const); +void PIMHA_vTerminate(uint32* const); +void PIMHA_vInitPortBit(PIMAPI_tenPort, IOAPI_tenEHIOType, uint32); +void PIMHA_vAssertPortBit(PIMAPI_tenPort, uint32, IOAPI_tenTriState); +void PIMHA_vSetPortMux(PIMAPI_tenPort, IOAPI_tenEHIOType, uint32, uint32); +bool PIMHA_boGetPortBitState(PIMAPI_tenPort, uint32); + + +#endif //PIMHA_H + diff --git a/source/KernelServices/PIT.c b/source/KernelServices/PIT.c new file mode 100644 index 0000000..f178cba --- /dev/null +++ b/source/KernelServices/PIT.c @@ -0,0 +1,51 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include +#include +#include +#include "mk64f12.h" + +#include "IOAPI.h" +#include "regset.h" +#include "sys.h" +#include "declarations.h" +#include "os.h" +#include "PIT.h" +#include "IRQ.h" + +extern void PIT3_Handler(void); + +const REGSET_tstReg32Val PIT_rastPITReg32Val[] = PIT_nReg32Set; + +void PIT_vStart(uint32* const u32Stat) +{ + REGSET_vInitReg32(&PIT_rastPITReg32Val[0]); + + //Activate_IRQ(IRQ_enIRQIDX_PIT4_RTI, IRQ_enICRSoftPrio15, PIT4_RTI_Handler); /* Setup PIT3 interrupt */ + + OS_xModuleStartOK(*u32Stat); +} + +void PIT_vRun(uint32* const u32Stat) +{ + +} + +void PIT_vTerminate(uint32* const u32Stat) +{ + +} + + + + diff --git a/source/KernelServices/PIT.h b/source/KernelServices/PIT.h new file mode 100644 index 0000000..da49181 --- /dev/null +++ b/source/KernelServices/PIT.h @@ -0,0 +1,31 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef PIT_H +#define PIT_H + +#include "sys.h" + +#define PIT_TLVAL0_val (SYS_PERIOD_RTI_nS / SYS_PERIOD_OSC_nS) + +/**/ +#define PIT_nReg32Set \ +{ \ + { NULL, 0, REGSET_enOverwrite } \ +}; +/**/ + +void PIT_vStart(uint32* const); +void PIT_vRun(uint32* const); +void PIT_vTerminate(uint32* const); + +#endif //PIT_H + diff --git a/source/KernelServices/RESM.c b/source/KernelServices/RESM.c new file mode 100644 index 0000000..11d1610 --- /dev/null +++ b/source/KernelServices/RESM.c @@ -0,0 +1,106 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _RESM_C + +#include +#include +#include + +#ifdef BUILD_KERNEL_APP + +#include "IOAPI.h" +#include +#include "TEPM.h" +#include "RESM.h" + +RESM_tstResource RESM_astResource[IO_Total_Count + RES_Count]; + +void RESM_vStart(uint32* const u32Stat) +{ + uint32 u32IDX; + + for (u32IDX = 0; u32IDX < (IO_Total_Count + RES_Count); u32IDX++) + { + RESM_astResource[u32IDX].tClientHandle = (SYSAPI_ttClientHandle)NULL; + } +} + +void RESM_vRun(uint32* const u32Stat) +{ + +} + +void RESM_vTerminate(uint32* const u32Stat) +{ + +} + +SYSAPI_ttClientHandle RESM_u32RequestEHIOResource(IOAPI_tenEHIOResource enEHIO, SYSAPI_ttClientHandle tClientHandle) +{ + if ((0 == RESM_astResource[enEHIO].tClientHandle) + ||(tClientHandle == RESM_astResource[enEHIO].tClientHandle)) + { + RESM_astResource[enEHIO].tClientHandle = tClientHandle; + } + else + { + tClientHandle = 0; + } + + return tClientHandle; +} + +SYSAPI_ttClientHandle RESM_u32GetMasterEHIOResource(IOAPI_tenEHIOResource enEHIOResource) +{ + return RESM_astResource[enEHIOResource].tClientHandle; +} + +uint32 RESM_u32GetMasterEHIOResourceList(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tenEHIOResource* penEHIOResource) +{ + uint32 u32MasterCount = 0; + + switch (enEHIOResource) + { + case EH_IO_TMR1: + case EH_IO_TMR2: + case EH_IO_TMR3: + case EH_IO_TMR4: + case EH_IO_TMR5: + case EH_IO_TMR6: + case EH_IO_TMR7: + case EH_IO_TMR8: + case EH_IO_TMR9: + case EH_IO_TMR10: + case EH_IO_TMR11: + case EH_IO_TMR12: + case EH_IO_TMR13: + case EH_IO_TMR14: + case EH_IO_TMR15: + case EH_IO_TMR16: + { +#ifdef BUILD_KERNEL_OR_KERNEL_APP + TEPM_boGetMasterEHIOResourceList(enEHIOResource, penEHIOResource, &u32MasterCount); +#endif + break; + } + default: + { + break; + } + } + + return u32MasterCount; +} + + +#endif // KERNEL + diff --git a/source/KernelServices/RESM.h b/source/KernelServices/RESM.h new file mode 100644 index 0000000..5dd60e2 --- /dev/null +++ b/source/KernelServices/RESM.h @@ -0,0 +1,51 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#include "build.h" +#include "RESAPI.h" +#include "IOAPI.h" +#include "SYSAPI.h" + +#ifdef BUILD_KERNEL_APP + +#ifndef RESM_H +#define RESM_H + +#include + +typedef struct +{ + SYSAPI_ttClientHandle tClientHandle; +} RESM_tstResource; + +#define RESM_nMastersMax 10u + +#undef EXTERN +#ifdef _RESM_C + #define EXTERN +#else + #define EXTERN extern +#endif + +EXTERN SYSAPI_ttClientHandle SYSAPI_atMasterHandle[RESM_nMastersMax]; + +void RESM_vStart(uint32* const u32Stat); +void RESM_vRun(uint32* const u32Stat); +void RESM_vTerminate(uint32* const u32Stat); +SYSAPI_ttClientHandle RESM_u32RequestEHIOResource(IOAPI_tenEHIOResource, SYSAPI_ttClientHandle); +uint32 RESM_u32GetMasterEHIOResourceList(IOAPI_tenEHIOResource, IOAPI_tenEHIOResource*); +SYSAPI_ttClientHandle RESM_u32GetMasterEHIOResource(IOAPI_tenEHIOResource); + +#endif //RESM_H + +#endif // KERNEL + diff --git a/source/KernelServices/SIM.c b/source/KernelServices/SIM.c new file mode 100644 index 0000000..6eeee85 --- /dev/null +++ b/source/KernelServices/SIM.c @@ -0,0 +1,55 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: SIM */ +/* DESCRIPTION: This code is provides functions for clock register */ +/* setting in future will support low power clocking */ +/* for power modes and shutdown etc */ +/* FILE NAME: SIM.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include "mk64f12.h" +#include "SIM.h" +#include "regset.h" +#include + +static void SIM_vSetRegAddress(SIMHA_tenReg, REGSET_tstReg32Val*); +REGSET_tstReg32Val SIM_astSIMReg32Val[2]; + +void SIM_vSetReg32(SIMHA_tenReg enReg, uint32 u32RegMask) +{ + SIM_vSetRegAddress(enReg, &SIM_astSIMReg32Val[0]); + SIM_astSIMReg32Val[0].val = u32RegMask; + SIM_astSIMReg32Val[0].writeMode = REGSET_enOr; + SIM_astSIMReg32Val[1].reg = NULL; + REGSET_vInitReg32(&SIM_astSIMReg32Val[0]); +} + +void SIM_vClrReg32(SIMHA_tenReg enReg, uint32 u32RegMask) +{ + SIM_vSetRegAddress(enReg, &SIM_astSIMReg32Val[0]); + SIM_astSIMReg32Val[0].val = ~u32RegMask; + SIM_astSIMReg32Val[0].writeMode = REGSET_enAnd; + SIM_astSIMReg32Val[1].reg = NULL; + REGSET_vInitReg32(&SIM_astSIMReg32Val[0]); +} + +bool SIM_boEnablePeripheralClock(IRQn_Type IRQn) +{ + return SIMHA_boEnablePeripheralClock(IRQn); +} + +static void SIM_vSetRegAddress(SIMHA_tenReg enReg, REGSET_tstReg32Val* pstReg32Val) +{ + SIMHA_vSetRegAddress(enReg, pstReg32Val); +} + + + + + + diff --git a/source/KernelServices/SIM.h b/source/KernelServices/SIM.h new file mode 100644 index 0000000..5ef31cb --- /dev/null +++ b/source/KernelServices/SIM.h @@ -0,0 +1,29 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: SIM Header File */ +/* DESCRIPTION: This code is provides enum definitions */ +/* */ +/* FILE NAME: SIM.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#ifdef KERNEL + +#ifndef SIM_H +#define SIM_H + +#include +#include "simha.h" + + +void SIM_vSetReg32(SIMHA_tenReg, uint32); +void SIM_vClrReg32(SIMHA_tenReg, uint32); +void SIM__vSetRegAddress(SIMHA_tenReg); + +#endif // SIM_H + +#endif // KERNEL diff --git a/source/KernelServices/SIMHA.c b/source/KernelServices/SIMHA.c new file mode 100644 index 0000000..0a02714 --- /dev/null +++ b/source/KernelServices/SIMHA.c @@ -0,0 +1,161 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: SIM Hardware Adaption */ +/* DESCRIPTION: This code is provides functions for clock register */ +/* setting in future will support low power clocking */ +/* for power modes and shutdown etc */ +/* FILE NAME: SIMHA.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define SIMHA_C + +#include +#include "CPUAbstract.h" +#include "SIM.h" +#include "declarations.h" +#include "types.h" + +void SIMHA_vSetRegAddress(SIMHA_tenReg enReg, REGSET_tstReg32Val* pstReg32Val) +{ +#if defined(BUILD_MK60) + switch(enReg) + { + case SIM_SCGC1: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SCGC1)); + break; + + case SIM_SCGC2: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SCGC2)); + break; + + case SIM_SCGC3: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SCGC3)); + break; + + case SIM_SCGC4: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SCGC4)); + break; + + case SIM_SCGC5: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SCGC5)); + break; + + case SIM_SCGC6: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SCGC6)); + break; + + case SIM_SCGC7: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SCGC7)); + break; + + case SIM_SOPT1: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SOPT1)); + break; + + case SIM_SOPT2: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SOPT2)); + break; + + case SIM_SOPT4: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SOPT4)); + break; + + case SIM_SOPT5: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SOPT5)); + break; + + case SIM_SOPT6: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SOPT6)); + break; + + case SIM_SOPT7: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SOPT7)); + break; + + default: + break; + } +#endif //BUILD_MK60 + +#if defined(BUILD_MK64) + switch(enReg) + { + case SIM_SCGC1: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SCGC1)); + break; + + case SIM_SCGC2: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SCGC2)); + break; + + case SIM_SCGC3: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SCGC3)); + break; + + case SIM_SCGC4: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SCGC4)); + break; + + case SIM_SCGC5: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SCGC5)); + break; + + case SIM_SCGC6: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SCGC6)); + break; + + case SIM_SCGC7: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SCGC7)); + break; + + case SIM_SOPT1: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SOPT1)); + break; + + case SIM_SOPT2: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SOPT2)); + break; + + case SIM_SOPT4: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SOPT4)); + break; + + case SIM_SOPT5: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SOPT5)); + break; + + case SIM_SOPT7: + pstReg32Val->reg = (volatile uint32*)(SIM_BASE + offsetof(SIM_Type, SOPT7)); + break; + + default: + break; + } +#endif //BUILD_MK64 +} + +bool SIMHA_boEnablePeripheralClock(IRQn_Type IRQn) +{ +#ifdef BUILD_SAM3X8E + uint32 u32RetVal; + bool boRetVal; + + u32RetVal = pmc_enable_periph_clk(IRQn); + boRetVal = (0 == u32RetVal) ? TRUE : FALSE; + + return boRetVal; +#endif //BUILD_SAM3X8E + + return FALSE; +} + + + + + + + diff --git a/source/KernelServices/SIMHA.h b/source/KernelServices/SIMHA.h new file mode 100644 index 0000000..5226b2e --- /dev/null +++ b/source/KernelServices/SIMHA.h @@ -0,0 +1,74 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: SIM Hardware Adaption Header File */ +/* DESCRIPTION: This code is provides enum definitions */ +/* */ +/* FILE NAME: SIMHA.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef SIMHA_H +#define SIMHA_H + +#include "build.h" +#include "regset.h" + +#ifdef BUILD_SAM3X8E +#include "pmc.h" +#endif //BUILD_SAM3X8E + +#ifdef BUILD_MK60 +typedef enum +{ + SIM_SCGC1, + SIM_SCGC2, + SIM_SCGC3, + SIM_SCGC4, + SIM_SCGC5, + SIM_SCGC6, + SIM_SCGC7, + SIM_SOPT1, + SIM_SOPT2, + SIM_SOPT4, + SIM_SOPT5, + SIM_SOPT6, + SIM_SOPT7 +} SIMHA_tenReg; +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +typedef enum +{ + SIM_SCGC1, + SIM_SCGC2, + SIM_SCGC3, + SIM_SCGC4, + SIM_SCGC5, + SIM_SCGC6, + SIM_SCGC7, + SIM_SOPT1, + SIM_SOPT2, + SIM_SOPT4, + SIM_SOPT5, + SIM_SOPT6, + SIM_SOPT7 +} SIMHA_tenReg; +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +typedef enum +{ + SIM_PC0, + SIM_PC1 +} SIMHA_tenReg; +#endif //BUILD_SAM3X8E + +void SIMHA_vSetRegAddress(SIMHA_tenReg, REGSET_tstReg32Val*); +bool SIMHA_boEnablePeripheralClock(IRQn_Type); + +#endif //SIMHA_H + + diff --git a/source/KernelServices/TIMER.c b/source/KernelServices/TIMER.c new file mode 100644 index 0000000..d7a6cf9 --- /dev/null +++ b/source/KernelServices/TIMER.c @@ -0,0 +1,99 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: TIMER */ +/* DESCRIPTION: This code provides functions for kernel timers */ +/* */ +/* FILE NAME: TIMER.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include +#include +#include +#include "OS.h" +#include "TIMER.h" + +TIMER_tstTimer TIMER_stTimer[TIMER_nTimerCount]; +uint32 u32AlarmCounter; + +void TIMER_vStart(uint32* const u32Stat) +{ + uint32 u32IDX; + + for(u32IDX = 0; u32IDX < TIMER_nTimerCount; u32IDX++) + { + TIMER_stTimer[u32IDX].enState = enReset; + TIMER_stTimer[u32IDX].pfCallBack = NULL; + } + + OS_xModuleStartOK(*u32Stat); +} + +void TIMER_vRun(uint32* const u32Stat) +{ + uint32 u32IDX; + + u32AlarmCounter++; + +#ifdef BUILD_KERNEL_OR_KERNEL_APP + if (0xffffffff > OS_u32TickCounter) + { + OS_u32TickCounter++; + } +#endif + + for (u32IDX = 0; u32IDX < TIMER_nTimerCount; u32IDX++) + { + if (enPending == TIMER_stTimer[u32IDX].enState) + { + if (u32AlarmCounter == TIMER_stTimer[u32IDX].u32AlarmPoint) + { + TIMER_stTimer[u32IDX].enState = enExpired; + if(NULL != TIMER_stTimer[u32IDX].pfCallBack) + { + TIMER_stTimer[u32IDX].pfCallBack(); + } + } + } + } +} + +void TIMER_vTerminate(uint32* const u32Stat) +{ + +} + +uint32 TIMER_vConfigureAlarm(uint32 const u32DelayMs, tpfTimerCallBack pfCallBack) +{ + uint32 u32IDX; + + for(u32IDX = 0; u32IDX < TIMER_nTimerCount; u32IDX++) + { + if(enReset == TIMER_stTimer[u32IDX].enState) + { + TIMER_stTimer[u32IDX].enState = enPending; + TIMER_stTimer[u32IDX].pfCallBack = pfCallBack; + TIMER_stTimer[u32IDX].u32AlarmPoint = u32AlarmCounter + u32DelayMs; + break; + } + } + + return u32IDX; +} + +uint32 TIMER_vResetAlarm(uint32 const u32TimerIndex) +{ + return 0; +} + +uint32 TIMER_vSetAlarm(uint32 const u32DelayMs, sint32 const i32TimerIndex) +{ + TIMER_stTimer[i32TimerIndex].u32AlarmPoint = u32AlarmCounter + u32DelayMs; + TIMER_stTimer[i32TimerIndex].enState = enPending; + + return 0; +} diff --git a/source/KernelServices/TIMER.h b/source/KernelServices/TIMER.h new file mode 100644 index 0000000..509f22d --- /dev/null +++ b/source/KernelServices/TIMER.h @@ -0,0 +1,46 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: TIMER Header File */ +/* DESCRIPTION: This code provides enum definitions for kernel timers */ +/* */ +/* FILE NAME: TIMER.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef TIMER_H +#define TIMER_H + +#include +#include +#include + +#define TIMER_nTimerCount 10u + +typedef void ( *tpfTimerCallBack )( void ); + +typedef enum +{ + enReset, + enPending, + enExpired +} TIMER_tenState; + +typedef struct +{ + TIMER_tenState enState; + uint32 u32AlarmPoint; + tpfTimerCallBack pfCallBack; +} TIMER_tstTimer; + +void TIMER_vStart( uint32* const ); +void TIMER_vRun( uint32* const ); +void TIMER_vTerminate( uint32* const ); +uint32 TIMER_vConfigureAlarm( uint32 const, tpfTimerCallBack ); +uint32 TIMER_vResetAlarm( uint32 const ); +uint32 TIMER_vSetAlarm( uint32 const, sint32 const ); + +#endif // TIMER_H + diff --git a/source/KernelServices/dll.h b/source/KernelServices/dll.h new file mode 100644 index 0000000..baa160e --- /dev/null +++ b/source/KernelServices/dll.h @@ -0,0 +1,165 @@ +/******************************************************************************/ +/* data link layer header file */ +/******************************************************************************/ +/* */ +/* Copyright (c) 2013 MD Automotive Controls. All rights reserved. */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#ifndef DLL_H +#define DLL_H + +//#include "netif/ethernetif.h" +#include +#include "OS.h" +#include "IOAPI.h" + +#define RX_BUFF_SIZE 192u +#define TX_BUFF_SIZE 32u +#define RX_SEG_FRAME_UNSEG 0x00u +#define RX_SEG_FRAME_ONE 0x10u +#define RX_SEG_FRAME_SEQ 0x20u +#define TX_BUFF_COMPLETE 0xFFu +#define RX_BUFF_FULL 0xFFu +#define DLL_nTXIPBufferSize 1024u + +#define RX_BUFF_SMALL_SIZE 21u +#define DLL_ETH_SOURCE_PORT_OPEN 1 +#define DLL_ETH_SOURCE_IP_OPEN 1 + +/* Warning do NOT make the working buffer + sizes LESS than the max frame bytes!! */ +#define DLL_nIICTXWorkBuffMaxBytes 16u +#define DLL_nSPITXWorkBuffMaxBytes 16u +#define DLL_nUARTTXWorkBuffMaxBytes 24u +#define DLL_nCANTXWorkBuffMaxBytes 256u +#define DLL_nUSBTXWorkBuffMaxBytes 256u +#define DLL_nENETTXWorkBuffMaxBytes 1024u + +#define DLL_nIICTXWorkBuffCount 2u +#define DLL_nSPITXWorkBuffCount 2u +#define DLL_nUARTTXWorkBuffCount 2u +#define DLL_nCANTXWorkBuffCount 1u +#define DLL_nUSBTXWorkBuffCount 1u +#define DLL_nENETTXWorkBuffCount 1u +#define DLL_nClientTXBufferCount (DLL_nIICTXWorkBuffCount + \ + DLL_nSPITXWorkBuffCount + \ + DLL_nUARTTXWorkBuffCount + \ + DLL_nCANTXWorkBuffCount + \ + DLL_nENETTXWorkBuffCount) + +#define DLL_nIICVirtualChannelCount (EH_VIO_SPI1 - EH_VIO_IIC1) +#define DLL_nSPIVirtualChannelCount (EH_VIO_UART1 - EH_VIO_SPI1) +#define DLL_nUARTVirtualChannelCount (EH_VIO_CAN1 - EH_VIO_UART1) +#define DLL_nCANVirtualChannelCount (EH_VIO_USB - EH_VIO_CAN1) +#define DLL_nUSBVirtualChannelCount (EH_VIO_ENET_CH1 - EH_VIO_USB) +#define DLL_nENETVirtualChannelCount (EH_VIO_FTM0 - EH_VIO_ENET_CH1) + +#define DLL_nIICTXQueueByteCount (DLL_nIICTXWorkBuffMaxBytes * 2u) + 1u +#define DLL_nSPITXQueueByteCount (DLL_nSPITXWorkBuffMaxBytes * 2u) + 1u +#define DLL_nUARTTXQueueByteCount (DLL_nUARTTXWorkBuffMaxBytes * 2u) + 1u +#define DLL_nCANTXQueueByteCount (DLL_nCANTXWorkBuffMaxBytes * 2u) + 1u +#define DLL_nUSBTXQueueByteCount (DLL_nUSBTXWorkBuffMaxBytes * 2u) + 1u +#define DLL_nENETTXQueueByteCount (DLL_nENETTXWorkBuffMaxBytes * 2u) + 1u + +#define DLL_nMaxTXFrameBytes \ +{ \ + 16, \ + 16, \ + 16, \ + 16, \ + 24, \ + 24, \ + 24, \ + 24, \ + 24, \ + 24, \ + 12, \ + 256, \ + 1024, \ + 1024, \ + 1024, \ + 1024 \ +} + +#ifdef BUILD_PBL + #define DLL_xGetClientHandle() 0xf0000000 +#endif +#ifdef BUILD_SBL + #define DLL_xGetClientHandle() 0xf0000000 +#endif +#ifdef BUILD_KERNEL + #define DLL_xGetClientHandle() OS_stSVCDataStruct.tClientHandle | 0xf0000000 +#endif +#ifdef BUILD_KERNEL_APP + #define DLL_xGetClientHandle() OS_stSVCDataStruct.tClientHandle | 0xf0000000 +#endif + +#if RX_BUFF_SIZE > 256u + #warning "RX buffer size" +#endif + +#if TX_BUFF_SIZE > 256u + #warning "TX buffer size" +#endif + +#define DLL_nVirtualChannelCount (EH_VIO_FTM0 - EH_VIO_IIC1) +#define DLL_nTXBytesBufferSize 25u + +typedef void (*pfCallBackDLLToModule)(uint8*); +typedef sint32 DLL_tDLLVirtualChannel; + +typedef struct +{ + uint8 u8Data[RX_BUFF_SIZE]; + uint8 u8DataCount; + uint8 u8RXByteIDX; + uint8 biFramed : 1; + uint8 biWithCRC : 1; + uint8 biRXFull : 1; + uint8 biSpare : 5; +} DLL_tstRXDLLData; + + +typedef struct +{ + puint8 pu8TXData; + uint8 u8ByteCount; +} DLL_tstTXCB; + +typedef struct +{ + uint8 u8Data[DLL_nTXBytesBufferSize]; + uint8 u8DataCount; + uint8 u8TXByteIDX; + uint8 biFramed : 1; + uint8 biWithCRC : 1; + uint8 biTXEmpty : 1; + uint8 biSpare : 5; +} DLL_tstTXBytesDLLData; + +typedef struct +{ + uint8 u8Data[RX_BUFF_SMALL_SIZE]; + uint8* pu8RX; + uint8 u8RXRequestedCount; + uint8 u8RXReceivedCount; +} DLL_tstRXSmallBuffer; + + +DLL_tstRXDLLData* DLL_pstGetRXBuffer(IOAPI_tenEHIOResource); +void DLL_vFrameRXCB(IOAPI_tenEHIOResource, puint8); +void DLL_vStart(puint32 const); +void DLL_vRun(puint32 const); +void DLL_vTerminate(puint32 const); +void DLL_vReceiveUARTBytes(IOAPI_tenEHIOResource, DLL_tstRXDLLData*); +bool DLL_vQueueCANMessage(IOAPI_tenEHIOResource, PROTAPI_tstCANMsg*); +bool DLL_boQueueMessage(IOAPI_tenEHIOResource, puint8, uint32); +DLL_tDLLVirtualChannel DLL_tGetVirtualChannel(IOAPI_tenEHIOResource); +bool DLL_boInitDLLChannel(IOAPI_tenEHIOResource, IOAPI_tstPortConfigCB*); +IOAPI_tenPortMode DLL_enGetChannelMode(IOAPI_tenEHIOResource); +void* DLL_pvGetBuffered(IOAPI_tenEHIOResource); + +#endif // DLL_H + diff --git a/source/KernelServices/ffconf.h b/source/KernelServices/ffconf.h new file mode 100644 index 0000000..c28b96c --- /dev/null +++ b/source/KernelServices/ffconf.h @@ -0,0 +1,212 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module configuration file R0.10 (C)ChaN, 2013 +/----------------------------------------------------------------------------/ +/ +/ CAUTION! Do not forget to make clean the project after any changes to +/ the configuration options. +/ +/----------------------------------------------------------------------------*/ +#ifndef _FFCONF +#define _FFCONF 80960 /* Revision ID */ + + +/*---------------------------------------------------------------------------/ +/ Functions and Buffer Configurations +/----------------------------------------------------------------------------*/ + +#define _FS_TINY 1 /* 0:Normal or 1:Tiny */ +/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system +/ object instead of the sector buffer in the individual file object for file +/ data transfer. This reduces memory consumption 512 bytes each file object. */ + + +#define _FS_READONLY 1 /* 0:Read/Write or 1:Read only */ +/* Setting _FS_READONLY to 1 defines read only configuration. This removes +/ writing functions, f_write(), f_sync(), f_unlink(), f_mkdir(), f_chmod(), +/ f_rename(), f_truncate() and useless f_getfree(). */ + + +#define _FS_MINIMIZE 1 /* 0 to 3 */ +/* The _FS_MINIMIZE option defines minimization level to remove API functions. +/ +/ 0: All basic functions are enabled. +/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(), +/ f_truncate() and f_rename() function are removed. +/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. +/ 3: f_lseek() function is removed in addition to 2. */ + + +#define _USE_STRFUNC 0 /* 0:Disable or 1-2:Enable */ +/* To enable string functions, set _USE_STRFUNC to 1 or 2. */ + + +#define _USE_MKFS 0 /* 0:Disable or 1:Enable */ +/* To enable f_mkfs() function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ + + +#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */ +/* To enable fast seek feature, set _USE_FASTSEEK to 1. */ + + +#define _USE_LABEL 0 /* 0:Disable or 1:Enable */ +/* To enable volume label functions, set _USE_LAVEL to 1 */ + + +#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */ +/* To enable f_forward() function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ + + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/----------------------------------------------------------------------------*/ + +#define _CODE_PAGE 437 +/* The _CODE_PAGE specifies the OEM code page to be used on the target system. +/ Incorrect setting of the code page can cause a file open failure. +/ +/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows) +/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows) +/ 949 - Korean (DBCS, OEM, Windows) +/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) +/ 1250 - Central Europe (Windows) +/ 1251 - Cyrillic (Windows) +/ 1252 - Latin 1 (Windows) +/ 1253 - Greek (Windows) +/ 1254 - Turkish (Windows) +/ 1255 - Hebrew (Windows) +/ 1256 - Arabic (Windows) +/ 1257 - Baltic (Windows) +/ 1258 - Vietnam (OEM, Windows) +/ 437 - U.S. (OEM) +/ 720 - Arabic (OEM) +/ 737 - Greek (OEM) +/ 775 - Baltic (OEM) +/ 850 - Multilingual Latin 1 (OEM) +/ 858 - Multilingual Latin 1 + Euro (OEM) +/ 852 - Latin 2 (OEM) +/ 855 - Cyrillic (OEM) +/ 866 - Russian (OEM) +/ 857 - Turkish (OEM) +/ 862 - Hebrew (OEM) +/ 874 - Thai (OEM, Windows) +/ 1 - ASCII (Valid for only non-LFN cfg.) +*/ + + +#define _USE_LFN 0 /* 0 to 3 */ +#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ +/* The _USE_LFN option switches the LFN feature. +/ +/ 0: Disable LFN feature. _MAX_LFN has no effect. +/ 1: Enable LFN with static working buffer on the BSS. Always NOT reentrant. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ 3: Enable LFN with dynamic working buffer on the HEAP. +/ +/ To enable LFN feature, Unicode handling functions ff_convert() and ff_wtoupper() +/ function must be added to the project. +/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When use stack for the +/ working buffer, take care on stack overflow. When use heap memory for the working +/ buffer, memory management functions, ff_memalloc() and ff_memfree(), must be added +/ to the project. */ + + +#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */ +/* To switch the character encoding on the FatFs API to Unicode, enable LFN feature +/ and set _LFN_UNICODE to 1. */ + + +#define _STRF_ENCODE 3 /* 0:ANSI/OEM, 1:UTF-16LE, 2:UTF-16BE, 3:UTF-8 */ +/* When Unicode API is enabled, character encoding on the all FatFs API is switched +/ to Unicode. This option selects the character encoding on the file to be read/written +/ via string functions, f_gets(), f_putc(), f_puts and f_printf(). +/ This option has no effect when _LFN_UNICODE is 0. */ + + +#define _FS_RPATH 0 /* 0 to 2 */ +/* The _FS_RPATH option configures relative path feature. +/ +/ 0: Disable relative path feature and remove related functions. +/ 1: Enable relative path. f_chdrive() and f_chdir() function are available. +/ 2: f_getcwd() function is available in addition to 1. +/ +/ Note that output of the f_readdir() fnction is affected by this option. */ + + +/*---------------------------------------------------------------------------/ +/ Drive/Volume Configurations +/----------------------------------------------------------------------------*/ + +#define _VOLUMES 1 +/* Number of volumes (logical drives) to be used. */ + + +#define _MULTI_PARTITION 0 /* 0:Single partition, 1:Enable multiple partition */ +/* When set to 0, each volume is bound to the same physical drive number and +/ it can mount only first primaly partition. When it is set to 1, each volume +/ is tied to the partitions listed in VolToPart[]. */ + + +#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */ +/* Maximum sector size to be handled. +/ Always set 512 for memory card and hard disk but a larger value may be +/ required for on-board flash memory, floppy disk and optical disk. +/ When _MAX_SS is larger than 512, it configures FatFs to variable sector size +/ and GET_SECTOR_SIZE command must be implemented to the disk_ioctl() function. */ + + +#define _USE_ERASE 0 /* 0:Disable or 1:Enable */ +/* To enable sector erase feature, set _USE_ERASE to 1. Also CTRL_ERASE_SECTOR command +/ should be added to the disk_ioctl() function. */ + + +#define _FS_NOFSINFO 0 /* 0 or 1 */ +/* If you need to know the correct free space on the FAT32 volume, set this +/ option to 1 and f_getfree() function at first time after volume mount will +/ force a full FAT scan. +/ +/ 0: Load all informations in the FSINFO if available. +/ 1: Do not trust free cluster count in the FSINFO. +*/ + + + +/*---------------------------------------------------------------------------/ +/ System Configurations +/----------------------------------------------------------------------------*/ + +#define _WORD_ACCESS 1 /* 0 or 1 */ +/* The _WORD_ACCESS option is an only platform dependent option. It defines +/ which access method is used to the word data on the FAT volume. +/ +/ 0: Byte-by-byte access. Always compatible with all platforms. +/ 1: Word access. Do not choose this unless under both the following conditions. +/ +/ * Byte order on the memory is little-endian. +/ * Address miss-aligned word access is always allowed for all instructions. +/ +/ If it is the case, _WORD_ACCESS can also be set to 1 to improve performance +/ and reduce code size. +*/ + + +/* A header file that defines sync object types on the O/S, such as +/ windows.h, ucos_ii.h and semphr.h, must be included prior to ff.h. */ + +#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */ +#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ +#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */ + +/* The _FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs module. +/ +/ 0: Disable re-entrancy. _SYNC_t and _FS_TIMEOUT have no effect. +/ 1: Enable re-entrancy. Also user provided synchronization handlers, +/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() +/ function must be added to the project. */ + + +#define _FS_LOCK 0 /* 0:Disable or >=1:Enable */ +/* To enable file lock control feature, set _FS_LOCK to 1 or greater. + The value defines how many files can be opened simultaneously. */ + + +#endif /* _FFCONFIG */ diff --git a/source/KernelServices/regset.c b/source/KernelServices/regset.c new file mode 100644 index 0000000..424665c --- /dev/null +++ b/source/KernelServices/regset.c @@ -0,0 +1,175 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: REGSET */ +/* DESCRIPTION: This code is functions for register setup */ +/* */ +/* FILE NAME: REGSET.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include +#include +#include "mk64f12.h" +#include "regset.h" +#include "OS.h" + + +void REGSET_vStart(uint32* u32Stat) +{ + OS_xModuleStartOK(*u32Stat); +} + +void REGSET_vRun(uint32* const u32Stat) +{ +} + +void REGSET_vTerminate(uint32* const u32Stat) +{ + +} + + +/************************************************ +* +* Function: REGSET_vInitReg32 +* +* Inputs: list - pointer to the null terminated list of +* register:value:writemode triples. +* +* Outputs: All registers in list are set to value iaw +* write mode. +* +* Returns: None. +* +* Description: This routine navigates a list of 32 bit +* registers and set them to a default value +* and returns on NULL register pointer. +* +************************************************/ +void REGSET_vInitReg32(const REGSET_tstReg32Val* ast) +{ + while(ast->reg != NULL) + { + switch (ast->writeMode) + { + case REGSET_enOverwrite: + *ast->reg = ast->val; + break; + + case REGSET_enOr: + *ast->reg |= ast->val; + break; + + case REGSET_enAnd: + *ast->reg &= ast->val; + break; + + case REGSET_enXor: + *ast->reg ^= ast->val; + break; + + default: + break; + } + ast++; + } +} + + +/************************************************ +* +* Function: REGSET_vInitReg16 +* +* Inputs: list - pointer to the null terminated list of +* register:value:writemode triples. +* +* Outputs: All registers in list are set to value iaw +* write mode. +* +* Returns: None. +* +* Description: This routine navigates a list of 16 bit +* registers and set them to a default value +* and returns on NULL register pointer. +* +************************************************/ +void REGSET_vInitReg16(const REGSET_tstReg16Val* ast) +{ + while(ast->reg != NULL) + { + switch (ast->writeMode) + { + case REGSET_enOverwrite: + *ast->reg = ast->val; + break; + + case REGSET_enOr: + *ast->reg |= ast->val; + break; + + case REGSET_enAnd: + *ast->reg &= ast->val; + break; + + case REGSET_enXor: + *ast->reg ^= ast->val; + break; + + default: + break; + } + ast++; + } +} + +/************************************************ +* +* Function: REGSET_vInitReg8 +* +* Inputs: list - pointer to the null terminated list of +* register:value:writemode triples. +* +* Outputs: All registers in list are set to value iaw +* write mode. +* +* Returns: None. +* +* Description: This routine navigates a list of 8 bit +* registers and set them to a default value +* and returns on NULL register pointer. +* +************************************************/ +void REGSET_vInitReg8(const REGSET_tstReg8Val* ast) +{ + while(ast->reg != NULL) + { + switch (ast->writeMode) + { + case REGSET_enOverwrite: + *ast->reg = ast->val; + break; + + case REGSET_enOr: + *ast->reg |= ast->val; + break; + + case REGSET_enAnd: + *ast->reg &= ast->val; + break; + + case REGSET_enXor: + *ast->reg ^= ast->val; + break; + + default: + break; + } + ast++; + } +} + + diff --git a/source/KernelServices/regset.h b/source/KernelServices/regset.h new file mode 100644 index 0000000..58a36cb --- /dev/null +++ b/source/KernelServices/regset.h @@ -0,0 +1,57 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: REGSET Header File */ +/* DESCRIPTION: This code is definitions for register setup structs */ +/* */ +/* FILE NAME: REGSET.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef REGSET_H +#define REGSET_H + +#include +#include + +typedef enum +{ + REGSET_enOverwrite, + REGSET_enAnd, + REGSET_enOr, + REGSET_enXor +} REGSET_tenRegWriteMode; + +typedef struct +{ + volatile uint32* reg; + uint32 val; + REGSET_tenRegWriteMode writeMode; +} REGSET_tstReg32Val; + +typedef struct +{ + volatile uint16* reg; + uint16 val; + REGSET_tenRegWriteMode writeMode; +} REGSET_tstReg16Val; + +typedef struct +{ + volatile uint8* reg; + uint8 val; + REGSET_tenRegWriteMode writeMode; +} REGSET_tstReg8Val; + + +void REGSET_vStart(uint32* const); +void REGSET_vRun(uint32* const); +void REGSET_vTerminate(uint32* const); +void REGSET_vInitReg32(const REGSET_tstReg32Val*); +void REGSET_vInitReg16(const REGSET_tstReg16Val*); +void REGSET_vInitReg8(const REGSET_tstReg8Val*); + +#endif //REGSET_H + diff --git a/source/LegacyDrivers/include/FTFx_FX_256K_32K_2K_1K_1K.h b/source/LegacyDrivers/include/FTFx_FX_256K_32K_2K_1K_1K.h new file mode 100644 index 0000000..f87c178 --- /dev/null +++ b/source/LegacyDrivers/include/FTFx_FX_256K_32K_2K_1K_1K.h @@ -0,0 +1,418 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2012, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FTFx_FX_256K_32K_2K_1K_1K.h * +* DATE : June 19, 2012 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.19.2012 FPT Team Initial Version +*************************************************************************/ + +#ifndef _FTFx_FX_256K_32K_2K_1K_1K_H_ +#define _FTFx_FX_256K_32K_2K_1K_1K_H_ + +#include "SSD_FTFx_Common.h" + +#define BYTE2WORD(x) (x) + +/* Endianness */ +#define ENDIANNESS BIG_ENDIAN + +/* cpu core */ +#define CPU_CORE COLDFIRE + +/* PFlash sector size */ +#define FTFx_PSECTOR_SIZE 0x00000400 /* 1 KB size */ +/* DFlash sector size */ +#define FTFx_DSECTOR_SIZE 0x00000400 /* 1 KB size */ + +#define DEBLOCK_SIZE 0x00008000 /* 32 KB size */ +/* EEE Data Set Size Field Description */ +#define EEESIZE_0000 0x00000000 /* Reserved */ +#define EEESIZE_0001 0x00000000 /* Reserved */ +#define EEESIZE_0010 0x00000000 /* Reserved */ +#define EEESIZE_0011 0x00000800 +#define EEESIZE_0100 0x00000400 +#define EEESIZE_0101 0x00000200 +#define EEESIZE_0110 0x00000100 +#define EEESIZE_0111 0x00000080 +#define EEESIZE_1000 0x00000040 +#define EEESIZE_1001 0x00000020 +#define EEESIZE_1010 0x00000000 /* Reserved */ +#define EEESIZE_1011 0x00000000 /* Reserved */ +#define EEESIZE_1100 0x00000000 /* Reserved */ +#define EEESIZE_1101 0x00000000 /* Reserved */ +#define EEESIZE_1110 0x00000000 /* Reserved */ +#define EEESIZE_1111 0x00000000 /* Default value */ + +/* D/E-Flash Partition Code Field Description */ +#define DEPART_0000 0x00008000 +#define DEPART_0001 0x00006000 +#define DEPART_0010 0x00004000 +#define DEPART_0011 0x00000000 +#define DEPART_0100 0x00008000 /* Reserved */ +#define DEPART_0101 0x00008000 /* Reserved */ +#define DEPART_0110 0x00008000 /* Reserved */ +#define DEPART_0111 0x00008000 /* Reserved */ +#define DEPART_1000 0x00000000 +#define DEPART_1001 0x00002000 +#define DEPART_1010 0x00004000 +#define DEPART_1011 0x00008000 +#define DEPART_1100 0x00008000 /* Reserved */ +#define DEPART_1101 0x00008000 /* Reserved */ +#define DEPART_1110 0x00008000 /* Reserved */ +#define DEPART_1111 0x00008000 /* Default value */ +/*destination to read Dflash IFR area*/ +#define DFLASH_IFR_READRESOURCE_ADDRESS 0x8000FC +/* Address offset and size of PFlash IFR and DFlash IFR */ +#define PFLASH_IFR_OFFSET 0x00000000 +#define PFLASH_IFR_SIZE 0x00000100 +#define DFLASH_IFR_OFFSET 0x00000000 +#define DFLASH_IFR_SIZE 0x00000100 + +/* Size for checking alignment of a function */ +#define ERSBLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of erase block function */ +#define PGMCHK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program check function */ +#define PPGMSEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program section function on Pflash */ +#define DPGMSEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program section function on Dflash */ +#define RD1BLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify block function */ +#define SWAP_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of swap function*/ +#define PRD1SEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify section function on Pflash */ +#define DRD1SEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify section function on Dflash */ +#define RDRSRC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of read resource function */ +#define RDONCE_INDEX_MAX 0xF /* maximum index in read once command */ + +/* -------------------- Function Pointer ------------------------------- */ +typedef UINT32 (*pFLASHCOMMANDSEQUENCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* Flash initialization */ +typedef UINT32 (*pFLASHINIT) (PFLASH_SSD_CONFIG PSSDConfig); + +/* P-Flash get protection */ +typedef UINT32 (*pPFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +typedef UINT32 (*pPFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +typedef UINT32 (*pFLASHGETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +typedef UINT32 (*pFLASHSETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +typedef UINT32 (*pFLASHGETSECURITYSTATE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +typedef UINT32 (*pFLASHSECURITYBYPASS) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +typedef UINT32 (*pFLASHERASEALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +typedef UINT32 (*pFLASHERASEBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +typedef UINT32 (*pFLASHERASESECTOR) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +typedef UINT32 (*pFLASHERASESUSPEND) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +typedef UINT32 (*pFLASHERASERESUME) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +typedef UINT32 (*pFLASHPROGRAMSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +typedef UINT32 (*pFLASHCHECKSUM) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +typedef UINT32 (*pFLASHVERIFYALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +typedef UINT32 (*pFLASHVERIFYBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +typedef UINT32 (*pFLASHVERIFYSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +typedef UINT32 (*pFLASHREADONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +typedef UINT32 (*pFLASHPROGRAMONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +typedef UINT32 (*pFLASHPROGRAMCHECK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +typedef UINT32 (*pFLASHREADRESOURCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Longword */ +typedef UINT32 (*pFLASHPROGRAMLONGWORD) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* PFlash Get swap status */ +typedef UINT32 (*pPFLASHGETSWAPSTATUS) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + UINT8* pCurrentSwapMode, \ + UINT8* pCurrentSwapBlockStatus, \ + UINT8* pNextSwapBlockStatus, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Swap the two P-Flash blocks with each other */ +typedef UINT32 (*PFLASHSWAP)(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + PFLASH_SWAP_CALLBACK pSwapCallback, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* D-Flash get protection */ +typedef UINT32 (*pDFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); +/* D-Flash set protection */ +typedef UINT32 (*pDFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); + +/* EERAM get protection */ +typedef UINT32 (*pEERAMGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* EERAM set protection */ +typedef UINT32 (*pEERAMSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); +/* Flash D/E-Flash Partition */ +typedef UINT32 (*pDEFLASHPARTITION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEDataSizeCode, \ + UINT8 DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash Set EEEEnable */ +typedef UINT32 (*pSETEEEENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEEnable); + +/* EEPROM Emulator Write */ +typedef UINT32 (*pEEEWRITE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source); + +/*---------------- Function Prototypes for Flash SSD --------------------*/ + +/* Flash initialization */ +extern UINT32 FlashInit(PFLASH_SSD_CONFIG PSSDConfig); + +/* Internal function. Called by driver APIs only */ +/* Flash command sequence */ +extern UINT32 FlashCommandSequence(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* P-Flash get protection */ +extern UINT32 PFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +extern UINT32 PFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +extern UINT32 FlashGetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +extern UINT32 FlashSetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +extern UINT32 FlashGetSecurityState(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +extern UINT32 FlashSecurityBypass(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +extern UINT32 FlashEraseAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +extern UINT32 FlashEraseBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +extern UINT32 FlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +extern UINT32 FlashEraseSuspend(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +extern UINT32 FlashEraseResume(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +extern UINT32 FlashProgramSection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +extern UINT32 FlashCheckSum(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +extern UINT32 FlashVerifyAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +extern UINT32 FlashVerifyBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +extern UINT32 FlashVerifySection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +extern UINT32 FlashReadOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +extern UINT32 FlashProgramOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +extern UINT32 FlashProgramCheck(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +extern UINT32 FlashReadResource(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Longword */ +extern UINT32 FlashProgramLongword(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Get Swap status of P-Flash */ +extern UINT32 PFlashGetSwapStatus(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + UINT8* pCurrentSwapMode, \ + UINT8* pCurrentSwapBlockStatus, \ + UINT8* pNextSwapBlockStatus, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Swap the two P-Flash blocks with each other */ +extern UINT32 PFlashSwap(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + PFLASH_SWAP_CALLBACK pSwapCallback, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* D-Flash get protection */ +extern UINT32 DFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* D-Flash set protection */ +extern UINT32 DFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); + +/* EERAM get protection */ +extern UINT32 EERAMGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* EERAM set protection */ +extern UINT32 EERAMSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); +/* Flash D/E-Flash Partition */ +extern UINT32 DEFlashPartition(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEDataSizeCode, \ + UINT8 DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash Set EEEEnable */ +extern UINT32 SetEEEEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEEnable); + +/* EEPROM Emulator Write */ +extern UINT32 EEEWrite(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source); + +#endif /* _FTFx_FX_256K_32K_2K_1K_1K_H_ */ diff --git a/source/LegacyDrivers/include/FTFx_JX_128K_32K_2K_1K_1K.h b/source/LegacyDrivers/include/FTFx_JX_128K_32K_2K_1K_1K.h new file mode 100644 index 0000000..b53aa57 --- /dev/null +++ b/source/LegacyDrivers/include/FTFx_JX_128K_32K_2K_1K_1K.h @@ -0,0 +1,389 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2012, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FTFx_JX_128K_32K_2K_1K_1K.h * +* DATE : June 19, 2012 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.19.2012 FPT Team Initial Version +*************************************************************************/ + +#ifndef _FTFx_JX_128K_32K_2K_1K_1K_H_ +#define _FTFx_JX_128K_32K_2K_1K_1K_H_ + +#include "SSD_FTFx_Common.h" + +#define BYTE2WORD(x) (x) + +/* Endianness */ +#define ENDIANNESS BIG_ENDIAN + +/* cpu core */ +#define CPU_CORE COLDFIRE + +/* PFlash sector size */ +#define FTFx_PSECTOR_SIZE 0x00000400 /* 1 KB size */ +/* DFlash sector size */ +#define FTFx_DSECTOR_SIZE 0x00000400 /* 1 KB size */ + +#define DEBLOCK_SIZE 0x00008000 /* 32 KB size */ +/* EEE Data Set Size Field Description */ +#define EEESIZE_0000 0x00000000 /* Reserved */ +#define EEESIZE_0001 0x00000000 /* Reserved */ +#define EEESIZE_0010 0x00000000 /* Reserved */ +#define EEESIZE_0011 0x00000800 +#define EEESIZE_0100 0x00000400 +#define EEESIZE_0101 0x00000200 +#define EEESIZE_0110 0x00000100 +#define EEESIZE_0111 0x00000080 +#define EEESIZE_1000 0x00000040 +#define EEESIZE_1001 0x00000020 +#define EEESIZE_1010 0x00000000 /* Reserved */ +#define EEESIZE_1011 0x00000000 /* Reserved */ +#define EEESIZE_1100 0x00000000 /* Reserved */ +#define EEESIZE_1101 0x00000000 /* Reserved */ +#define EEESIZE_1110 0x00000000 /* Reserved */ +#define EEESIZE_1111 0x00000000 /* Default value */ + +/* D/E-Flash Partition Code Field Description */ +#define DEPART_0000 0x00008000 +#define DEPART_0001 0x00006000 +#define DEPART_0010 0x00004000 +#define DEPART_0011 0x00000000 +#define DEPART_0100 0x00008000 /* Reserved */ +#define DEPART_0101 0x00008000 /* Reserved */ +#define DEPART_0110 0x00008000 /* Reserved */ +#define DEPART_0111 0x00008000 /* Reserved */ +#define DEPART_1000 0x00000000 +#define DEPART_1001 0x00002000 +#define DEPART_1010 0x00004000 +#define DEPART_1011 0x00008000 +#define DEPART_1100 0x00008000 /* Reserved */ +#define DEPART_1101 0x00008000 /* Reserved */ +#define DEPART_1110 0x00008000 /* Reserved */ +#define DEPART_1111 0x00008000 /* Default value */ +/*destination to read Dflash IFR area*/ +#define DFLASH_IFR_READRESOURCE_ADDRESS 0x8000FC +/* Address offset and size of PFlash IFR and DFlash IFR */ +#define PFLASH_IFR_OFFSET 0x00000000 +#define PFLASH_IFR_SIZE 0x00000100 +#define DFLASH_IFR_OFFSET 0x00000000 +#define DFLASH_IFR_SIZE 0x00000100 + +/* Size for checking alignment of a function */ +#define ERSBLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of erase block function */ +#define PGMCHK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program check function */ +#define PPGMSEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program section function on Pflash */ +#define DPGMSEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program section function on Dflash */ +#define RD1BLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify block function */ +#define SWAP_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of swap function*/ +#define PRD1SEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify section function on Pflash */ +#define DRD1SEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify section function on Dflash */ +#define RDRSRC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of read resource function */ +#define RDONCE_INDEX_MAX 0xF /* maximum index in read once command */ + +/* -------------------- Function Pointer ------------------------------- */ +typedef UINT32 (*pFLASHCOMMANDSEQUENCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* Flash initialization */ +typedef UINT32 (*pFLASHINIT) (PFLASH_SSD_CONFIG PSSDConfig); + +/* P-Flash get protection */ +typedef UINT32 (*pPFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +typedef UINT32 (*pPFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +typedef UINT32 (*pFLASHGETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +typedef UINT32 (*pFLASHSETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +typedef UINT32 (*pFLASHGETSECURITYSTATE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +typedef UINT32 (*pFLASHSECURITYBYPASS) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +typedef UINT32 (*pFLASHERASEALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +typedef UINT32 (*pFLASHERASEBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +typedef UINT32 (*pFLASHERASESECTOR) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +typedef UINT32 (*pFLASHERASESUSPEND) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +typedef UINT32 (*pFLASHERASERESUME) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +typedef UINT32 (*pFLASHPROGRAMSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +typedef UINT32 (*pFLASHCHECKSUM) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +typedef UINT32 (*pFLASHVERIFYALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +typedef UINT32 (*pFLASHVERIFYBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +typedef UINT32 (*pFLASHVERIFYSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +typedef UINT32 (*pFLASHREADONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +typedef UINT32 (*pFLASHPROGRAMONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +typedef UINT32 (*pFLASHPROGRAMCHECK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +typedef UINT32 (*pFLASHREADRESOURCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program Longword */ +typedef UINT32 (*pFLASHPROGRAMLONGWORD) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* D-Flash get protection */ +typedef UINT32 (*pDFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); +/* D-Flash set protection */ +typedef UINT32 (*pDFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); + +/* EERAM get protection */ +typedef UINT32 (*pEERAMGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* EERAM set protection */ +typedef UINT32 (*pEERAMSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); +/* Flash D/E-Flash Partition */ +typedef UINT32 (*pDEFLASHPARTITION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEDataSizeCode, \ + UINT8 DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash Set EEEEnable */ +typedef UINT32 (*pSETEEEENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEEnable); + +/* EEPROM Emulator Write */ +typedef UINT32 (*pEEEWRITE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source); +/*---------------- Function Prototypes for Flash SSD --------------------*/ + +/* Flash initialization */ +extern UINT32 FlashInit(PFLASH_SSD_CONFIG PSSDConfig); + +/* Internal function. Called by driver APIs only */ +/* Flash command sequence */ +extern UINT32 FlashCommandSequence(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* P-Flash get protection */ +extern UINT32 PFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +extern UINT32 PFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +extern UINT32 FlashGetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +extern UINT32 FlashSetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +extern UINT32 FlashGetSecurityState(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +extern UINT32 FlashSecurityBypass(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +extern UINT32 FlashEraseAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +extern UINT32 FlashEraseBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +extern UINT32 FlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +extern UINT32 FlashEraseSuspend(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +extern UINT32 FlashEraseResume(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +extern UINT32 FlashProgramSection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +extern UINT32 FlashCheckSum(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +extern UINT32 FlashVerifyAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +extern UINT32 FlashVerifyBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +extern UINT32 FlashVerifySection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +extern UINT32 FlashReadOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +extern UINT32 FlashProgramOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +extern UINT32 FlashProgramCheck(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +extern UINT32 FlashReadResource(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Longword */ +extern UINT32 FlashProgramLongword(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* D-Flash get protection */ +extern UINT32 DFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* D-Flash set protection */ +extern UINT32 DFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); + +/* EERAM get protection */ +extern UINT32 EERAMGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* EERAM set protection */ +extern UINT32 EERAMSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); +/* Flash D/E-Flash Partition */ +extern UINT32 DEFlashPartition(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEDataSizeCode, \ + UINT8 DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash Set EEEEnable */ +extern UINT32 SetEEEEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEEnable); + +/* EEPROM Emulator Write */ +extern UINT32 EEEWrite(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source); + +#endif /* _FTFx_JX_128K_32K_2K_1K_1K_H_ */ diff --git a/source/LegacyDrivers/include/FTFx_KX_(128_64_32)K_0K_0K_1K_0K.h b/source/LegacyDrivers/include/FTFx_KX_(128_64_32)K_0K_0K_1K_0K.h new file mode 100644 index 0000000..9a406c5 --- /dev/null +++ b/source/LegacyDrivers/include/FTFx_KX_(128_64_32)K_0K_0K_1K_0K.h @@ -0,0 +1,297 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2012, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FTFx_KX_(128_64_32)K_0K_0K_1K_0K.h * +* DATE : June 19, 2012 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.19.2012 FPT Team Initial Version +*************************************************************************/ + +#ifndef _FTFx_KX_128_64_32K_0K_0K_1K_0K_H_ +#define _FTFx_KX_128_64_32K_0K_0K_1K_0K_H_ + +#include "SSD_FTFx_Common.h" + +#define BYTE2WORD(x) (x) + +/* Endianness */ +#define ENDIANNESS LITTLE_ENDIAN + +/* cpu core */ +#define CPU_CORE ARM_CM4 + +/* PFlash sector size */ +#define FTFx_PSECTOR_SIZE 0x00000400 /* 1 KB size */ +/* DFlash sector size */ +#define FTFx_DSECTOR_SIZE 0x00000000 /* 0 KB size */ +#define DEBLOCK_SIZE 0x00000000 /* 0 KB size */ +/*destination to read Dflash IFR area*/ +#define DFLASH_IFR_READRESOURCE_ADDRESS 0x8000FC + +/* Address offset and size of PFlash IFR and DFlash IFR */ +#define PFLASH_IFR_OFFSET 0x00000000 +#define PFLASH_IFR_SIZE 0x00000100 +#define DFLASH_IFR_OFFSET 0xFFFFFFFF /* reserved */ +#define DFLASH_IFR_SIZE 0xFFFFFFFF /* reserved */ + +/* Size for checking alignment of a section */ +#define ERSBLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of erase block function */ +#define PGMCHK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program check function */ +#define PPGMSEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program section function */ +#define DPGMSEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program section function */ +#define RD1BLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify block function */ +#define PRD1SEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify section function */ +#define DRD1SEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify section function */ +#define SWAP_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of swap function*/ +#define RDRSRC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of read resource function */ +#define RDONCE_INDEX_MAX 0xF /* maximum index in read once command */ + +/* -------------------- Function Pointer ------------------------------- */ +typedef UINT32 (*pFLASHCOMMANDSEQUENCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* Flash initialization */ +typedef UINT32 (*pFLASHINIT) (PFLASH_SSD_CONFIG PSSDConfig); + +/* P-Flash get protection */ +typedef UINT32 (*pPFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +typedef UINT32 (*pPFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +typedef UINT32 (*pFLASHGETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +typedef UINT32 (*pFLASHSETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +typedef UINT32 (*pFLASHGETSECURITYSTATE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +typedef UINT32 (*pFLASHSECURITYBYPASS) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +typedef UINT32 (*pFLASHERASEALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +typedef UINT32 (*pFLASHERASEBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +typedef UINT32 (*pFLASHERASESECTOR) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +typedef UINT32 (*pFLASHERASESUSPEND) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +typedef UINT32 (*pFLASHERASERESUME) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +typedef UINT32 (*pFLASHPROGRAMSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +typedef UINT32 (*pFLASHCHECKSUM) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +typedef UINT32 (*pFLASHVERIFYALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +typedef UINT32 (*pFLASHVERIFYBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +typedef UINT32 (*pFLASHVERIFYSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +typedef UINT32 (*pFLASHREADONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +typedef UINT32 (*pFLASHPROGRAMONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +typedef UINT32 (*pFLASHPROGRAMCHECK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +typedef UINT32 (*pFLASHREADRESOURCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Longword */ +typedef UINT32 (*pFLASHPROGRAMLONGWORD) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/*---------------- Function Prototypes for Flash SSD --------------------*/ + +/* Flash initialization */ +extern UINT32 FlashInit(PFLASH_SSD_CONFIG PSSDConfig); + +/* Internal function. Called by driver APIs only */ +/* Flash command sequence */ +extern UINT32 FlashCommandSequence(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* P-Flash get protection */ +extern UINT32 PFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +extern UINT32 PFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +extern UINT32 FlashGetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +extern UINT32 FlashSetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +extern UINT32 FlashGetSecurityState(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +extern UINT32 FlashSecurityBypass(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +extern UINT32 FlashEraseAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +extern UINT32 FlashEraseBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +extern UINT32 FlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +extern UINT32 FlashEraseSuspend(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +extern UINT32 FlashEraseResume(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +extern UINT32 FlashProgramSection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +extern UINT32 FlashCheckSum(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +extern UINT32 FlashVerifyAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +extern UINT32 FlashVerifyBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +extern UINT32 FlashVerifySection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +extern UINT32 FlashReadOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +extern UINT32 FlashProgramOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +extern UINT32 FlashProgramCheck(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +extern UINT32 FlashReadResource(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Longword */ +extern UINT32 FlashProgramLongword(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +#endif /* _FTFx_KX_(128_64_32)K_0K_0K_1K_0K_H_ */ diff --git a/source/LegacyDrivers/include/FTFx_KX_(128_64_32)K_32K_2K_1K_1K.h b/source/LegacyDrivers/include/FTFx_KX_(128_64_32)K_32K_2K_1K_1K.h new file mode 100644 index 0000000..ec6cb49 --- /dev/null +++ b/source/LegacyDrivers/include/FTFx_KX_(128_64_32)K_32K_2K_1K_1K.h @@ -0,0 +1,393 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2012, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FTFx_KX_(128_64_32)K_32K_2K_1K_1K.h * +* DATE : June 19, 2012 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.19.2012 FPT Team Initial Version +*************************************************************************/ + +#ifndef _FTFx_KX_128_64_32K_32K_2K_1K_1K_H_ +#define _FTFx_KX_128_64_32K_32K_2K_1K_1K_H_ + +#include "SSD_FTFx_Common.h" + +#define BYTE2WORD(x) (x) + +/* Endianness */ +#define ENDIANNESS LITTLE_ENDIAN + +/* cpu core */ +#define CPU_CORE ARM_CM4 + +/* PFlash sector size */ +#define FTFx_PSECTOR_SIZE 0x00000400 /* 1 KB size */ +/* DFlash sector size */ +#define FTFx_DSECTOR_SIZE 0x00000400 /* 1 KB size */ +#define DEBLOCK_SIZE 0x00008000 /* 32 KB size */ + +/* EEE Data Set Size Field Description */ +#define EEESIZE_0000 0x00000000 /* Reserved */ +#define EEESIZE_0001 0x00000000 /* Reserved */ +#define EEESIZE_0010 0x00000000 /* Reserved */ +#define EEESIZE_0011 0x00000800 +#define EEESIZE_0100 0x00000400 +#define EEESIZE_0101 0x00000200 +#define EEESIZE_0110 0x00000100 +#define EEESIZE_0111 0x00000080 +#define EEESIZE_1000 0x00000040 +#define EEESIZE_1001 0x00000020 +#define EEESIZE_1010 0x00000000 /* Reserved */ +#define EEESIZE_1011 0x00000000 /* Reserved */ +#define EEESIZE_1100 0x00000000 /* Reserved */ +#define EEESIZE_1101 0x00000000 /* Reserved */ +#define EEESIZE_1110 0x00000000 /* Reserved */ +#define EEESIZE_1111 0x00000000 /* Default value */ + +/* D/E-Flash Partition Code Field Description */ +#define DEPART_0000 0x00008000 +#define DEPART_0001 0x00006000 +#define DEPART_0010 0x00004000 +#define DEPART_0011 0x00000000 +#define DEPART_0100 0x00008000 /* Reserved */ +#define DEPART_0101 0x00008000 /* Reserved */ +#define DEPART_0110 0x00008000 /* Reserved */ +#define DEPART_0111 0x00008000 /* Reserved */ +#define DEPART_1000 0x00000000 +#define DEPART_1001 0x00002000 +#define DEPART_1010 0x00004000 +#define DEPART_1011 0x00008000 +#define DEPART_1100 0x00008000 /* Reserved */ +#define DEPART_1101 0x00008000 /* Reserved */ +#define DEPART_1110 0x00008000 /* Reserved */ +#define DEPART_1111 0x00008000 /* Default value */ + +/*destination to read Dflash IFR area*/ +#define DFLASH_IFR_READRESOURCE_ADDRESS 0x8000FC + +/* Address offset and size of PFlash IFR and DFlash IFR */ +#define PFLASH_IFR_OFFSET 0x00000000 +#define PFLASH_IFR_SIZE 0x00000100 +#define DFLASH_IFR_OFFSET 0x00000000 +#define DFLASH_IFR_SIZE 0x00000100 + +/* Size for checking alignment of a section */ +#define ERSBLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of erase block function */ +#define PGMCHK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program check function */ +#define PPGMSEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program section function */ +#define DPGMSEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program section function */ +#define RD1BLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify block function */ +#define PRD1SEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify section function */ +#define DRD1SEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify section function */ +#define SWAP_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of swap function*/ +#define RDRSRC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of read resource function */ +#define RDONCE_INDEX_MAX 0xF /* maximum index in read once command */ + +/* -------------------- Function Pointer ------------------------------- */ +typedef UINT32 (*pFLASHCOMMANDSEQUENCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* Flash initialization */ +typedef UINT32 (*pFLASHINIT) (PFLASH_SSD_CONFIG PSSDConfig); + +/* P-Flash get protection */ +typedef UINT32 (*pPFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +typedef UINT32 (*pPFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +typedef UINT32 (*pFLASHGETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +typedef UINT32 (*pFLASHSETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +typedef UINT32 (*pFLASHGETSECURITYSTATE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +typedef UINT32 (*pFLASHSECURITYBYPASS) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +typedef UINT32 (*pFLASHERASEALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +typedef UINT32 (*pFLASHERASEBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +typedef UINT32 (*pFLASHERASESECTOR) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +typedef UINT32 (*pFLASHERASESUSPEND) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +typedef UINT32 (*pFLASHERASERESUME) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +typedef UINT32 (*pFLASHPROGRAMSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +typedef UINT32 (*pFLASHCHECKSUM) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +typedef UINT32 (*pFLASHVERIFYALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +typedef UINT32 (*pFLASHVERIFYBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +typedef UINT32 (*pFLASHVERIFYSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +typedef UINT32 (*pFLASHREADONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +typedef UINT32 (*pFLASHPROGRAMONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +typedef UINT32 (*pFLASHPROGRAMCHECK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +typedef UINT32 (*pFLASHREADRESOURCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Longword */ +typedef UINT32 (*pFLASHPROGRAMLONGWORD) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* D-Flash get protection */ +typedef UINT32 (*pDFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); +/* D-Flash set protection */ +typedef UINT32 (*pDFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); + +/* EERAM get protection */ +typedef UINT32 (*pEERAMGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* EERAM set protection */ +typedef UINT32 (*pEERAMSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); +/* Flash D/E-Flash Partition */ +typedef UINT32 (*pDEFLASHPARTITION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEDataSizeCode, \ + UINT8 DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash Set EEEEnable */ +typedef UINT32 (*pSETEEEENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEEnable); + +/* EEPROM Emulator Write */ +typedef UINT32 (*pEEEWRITE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source); + +/*---------------- Function Prototypes for Flash SSD --------------------*/ + +/* Flash initialization */ +extern UINT32 FlashInit(PFLASH_SSD_CONFIG PSSDConfig); + +/* Internal function. Called by driver APIs only */ +/* Flash command sequence */ +extern UINT32 FlashCommandSequence(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* P-Flash get protection */ +extern UINT32 PFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +extern UINT32 PFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +extern UINT32 FlashGetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +extern UINT32 FlashSetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +extern UINT32 FlashGetSecurityState(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +extern UINT32 FlashSecurityBypass(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +extern UINT32 FlashEraseAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +extern UINT32 FlashEraseBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +extern UINT32 FlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +extern UINT32 FlashEraseSuspend(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +extern UINT32 FlashEraseResume(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +extern UINT32 FlashProgramSection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +extern UINT32 FlashCheckSum(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +extern UINT32 FlashVerifyAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +extern UINT32 FlashVerifyBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +extern UINT32 FlashVerifySection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +extern UINT32 FlashReadOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +extern UINT32 FlashProgramOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +extern UINT32 FlashProgramCheck(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +extern UINT32 FlashReadResource(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Longword */ +extern UINT32 FlashProgramLongword(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* D-Flash get protection */ +extern UINT32 DFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* D-Flash set protection */ +extern UINT32 DFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); + +/* EERAM get protection */ +extern UINT32 EERAMGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* EERAM set protection */ +extern UINT32 EERAMSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); +/* Flash D/E-Flash Partition */ +extern UINT32 DEFlashPartition(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEDataSizeCode, \ + UINT8 DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash Set EEEEnable */ +extern UINT32 SetEEEEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEEnable); + +/* EEPROM Emulator Write */ +extern UINT32 EEEWrite(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source); + +#endif /* _FTFx_KX_(128_64_32)K_32K_2K_1K_1K_H_ */ diff --git a/source/LegacyDrivers/include/FTFx_KX_(256_128_64)K_32K_2K_2K_1K.h b/source/LegacyDrivers/include/FTFx_KX_(256_128_64)K_32K_2K_2K_1K.h new file mode 100644 index 0000000..2490eb3 --- /dev/null +++ b/source/LegacyDrivers/include/FTFx_KX_(256_128_64)K_32K_2K_2K_1K.h @@ -0,0 +1,420 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2012, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FTFx_KX_(256_128_64)K_32K_2K_2K_1K.h * +* DATE : June 19, 2012 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.19.2012 FPT Team Initial Version +*************************************************************************/ + +#ifndef _FTFx_KX_256_128_64K_32K_2K_2K_1K_H_ +#define _FTFx_KX_256_128_64K_32K_2K_2K_1K_H_ + +#include "SSD_FTFx_Common.h" + +#define BYTE2WORD(x) (x) + +/* Endianness */ +#define ENDIANNESS LITTLE_ENDIAN + +/* cpu core */ +#define CPU_CORE ARM_CM4 + +/* PFlash sector size */ +#define FTFx_PSECTOR_SIZE 0x00000800 /* 2 KB size */ +/* DFlash sector size */ +#define FTFx_DSECTOR_SIZE 0x00000400 /* 1 KB size */ +#define DEBLOCK_SIZE 0x00008000 /* 32 KB size */ + +/* EEE Data Set Size Field Description */ +#define EEESIZE_0000 0x00000000 /* Reserved */ +#define EEESIZE_0001 0x00000000 /* Reserved */ +#define EEESIZE_0010 0x00000000 +#define EEESIZE_0011 0x00000800 +#define EEESIZE_0100 0x00000400 +#define EEESIZE_0101 0x00000200 +#define EEESIZE_0110 0x00000100 +#define EEESIZE_0111 0x00000080 +#define EEESIZE_1000 0x00000040 +#define EEESIZE_1001 0x00000020 +#define EEESIZE_1010 0x00000000 /* Reserved */ +#define EEESIZE_1011 0x00000000 /* Reserved */ +#define EEESIZE_1100 0x00000000 /* Reserved */ +#define EEESIZE_1101 0x00000000 /* Reserved */ +#define EEESIZE_1110 0x00000000 /* Reserved */ +#define EEESIZE_1111 0x00000000 /* Default value */ + +/* D/E-Flash Partition Code Field Description */ +#define DEPART_0000 0x00008000 +#define DEPART_0001 0x00006000 +#define DEPART_0010 0x00004000 +#define DEPART_0011 0x00000000 +#define DEPART_0100 0x00008000 /* Reserved */ +#define DEPART_0101 0x00008000 /* Reserved */ +#define DEPART_0110 0x00008000 /* Reserved */ +#define DEPART_0111 0x00008000 /* Reserved */ +#define DEPART_1000 0x00000000 +#define DEPART_1001 0x00002000 +#define DEPART_1010 0x00004000 +#define DEPART_1011 0x00008000 +#define DEPART_1100 0x00008000 /* Reserved */ +#define DEPART_1101 0x00008000 /* Reserved */ +#define DEPART_1110 0x00008000 /* Reserved */ +#define DEPART_1111 0x00008000 /* Default value */ + +/*destination to read Dflash IFR area*/ +#define DFLASH_IFR_READRESOURCE_ADDRESS 0x8000FC + +/* Address offset and size of PFlash IFR and DFlash IFR */ +#define PFLASH_IFR_OFFSET 0x00000000 +#define PFLASH_IFR_SIZE 0x00000100 +#define DFLASH_IFR_OFFSET 0x00000000 +#define DFLASH_IFR_SIZE 0x00000100 + +#define ERSBLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of erase block function */ +#define PGMCHK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program check function */ +#define PPGMSEC_ALIGN_SIZE FTFx_PHRASE_SIZE /* check align of program section function */ +#define DPGMSEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program section function */ +#define RD1BLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify block function */ +#define PRD1SEC_ALIGN_SIZE FTFx_PHRASE_SIZE /* check align of verify section function */ +#define DRD1SEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify section function */ +#define SWAP_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of swap function*/ +#define RDRSRC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of read resource function */ + +#define RDONCE_INDEX_MAX 0xF /* maximum index in read once command */ + +/* -------------------- Function Pointer ------------------------------- */ +typedef UINT32 (*pFLASHCOMMANDSEQUENCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* Flash initialization */ +typedef UINT32 (*pFLASHINIT) (PFLASH_SSD_CONFIG PSSDConfig); + +/* P-Flash get protection */ +typedef UINT32 (*pPFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +typedef UINT32 (*pPFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +typedef UINT32 (*pFLASHGETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +typedef UINT32 (*pFLASHSETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +typedef UINT32 (*pFLASHGETSECURITYSTATE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +typedef UINT32 (*pFLASHSECURITYBYPASS) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +typedef UINT32 (*pFLASHERASEALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +typedef UINT32 (*pFLASHERASEBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +typedef UINT32 (*pFLASHERASESECTOR) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +typedef UINT32 (*pFLASHERASESUSPEND) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +typedef UINT32 (*pFLASHERASERESUME) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +typedef UINT32 (*pFLASHPROGRAMSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +typedef UINT32 (*pFLASHCHECKSUM) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +typedef UINT32 (*pFLASHVERIFYALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +typedef UINT32 (*pFLASHVERIFYBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +typedef UINT32 (*pFLASHVERIFYSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +typedef UINT32 (*pFLASHREADONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +typedef UINT32 (*pFLASHPROGRAMONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +typedef UINT32 (*pFLASHPROGRAMCHECK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +typedef UINT32 (*pFLASHREADRESOURCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Longword */ +typedef UINT32 (*pFLASHPROGRAMLONGWORD) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* PFlash Get swap status */ +typedef UINT32 (*pPFLASHGETSWAPSTATUS) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + UINT8* pCurrentSwapMode, \ + UINT8* pCurrentSwapBlockStatus, \ + UINT8* pNextSwapBlockStatus, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Swap the two P-Flash blocks with each other */ +typedef UINT32 (*PFLASHSWAP)(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + PFLASH_SWAP_CALLBACK pSwapCallback, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* D-Flash get protection */ +typedef UINT32 (*pDFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); +/* D-Flash set protection */ +typedef UINT32 (*pDFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); + +/* EERAM get protection */ +typedef UINT32 (*pEERAMGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* EERAM set protection */ +typedef UINT32 (*pEERAMSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); +/* Flash D/E-Flash Partition */ +typedef UINT32 (*pDEFLASHPARTITION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEDataSizeCode, \ + UINT8 DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash Set EEEEnable */ +typedef UINT32 (*pSETEEEENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEEnable); + +/* EEPROM Emulator Write */ +typedef UINT32 (*pEEEWRITE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source); + +/*---------------- Function Prototypes for Flash SSD --------------------*/ + +/* Flash initialization */ +extern UINT32 FlashInit(PFLASH_SSD_CONFIG PSSDConfig); + +/* Internal function. Called by driver APIs only */ +/* Flash command sequence */ +extern UINT32 FlashCommandSequence(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* P-Flash get protection */ +extern UINT32 PFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +extern UINT32 PFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +extern UINT32 FlashGetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +extern UINT32 FlashSetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +extern UINT32 FlashGetSecurityState(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +extern UINT32 FlashSecurityBypass(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +extern UINT32 FlashEraseAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +extern UINT32 FlashEraseBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +extern UINT32 FlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +extern UINT32 FlashEraseSuspend(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +extern UINT32 FlashEraseResume(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +extern UINT32 FlashProgramSection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +extern UINT32 FlashCheckSum(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +extern UINT32 FlashVerifyAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +extern UINT32 FlashVerifyBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +extern UINT32 FlashVerifySection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +extern UINT32 FlashReadOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +extern UINT32 FlashProgramOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +extern UINT32 FlashProgramCheck(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +extern UINT32 FlashReadResource(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Longword */ +extern UINT32 FlashProgramLongword(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Get Swap status of P-Flash */ +extern UINT32 PFlashGetSwapStatus(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + UINT8* pCurrentSwapMode, \ + UINT8* pCurrentSwapBlockStatus, \ + UINT8* pNextSwapBlockStatus, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Swap the two P-Flash blocks with each other */ +extern UINT32 PFlashSwap(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + PFLASH_SWAP_CALLBACK pSwapCallback, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* D-Flash get protection */ +extern UINT32 DFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* D-Flash set protection */ +extern UINT32 DFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); + +/* EERAM get protection */ +extern UINT32 EERAMGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* EERAM set protection */ +extern UINT32 EERAMSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); +/* Flash D/E-Flash Partition */ +extern UINT32 DEFlashPartition(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEDataSizeCode, \ + UINT8 DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash Set EEEEnable */ +extern UINT32 SetEEEEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEEnable); + +/* EEPROM Emulator Write */ +extern UINT32 EEEWrite(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source); + +#endif /* _FTFx_KX_(256_128_64)K_32K_2K_2K_1K_H_ */ diff --git a/source/LegacyDrivers/include/FTFx_KX_1024K_0K_16K_4K_0K.h b/source/LegacyDrivers/include/FTFx_KX_1024K_0K_16K_4K_0K.h new file mode 100644 index 0000000..80683a8 --- /dev/null +++ b/source/LegacyDrivers/include/FTFx_KX_1024K_0K_16K_4K_0K.h @@ -0,0 +1,325 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2012, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FTFx_KX_1024K_0K_16K_4K_0K.h * +* DATE : June 19, 2012 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.19.2012 FPT Team Initial Version +*************************************************************************/ + +#ifndef _FTFx_KX_1024K_0K_16K_4K_0K_H_ +#define _FTFx_KX_1024K_0K_16K_4K_0K_H_ + +#include "SSD_FTFx_Common.h" + +#define BYTE2WORD(x) (x) + +/* Endianness */ +#define ENDIANNESS LITTLE_ENDIAN + +/* cpu core */ +#define CPU_CORE ARM_CM4 + +/* PFlash sector size */ +#define FTFx_PSECTOR_SIZE 0x00001000 /* 4 KB size */ +/* DFlash sector size */ +#define FTFx_DSECTOR_SIZE 0x00000000 /* 0 KB size */ +#define DEBLOCK_SIZE 0x00000000 /* 0 KB size */ + +/* Address offset (compare to start addr of P/D flash) and size of PFlash IFR and DFlash IFR */ +#define PFLASH_IFR_OFFSET 0x00000000 +#define PFLASH_IFR_SIZE 0x00000400 +#define DFLASH_IFR_OFFSET 0xFFFFFFFF /* reserved */ +#define DFLASH_IFR_SIZE 0xFFFFFFFF /* reserved */ + +/*destination to read Dflash IFR area*/ +#define DFLASH_IFR_READRESOURCE_ADDRESS 0x8003F8 + +/* Size for checking alignment of a section */ +#define ERSBLK_ALIGN_SIZE FTFx_DPHRASE_SIZE /* check align of erase block function */ +#define PGMCHK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program check function */ +#define PPGMSEC_ALIGN_SIZE FTFx_DPHRASE_SIZE /* check align of program section function */ +#define DPGMSEC_ALIGN_SIZE FTFx_DPHRASE_SIZE /* check align of program section function */ +#define RD1BLK_ALIGN_SIZE FTFx_DPHRASE_SIZE /* check align of verify block function */ +#define PRD1SEC_ALIGN_SIZE FTFx_DPHRASE_SIZE /* check align of verify section function */ +#define DRD1SEC_ALIGN_SIZE FTFx_DPHRASE_SIZE /* check align of verify section function */ +#define SWAP_ALIGN_SIZE FTFx_DPHRASE_SIZE /* check align of swap function*/ +#define RDRSRC_ALIGN_SIZE FTFx_PHRASE_SIZE /* check align of read resource function */ +#define RDONCE_INDEX_MAX 0x7 /* maximum index in read once command */ + +/* -------------------- Function Pointer ------------------------------- */ +typedef UINT32 (*pFLASHCOMMANDSEQUENCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* Flash initialization */ +typedef UINT32 (*pFLASHINIT) (PFLASH_SSD_CONFIG PSSDConfig); + +/* P-Flash get protection */ +typedef UINT32 (*pPFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +typedef UINT32 (*pPFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +typedef UINT32 (*pFLASHGETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +typedef UINT32 (*pFLASHSETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +typedef UINT32 (*pFLASHGETSECURITYSTATE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +typedef UINT32 (*pFLASHSECURITYBYPASS) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +typedef UINT32 (*pFLASHERASEALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +typedef UINT32 (*pFLASHERASEBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +typedef UINT32 (*pFLASHERASESECTOR) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +typedef UINT32 (*pFLASHERASESUSPEND) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +typedef UINT32 (*pFLASHERASERESUME) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +typedef UINT32 (*pFLASHPROGRAMSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +typedef UINT32 (*pFLASHCHECKSUM) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +typedef UINT32 (*pFLASHVERIFYALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +typedef UINT32 (*pFLASHVERIFYBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +typedef UINT32 (*pFLASHVERIFYSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +typedef UINT32 (*pFLASHREADONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +typedef UINT32 (*pFLASHPROGRAMONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +typedef UINT32 (*pFLASHPROGRAMCHECK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +typedef UINT32 (*pFLASHREADRESOURCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Phrase */ +typedef UINT32 (*pFLASHPROGRAMPHRASE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* PFlash Get swap status */ +typedef UINT32 (*pPFLASHGETSWAPSTATUS) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + UINT8* pCurrentSwapMode, \ + UINT8* pCurrentSwapBlockStatus, \ + UINT8* pNextSwapBlockStatus, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Swap the two P-Flash blocks with each other */ +typedef UINT32 (*PFLASHSWAP)(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + PFLASH_SWAP_CALLBACK pSwapCallback, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/*---------------- Function Prototypes for Flash SSD --------------------*/ + +/* Flash initialization */ +extern UINT32 FlashInit(PFLASH_SSD_CONFIG PSSDConfig); + +/* Internal function. Called by driver APIs only */ +/* Flash command sequence */ +extern UINT32 FlashCommandSequence(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* P-Flash get protection */ +extern UINT32 PFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +extern UINT32 PFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +extern UINT32 FlashGetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +extern UINT32 FlashSetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +extern UINT32 FlashGetSecurityState(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +extern UINT32 FlashSecurityBypass(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +extern UINT32 FlashEraseAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +extern UINT32 FlashEraseBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +extern UINT32 FlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +extern UINT32 FlashEraseSuspend(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +extern UINT32 FlashEraseResume(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +extern UINT32 FlashProgramSection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +extern UINT32 FlashCheckSum(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +extern UINT32 FlashVerifyAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +extern UINT32 FlashVerifyBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +extern UINT32 FlashVerifySection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +extern UINT32 FlashReadOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +extern UINT32 FlashProgramOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +extern UINT32 FlashProgramCheck(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +extern UINT32 FlashReadResource(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program phrase */ +extern UINT32 FlashProgramPhrase(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Get Swap status of P-Flash */ +extern UINT32 PFlashGetSwapStatus(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + UINT8* pCurrentSwapMode, \ + UINT8* pCurrentSwapBlockStatus, \ + UINT8* pNextSwapBlockStatus, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Swap the two P-Flash blocks with each other */ +extern UINT32 PFlashSwap(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + PFLASH_SWAP_CALLBACK pSwapCallback, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +#endif /* _FTFx_KX_1024K_0K_16K_4K_0K_H_ */ diff --git a/source/LegacyDrivers/include/FTFx_KX_256K_256K_4K_2K_2K.h b/source/LegacyDrivers/include/FTFx_KX_256K_256K_4K_2K_2K.h new file mode 100644 index 0000000..a836b8c --- /dev/null +++ b/source/LegacyDrivers/include/FTFx_KX_256K_256K_4K_2K_2K.h @@ -0,0 +1,390 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2012, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FTFx_KX_256K_256K_4K_2K_2K.h * +* DATE : June 19, 2012 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.19.2012 FPT Team Initial Version +*************************************************************************/ + +#ifndef _FTFx_KX_256K_256K_4K_2K_2K_H_ +#define _FTFx_KX_256K_256K_4K_2K_2K_H_ + +#include "SSD_FTFx_Common.h" + +#define BYTE2WORD(x) (x) + +/* Endianness */ +#define ENDIANNESS LITTLE_ENDIAN + +/* cpu core */ +#define CPU_CORE ARM_CM4 + +/* PFlash sector size */ +#define FTFx_PSECTOR_SIZE 0x00000800 /* 2 KB size */ +/* DFlash sector size */ +#define FTFx_DSECTOR_SIZE 0x00000800 /* 2 KB size */ +#define DEBLOCK_SIZE 0x00040000 /* 256 KB size */ + +/* EEE Data Set Size Field Description */ +#define EEESIZE_0000 0x00000000 /* Reserved */ +#define EEESIZE_0001 0x00000000 /* Reserved */ +#define EEESIZE_0010 0x00001000 +#define EEESIZE_0011 0x00000800 +#define EEESIZE_0100 0x00000400 +#define EEESIZE_0101 0x00000200 +#define EEESIZE_0110 0x00000100 +#define EEESIZE_0111 0x00000080 +#define EEESIZE_1000 0x00000040 +#define EEESIZE_1001 0x00000020 +#define EEESIZE_1010 0x00000000 /* Reserved */ +#define EEESIZE_1011 0x00000000 /* Reserved */ +#define EEESIZE_1100 0x00000000 /* Reserved */ +#define EEESIZE_1101 0x00000000 /* Reserved */ +#define EEESIZE_1110 0x00000000 /* Reserved */ +#define EEESIZE_1111 0x00000000 /* Default value */ + +/* D/E-Flash Partition Code Field Description */ +#define DEPART_0000 0x00040000 +#define DEPART_0001 0x00040000 /* Reserved */ +#define DEPART_0010 0x0003C000 +#define DEPART_0011 0x00038000 +#define DEPART_0100 0x00030000 +#define DEPART_0101 0x00020000 +#define DEPART_0110 0x00000000 +#define DEPART_0111 0x00040000 /* Reserved */ +#define DEPART_1000 0x00000000 +#define DEPART_1001 0x00040000 /* Reserved */ +#define DEPART_1010 0x00004000 +#define DEPART_1011 0x00008000 +#define DEPART_1100 0x00010000 +#define DEPART_1101 0x00020000 +#define DEPART_1110 0x00040000 +#define DEPART_1111 0x00040000 /* Reserved */ +/*destination to read Dflash IFR area*/ +#define DFLASH_IFR_READRESOURCE_ADDRESS 0x8000FC + +/* Address offset and size of PFlash IFR and DFlash IFR */ +#define PFLASH_IFR_OFFSET 0x00000000 +#define PFLASH_IFR_SIZE 0x00000100 +#define DFLASH_IFR_OFFSET 0x00000000 +#define DFLASH_IFR_SIZE 0x00000100 + +/* Size for checking alignment of a section */ +#define ERSBLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of erase block function */ +#define PGMCHK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program check function */ +#define PPGMSEC_ALIGN_SIZE FTFx_PHRASE_SIZE /* check align of program section function */ +#define DPGMSEC_ALIGN_SIZE FTFx_PHRASE_SIZE /* check align of program section function */ +#define RD1BLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify block function */ +#define PRD1SEC_ALIGN_SIZE FTFx_PHRASE_SIZE /* check align of verify section function */ +#define DRD1SEC_ALIGN_SIZE FTFx_PHRASE_SIZE /* check align of verify section function */ +#define SWAP_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of swap function*/ +#define RDRSRC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of read resource function */ +#define RDONCE_INDEX_MAX 0xF /* maximum index in read once command */ + +/* -------------------- Function Pointer ------------------------------- */ +typedef UINT32 (*pFLASHCOMMANDSEQUENCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* Flash initialization */ +typedef UINT32 (*pFLASHINIT) (PFLASH_SSD_CONFIG PSSDConfig); + +/* P-Flash get protection */ +typedef UINT32 (*pPFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +typedef UINT32 (*pPFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +typedef UINT32 (*pFLASHGETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +typedef UINT32 (*pFLASHSETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +typedef UINT32 (*pFLASHGETSECURITYSTATE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +typedef UINT32 (*pFLASHSECURITYBYPASS) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +typedef UINT32 (*pFLASHERASEALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +typedef UINT32 (*pFLASHERASEBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +typedef UINT32 (*pFLASHERASESECTOR) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +typedef UINT32 (*pFLASHERASESUSPEND) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +typedef UINT32 (*pFLASHERASERESUME) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +typedef UINT32 (*pFLASHPROGRAMSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +typedef UINT32 (*pFLASHCHECKSUM) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +typedef UINT32 (*pFLASHVERIFYALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +typedef UINT32 (*pFLASHVERIFYBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +typedef UINT32 (*pFLASHVERIFYSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +typedef UINT32 (*pFLASHREADONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +typedef UINT32 (*pFLASHPROGRAMONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +typedef UINT32 (*pFLASHPROGRAMCHECK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +typedef UINT32 (*pFLASHREADRESOURCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program Longword */ +typedef UINT32 (*pFLASHPROGRAMLONGWORD) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* D-Flash get protection */ +typedef UINT32 (*pDFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); +/* D-Flash set protection */ +typedef UINT32 (*pDFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); + +/* EERAM get protection */ +typedef UINT32 (*pEERAMGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* EERAM set protection */ +typedef UINT32 (*pEERAMSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); +/* Flash D/E-Flash Partition */ +typedef UINT32 (*pDEFLASHPARTITION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEDataSizeCode, \ + UINT8 DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash Set EEEEnable */ +typedef UINT32 (*pSETEEEENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEEnable); + +/* EEPROM Emulator Write */ +typedef UINT32 (*pEEEWRITE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source); +/*---------------- Function Prototypes for Flash SSD --------------------*/ + +/* Flash initialization */ +extern UINT32 FlashInit(PFLASH_SSD_CONFIG PSSDConfig); + +/* Internal function. Called by driver APIs only */ +/* Flash command sequence */ +extern UINT32 FlashCommandSequence(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* P-Flash get protection */ +extern UINT32 PFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +extern UINT32 PFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +extern UINT32 FlashGetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +extern UINT32 FlashSetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +extern UINT32 FlashGetSecurityState(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +extern UINT32 FlashSecurityBypass(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +extern UINT32 FlashEraseAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +extern UINT32 FlashEraseBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +extern UINT32 FlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +extern UINT32 FlashEraseSuspend(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +extern UINT32 FlashEraseResume(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +extern UINT32 FlashProgramSection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +extern UINT32 FlashCheckSum(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +extern UINT32 FlashVerifyAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +extern UINT32 FlashVerifyBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +extern UINT32 FlashVerifySection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +extern UINT32 FlashReadOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +extern UINT32 FlashProgramOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +extern UINT32 FlashProgramCheck(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +extern UINT32 FlashReadResource(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Longword */ +extern UINT32 FlashProgramLongword(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* D-Flash get protection */ +extern UINT32 DFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* D-Flash set protection */ +extern UINT32 DFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); + +/* EERAM get protection */ +extern UINT32 EERAMGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* EERAM set protection */ +extern UINT32 EERAMSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); +/* Flash D/E-Flash Partition */ +extern UINT32 DEFlashPartition(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEDataSizeCode, \ + UINT8 DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash Set EEEEnable */ +extern UINT32 SetEEEEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEEnable); + +/* EEPROM Emulator Write */ +extern UINT32 EEEWrite(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source); + +#endif /* _FTFx_KX_256K_256K_4K_2K_2K_H_ */ diff --git a/source/LegacyDrivers/include/FTFx_KX_512K_0K_0K_2K_0K.h b/source/LegacyDrivers/include/FTFx_KX_512K_0K_0K_2K_0K.h new file mode 100644 index 0000000..ed05d14 --- /dev/null +++ b/source/LegacyDrivers/include/FTFx_KX_512K_0K_0K_2K_0K.h @@ -0,0 +1,326 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2012, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FTFx_KX_512K_0K_0K_2K_0K.h * +* DATE : June 19, 2012 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.19.2012 FPT Team Initial Version +*************************************************************************/ + +#ifndef _FTFx_KX_512K_0K_0K_2K_0K_H_ +#define _FTFx_KX_512K_0K_0K_2K_0K_H_ + +#include "SSD_FTFx_Common.h" + +#define BYTE2WORD(x) (x) + +/* Endianness */ +#define ENDIANNESS LITTLE_ENDIAN + +/* cpu core */ +#define CPU_CORE ARM_CM4 +/* PFlash sector size */ +#define FTFx_PSECTOR_SIZE 0x00000800 /* 2 KB size */ +/* DFlash sector size */ +#define FTFx_DSECTOR_SIZE 0x00000000 /* 0 KB size */ +#define DEBLOCK_SIZE 0x00000000 /* 0 KB size */ +/*destination to read Dflash IFR area*/ +#define DFLASH_IFR_READRESOURCE_ADDRESS 0x8000FC + +/* Address offset and size of PFlash IFR and DFlash IFR */ +#define PFLASH_IFR_OFFSET 0x00000000 +#define PFLASH_IFR_SIZE 0x00000100 +#define DFLASH_IFR_OFFSET 0xFFFFFFFF /* reserved */ +#define DFLASH_IFR_SIZE 0xFFFFFFFF /* reserved */ + +/* Size for checking alignment of a section */ +#define ERSBLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of erase block function */ +#define PGMCHK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program check function */ +#define PPGMSEC_ALIGN_SIZE FTFx_PHRASE_SIZE /* check align of program section function */ +#define DPGMSEC_ALIGN_SIZE FTFx_PHRASE_SIZE /* check align of program section function */ +#define RD1BLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify block function */ +#define PRD1SEC_ALIGN_SIZE FTFx_PHRASE_SIZE /* check align of verify section function */ +#define DRD1SEC_ALIGN_SIZE FTFx_PHRASE_SIZE /* check align of verify section function */ +#define SWAP_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of swap function*/ +#define RDRSRC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of read resource function */ +#define RDONCE_INDEX_MAX 0xF /* maximum index in read once command */ + + +/* -------------------- Function Pointer ------------------------------- */ +typedef UINT32 (*pFLASHCOMMANDSEQUENCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* Flash initialization */ +typedef UINT32 (*pFLASHINIT) (PFLASH_SSD_CONFIG PSSDConfig); + +/* P-Flash get protection */ +typedef UINT32 (*pPFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +typedef UINT32 (*pPFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +typedef UINT32 (*pFLASHGETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +typedef UINT32 (*pFLASHSETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +typedef UINT32 (*pFLASHGETSECURITYSTATE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +typedef UINT32 (*pFLASHSECURITYBYPASS) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +typedef UINT32 (*pFLASHERASEALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +typedef UINT32 (*pFLASHERASEBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +typedef UINT32 (*pFLASHERASESECTOR) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +typedef UINT32 (*pFLASHERASESUSPEND) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +typedef UINT32 (*pFLASHERASERESUME) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +typedef UINT32 (*pFLASHPROGRAMSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +typedef UINT32 (*pFLASHCHECKSUM) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +typedef UINT32 (*pFLASHVERIFYALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +typedef UINT32 (*pFLASHVERIFYBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +typedef UINT32 (*pFLASHVERIFYSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +typedef UINT32 (*pFLASHREADONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +typedef UINT32 (*pFLASHPROGRAMONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program check */ +typedef UINT32 (*pFLASHPROGRAMCHECK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +typedef UINT32 (*pFLASHREADRESOURCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Longword */ +typedef UINT32 (*pFLASHPROGRAMLONGWORD) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* PFlash Get swap status */ +typedef UINT32 (*pPFLASHGETSWAPSTATUS) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + UINT8* pCurrentSwapMode, \ + UINT8* pCurrentSwapBlockStatus, \ + UINT8* pNextSwapBlockStatus, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Swap the two P-Flash blocks with each other */ +typedef UINT32 (*PFLASHSWAP)(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + PFLASH_SWAP_CALLBACK pSwapCallback, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/*---------------- Function Prototypes for Flash SSD --------------------*/ + +/* Flash initialization */ +extern UINT32 FlashInit(PFLASH_SSD_CONFIG PSSDConfig); + +/* Internal function. Called by driver APIs only */ +/* Flash command sequence */ +extern UINT32 FlashCommandSequence(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* P-Flash get protection */ +extern UINT32 PFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +extern UINT32 PFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +extern UINT32 FlashGetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +extern UINT32 FlashSetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +extern UINT32 FlashGetSecurityState(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +extern UINT32 FlashSecurityBypass(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +extern UINT32 FlashEraseAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +extern UINT32 FlashEraseBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +extern UINT32 FlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +extern UINT32 FlashEraseSuspend(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +extern UINT32 FlashEraseResume(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +extern UINT32 FlashProgramSection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +extern UINT32 FlashCheckSum(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +extern UINT32 FlashVerifyAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +extern UINT32 FlashVerifyBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +extern UINT32 FlashVerifySection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +extern UINT32 FlashReadOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +extern UINT32 FlashProgramOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +extern UINT32 FlashProgramCheck(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +extern UINT32 FlashReadResource(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Longword */ +extern UINT32 FlashProgramLongword(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Get Swap status of P-Flash */ +extern UINT32 PFlashGetSwapStatus(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + UINT8* pCurrentSwapMode, \ + UINT8* pCurrentSwapBlockStatus, \ + UINT8* pNextSwapBlockStatus, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Swap the two P-Flash blocks with each other */ +extern UINT32 PFlashSwap(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + PFLASH_SWAP_CALLBACK pSwapCallback, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +#endif /* _FTFx_KX_512K_0K_0K_2K_0K_H_ */ + diff --git a/source/LegacyDrivers/include/FTFx_KX_512K_512K_16K_4K_4K.h b/source/LegacyDrivers/include/FTFx_KX_512K_512K_16K_4K_4K.h new file mode 100644 index 0000000..5d39855 --- /dev/null +++ b/source/LegacyDrivers/include/FTFx_KX_512K_512K_16K_4K_4K.h @@ -0,0 +1,420 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2012, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FTFx_KX_512K_512K_16K_4K_4K.h * +* DATE : June 19, 2012 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.19.2012 FPT Team Initial Version +*************************************************************************/ + +#ifndef _FTFx_KX_512K_512K_16K_4K_4K_H_ +#define _FTFx_KX_512K_512K_16K_4K_4K_H_ + +#include "SSD_FTFx_Common.h" + +#define BYTE2WORD(x) (x) + +/* Endianness */ +#define ENDIANNESS LITTLE_ENDIAN + +/* cpu core */ +#define CPU_CORE ARM_CM4 + +/* PFlash sector size */ +#define FTFx_PSECTOR_SIZE 0x00001000 /* 4 KB size */ +/* DFlash sector size */ +#define FTFx_DSECTOR_SIZE 0x00001000 /* 4 KB size */ +#define DEBLOCK_SIZE 0x00080000 /* 512 KB size */ + +/* EEE Data Set Size Field Description */ +#define EEESIZE_0000 0x00004000 /* 16386 bytes */ +#define EEESIZE_0001 0x00002000 /* 8192 bytes */ +#define EEESIZE_0010 0x00001000 /* 4096 bytes */ +#define EEESIZE_0011 0x00000800 /* 2048 bytes */ +#define EEESIZE_0100 0x00000400 /* 1024 bytes */ +#define EEESIZE_0101 0x00000200 /* 512 bytes */ +#define EEESIZE_0110 0x00000100 /* 256 bytes */ +#define EEESIZE_0111 0x00000080 /* 128 bytes */ +#define EEESIZE_1000 0x00000040 /* 64 bytes */ +#define EEESIZE_1001 0x00000020 /* 32 bytes */ +#define EEESIZE_1010 0x00000000 /* Reserved */ +#define EEESIZE_1011 0x00000000 /* Reserved */ +#define EEESIZE_1100 0x00000000 /* Reserved */ +#define EEESIZE_1101 0x00000000 /* Reserved */ +#define EEESIZE_1110 0x00000000 /* Reserved */ +#define EEESIZE_1111 0x00000000 /* 0 byte */ + +/* D/E-Flash Partition Code Field Description */ +#define DEPART_0000 0x00080000 /* 512 KB */ +#define DEPART_0001 0x00080000 /* Reserved */ +#define DEPART_0010 0x00080000 /* Reserved */ +#define DEPART_0011 0x00080000 /* Reserved */ +#define DEPART_0100 0x00070000 /* 448 KB */ +#define DEPART_0101 0x00060000 /* 384 KB */ +#define DEPART_0110 0x00040000 /* 256 KB */ +#define DEPART_0111 0x00000000 /* 0 KB */ +#define DEPART_1000 0x00000000 /* 0 KB */ +#define DEPART_1001 0x00080000 /* Reserved */ +#define DEPART_1010 0x00080000 /* Reserved */ +#define DEPART_1011 0x00080000 /* Reserved */ +#define DEPART_1100 0x00010000 /* 64 KB */ +#define DEPART_1101 0x00020000 /* 128 KB */ +#define DEPART_1110 0x00040000 /* 256 KB */ +#define DEPART_1111 0x00080000 /* 512 KB */ + +/* Address offset (compare to start addr of P/D flash) and size of PFlash IFR and DFlash IFR */ +#define PFLASH_IFR_OFFSET 0x00000000 +#define PFLASH_IFR_SIZE 0x00000400 +#define DFLASH_IFR_OFFSET 0x00000000 +#define DFLASH_IFR_SIZE 0x00000400 + +/*destination to read Dflash IFR area*/ +#define DFLASH_IFR_READRESOURCE_ADDRESS 0x8003F8 + +/* Size for checking alignment of a section */ +#define ERSBLK_ALIGN_SIZE FTFx_DPHRASE_SIZE /* check align of erase block function */ +#define PGMCHK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program check function */ +#define PPGMSEC_ALIGN_SIZE FTFx_DPHRASE_SIZE /* check align of program section function */ +#define DPGMSEC_ALIGN_SIZE FTFx_DPHRASE_SIZE /* check align of program section function */ +#define RD1BLK_ALIGN_SIZE FTFx_DPHRASE_SIZE /* check align of verify block function */ +#define PRD1SEC_ALIGN_SIZE FTFx_DPHRASE_SIZE /* check align of verify section function */ +#define DRD1SEC_ALIGN_SIZE FTFx_DPHRASE_SIZE /* check align of verify section function */ +#define SWAP_ALIGN_SIZE FTFx_DPHRASE_SIZE /* check align of swap function*/ +#define RDRSRC_ALIGN_SIZE FTFx_PHRASE_SIZE /* check align of read resource function */ +#define RDONCE_INDEX_MAX 0x7 /* maximum index in read once command */ + +/* -------------------- Function Pointer ------------------------------- */ +typedef UINT32 (*pFLASHCOMMANDSEQUENCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* Flash initialization */ +typedef UINT32 (*pFLASHINIT) (PFLASH_SSD_CONFIG PSSDConfig); + +/* P-Flash get protection */ +typedef UINT32 (*pPFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +typedef UINT32 (*pPFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +typedef UINT32 (*pFLASHGETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +typedef UINT32 (*pFLASHSETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +typedef UINT32 (*pFLASHGETSECURITYSTATE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +typedef UINT32 (*pFLASHSECURITYBYPASS) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +typedef UINT32 (*pFLASHERASEALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +typedef UINT32 (*pFLASHERASEBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +typedef UINT32 (*pFLASHERASESECTOR) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +typedef UINT32 (*pFLASHERASESUSPEND) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +typedef UINT32 (*pFLASHERASERESUME) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +typedef UINT32 (*pFLASHPROGRAMSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +typedef UINT32 (*pFLASHCHECKSUM) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +typedef UINT32 (*pFLASHVERIFYALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +typedef UINT32 (*pFLASHVERIFYBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +typedef UINT32 (*pFLASHVERIFYSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +typedef UINT32 (*pFLASHREADONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +typedef UINT32 (*pFLASHPROGRAMONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +typedef UINT32 (*pFLASHPROGRAMCHECK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +typedef UINT32 (*pFLASHREADRESOURCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Phrase */ +typedef UINT32 (*pFLASHPROGRAMPHRASE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* PFlash Get swap status */ +typedef UINT32 (*pPFLASHGETSWAPSTATUS) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + UINT8* pCurrentSwapMode, \ + UINT8* pCurrentSwapBlockStatus, \ + UINT8* pNextSwapBlockStatus, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Swap the two P-Flash blocks with each other */ +typedef UINT32 (*PFLASHSWAP)(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + PFLASH_SWAP_CALLBACK pSwapCallback, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* D-Flash get protection */ +typedef UINT32 (*pDFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); +/* D-Flash set protection */ +typedef UINT32 (*pDFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); + +/* EERAM get protection */ +typedef UINT32 (*pEERAMGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* EERAM set protection */ +typedef UINT32 (*pEERAMSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); +/* Flash D/E-Flash Partition */ +typedef UINT32 (*pDEFLASHPARTITION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEDataSizeCode, \ + UINT8 DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash Set EEEEnable */ +typedef UINT32 (*pSETEEEENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEEnable); + +/* EEPROM Emulator Write */ +typedef UINT32 (*pEEEWRITE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source); + +/*---------------- Function Prototypes for Flash SSD --------------------*/ + +/* Flash initialization */ +extern UINT32 FlashInit(PFLASH_SSD_CONFIG PSSDConfig); + +/* Internal function. Called by driver APIs only */ +/* Flash command sequence */ +extern UINT32 FlashCommandSequence(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* P-Flash get protection */ +extern UINT32 PFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +extern UINT32 PFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +extern UINT32 FlashGetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +extern UINT32 FlashSetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +extern UINT32 FlashGetSecurityState(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +extern UINT32 FlashSecurityBypass(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +extern UINT32 FlashEraseAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +extern UINT32 FlashEraseBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +extern UINT32 FlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +extern UINT32 FlashEraseSuspend(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +extern UINT32 FlashEraseResume(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +extern UINT32 FlashProgramSection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +extern UINT32 FlashCheckSum(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +extern UINT32 FlashVerifyAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +extern UINT32 FlashVerifyBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +extern UINT32 FlashVerifySection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +extern UINT32 FlashReadOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +extern UINT32 FlashProgramOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +extern UINT32 FlashProgramCheck(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +extern UINT32 FlashReadResource(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program phrase */ +extern UINT32 FlashProgramPhrase(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Get Swap status of P-Flash */ +extern UINT32 PFlashGetSwapStatus(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + UINT8* pCurrentSwapMode, \ + UINT8* pCurrentSwapBlockStatus, \ + UINT8* pNextSwapBlockStatus, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Swap the two P-Flash blocks with each other */ +extern UINT32 PFlashSwap(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + PFLASH_SWAP_CALLBACK pSwapCallback, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* D-Flash get protection */ +extern UINT32 DFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* D-Flash set protection */ +extern UINT32 DFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); + +/* EERAM get protection */ +extern UINT32 EERAMGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* EERAM set protection */ +extern UINT32 EERAMSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); +/* Flash D/E-Flash Partition */ +extern UINT32 DEFlashPartition(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEDataSizeCode, \ + UINT8 DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash Set EEEEnable */ +extern UINT32 SetEEEEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEEnable); + +/* EEPROM Emulator Write */ +extern UINT32 EEEWrite(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source); + +#endif /* _FTFx_KX_512K_512K_16K_4K_4K_H_ */ diff --git a/source/LegacyDrivers/include/FTFx_LX_(128_64_32_16_8)K_0K_0K_1K_0K.h b/source/LegacyDrivers/include/FTFx_LX_(128_64_32_16_8)K_0K_0K_1K_0K.h new file mode 100644 index 0000000..1f2a42d --- /dev/null +++ b/source/LegacyDrivers/include/FTFx_LX_(128_64_32_16_8)K_0K_0K_1K_0K.h @@ -0,0 +1,263 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2012, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FTFx_LX_(128_64_32_16_8)K_0K_0K_1K_0K.h * +* DATE : June 19, 2012 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.19.2012 FPT Team Initial Version +*************************************************************************/ + +#ifndef _FTFx_LX_128_64_32_16_8K_0K_0K_1K_0K_H_ +#define _FTFx_LX_128_64_32_16_8K_0K_0K_1K_0K_H_ + +#include "SSD_FTFx_Common.h" + +#define BYTE2WORD(x) (x) + +/* Endianness */ +#define ENDIANNESS LITTLE_ENDIAN + +/* cpu core */ +#define CPU_CORE ARM_CM0PLUS + +/* PFlash sector size */ +#define FTFx_PSECTOR_SIZE 0x00000400 /* 1 KB size */ +/* DFlash sector size */ +#define FTFx_DSECTOR_SIZE 0x00000000 /* 0 KB size */ +#define DEBLOCK_SIZE 0x00000000 /* 0 KB size */ +/*destination to read Dflash IFR area*/ +#define DFLASH_IFR_READRESOURCE_ADDRESS 0x8000FC + +/* Address offset and size of PFlash IFR and DFlash IFR */ +#define PFLASH_IFR_OFFSET 0x00000000 +#define PFLASH_IFR_SIZE 0x00000100 +#define DFLASH_IFR_OFFSET 0xFFFFFFFF /* reserved */ +#define DFLASH_IFR_SIZE 0xFFFFFFFF /* reserved */ + +/* Size for checking alignment of a section */ +#define ERSBLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of erase block function */ +#define PGMCHK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program check function */ +#define PPGMSEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program section function */ +#define DPGMSEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program section function */ +#define RD1BLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify block function */ +#define PRD1SEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify section function */ +#define DRD1SEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify section function */ +#define SWAP_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of swap function*/ +#define RDRSRC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of read resource function */ +#define RDONCE_INDEX_MAX 0xF /* maximum index in read once command */ + +/* -------------------- Function Pointer ------------------------------- */ +typedef UINT32 (*pFLASHCOMMANDSEQUENCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* Flash initialization */ +typedef UINT32 (*pFLASHINIT) (PFLASH_SSD_CONFIG PSSDConfig); + +/* P-Flash get protection */ +typedef UINT32 (*pPFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +typedef UINT32 (*pPFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +typedef UINT32 (*pFLASHGETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +typedef UINT32 (*pFLASHSETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +typedef UINT32 (*pFLASHGETSECURITYSTATE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +typedef UINT32 (*pFLASHSECURITYBYPASS) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +typedef UINT32 (*pFLASHERASEALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +typedef UINT32 (*pFLASHERASESECTOR) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +typedef UINT32 (*pFLASHERASESUSPEND) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +typedef UINT32 (*pFLASHERASERESUME) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash checksum */ +typedef UINT32 (*pFLASHCHECKSUM) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +typedef UINT32 (*pFLASHVERIFYALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +typedef UINT32 (*pFLASHVERIFYSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +typedef UINT32 (*pFLASHREADONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +typedef UINT32 (*pFLASHPROGRAMONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +typedef UINT32 (*pFLASHPROGRAMCHECK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +typedef UINT32 (*pFLASHREADRESOURCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Longword */ +typedef UINT32 (*pFLASHPROGRAMLONGWORD) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/*---------------- Function Prototypes for Flash SSD --------------------*/ + +/* Flash initialization */ +extern UINT32 FlashInit(PFLASH_SSD_CONFIG PSSDConfig); + +/* Internal function. Called by driver APIs only */ +/* Flash command sequence */ +extern UINT32 FlashCommandSequence(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* P-Flash get protection */ +extern UINT32 PFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +extern UINT32 PFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +extern UINT32 FlashGetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +extern UINT32 FlashSetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +extern UINT32 FlashGetSecurityState(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +extern UINT32 FlashSecurityBypass(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +extern UINT32 FlashEraseAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +extern UINT32 FlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +extern UINT32 FlashEraseSuspend(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +extern UINT32 FlashEraseResume(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash checksum */ +extern UINT32 FlashCheckSum(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +extern UINT32 FlashVerifyAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +extern UINT32 FlashVerifySection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +extern UINT32 FlashReadOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +extern UINT32 FlashProgramOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +extern UINT32 FlashProgramCheck(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +extern UINT32 FlashReadResource(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Longword */ +extern UINT32 FlashProgramLongword(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +#endif /* _FTFx_LX_(128_64_32_16_8)K_0K_0K_1K_0K_H_ */ diff --git a/source/LegacyDrivers/include/FTFx_NX_(256_128_96_64)K_32K_2K_2K_1K.h b/source/LegacyDrivers/include/FTFx_NX_(256_128_96_64)K_32K_2K_2K_1K.h new file mode 100644 index 0000000..faf83b6 --- /dev/null +++ b/source/LegacyDrivers/include/FTFx_NX_(256_128_96_64)K_32K_2K_2K_1K.h @@ -0,0 +1,395 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2012, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FTFx_NX_(256_128_96_64)K_32K_2K_2K_1K.h * +* DATE : June 19, 2012 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.19.2012 FPT Team Initial Version +*************************************************************************/ + +#ifndef _FTFx_NX_256_128_96_64K_32K_2K_2K_1K_H_ +#define _FTFx_NX_256_128_96_64K_32K_2K_2K_1K_H_ + +#include "SSD_FTFx_Common.h" + +#define BYTE2WORD(x) ((x)>>1) + +/* Endianness */ +#define ENDIANNESS LITTLE_ENDIAN + +/* cpu core */ +#define CPU_CORE DSC_56800EX +/* Kinetis CPU */ + +/* PFlash sector size */ +#define FTFx_PSECTOR_SIZE 0x00000800 /* 2 KB size */ +/* DFlash sector size */ +#define FTFx_DSECTOR_SIZE 0x00000400 /* 1 KB size */ +#define DEBLOCK_SIZE 0x00008000 /* 32 KB size */ + +/* EEE Data Set Size Field Description */ +#define EEESIZE_0000 0x00000000 /* Reserved */ +#define EEESIZE_0001 0x00000000 /* Reserved */ +#define EEESIZE_0010 0x00000000 +#define EEESIZE_0011 0x00000800 +#define EEESIZE_0100 0x00000400 +#define EEESIZE_0101 0x00000200 +#define EEESIZE_0110 0x00000100 +#define EEESIZE_0111 0x00000080 +#define EEESIZE_1000 0x00000040 +#define EEESIZE_1001 0x00000020 +#define EEESIZE_1010 0x00000000 /* Reserved */ +#define EEESIZE_1011 0x00000000 /* Reserved */ +#define EEESIZE_1100 0x00000000 /* Reserved */ +#define EEESIZE_1101 0x00000000 /* Reserved */ +#define EEESIZE_1110 0x00000000 /* Reserved */ +#define EEESIZE_1111 0x00000000 /* Default value */ + +/* D/E-Flash Partition Code Field Description */ +#define DEPART_0000 0x00008000 +#define DEPART_0001 0x00006000 +#define DEPART_0010 0x00004000 +#define DEPART_0011 0x00000000 +#define DEPART_0100 0x00008000 /* Reserved */ +#define DEPART_0101 0x00008000 /* Reserved */ +#define DEPART_0110 0x00008000 /* Reserved */ +#define DEPART_0111 0x00008000 /* Reserved */ +#define DEPART_1000 0x00000000 +#define DEPART_1001 0x00002000 +#define DEPART_1010 0x00004000 +#define DEPART_1011 0x00008000 +#define DEPART_1100 0x00008000 /* Reserved */ +#define DEPART_1101 0x00008000 /* Reserved */ +#define DEPART_1110 0x00008000 /* Reserved */ +#define DEPART_1111 0x00008000 /* Default value */ + +/*destination to read Dflash IFR area*/ +#define DFLASH_IFR_READRESOURCE_ADDRESS 0x8000FC + +/* Address offset and size of PFlash IFR and DFlash IFR */ +#define PFLASH_IFR_OFFSET 0x00000000 +#define PFLASH_IFR_SIZE 0x00000100 +#define DFLASH_IFR_OFFSET 0x00000000 +#define DFLASH_IFR_SIZE 0x00000100 + +/* Size for checking alignment of a section */ +#define ERSBLK_ALIGN_SIZE FTFx_WORD_SIZE /* check align of erase block function */ +#define PGMCHK_ALIGN_SIZE FTFx_WORD_SIZE /* check align of program check function */ +#define PPGMSEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program section function */ +#define DPGMSEC_ALIGN_SIZE FTFx_WORD_SIZE /* check align of program section function */ +#define RD1BLK_ALIGN_SIZE FTFx_WORD_SIZE /* check align of verify block function */ +#define PRD1SEC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify section function */ +#define DRD1SEC_ALIGN_SIZE FTFx_WORD_SIZE /* check align of verify section function */ +#define SWAP_ALIGN_SIZE FTFx_WORD_SIZE /* check align of swap function*/ +#define RDRSRC_ALIGN_SIZE FTFx_WORD_SIZE /* check align of read resource function */ + +#define RDONCE_INDEX_MAX 0xF /* maximum index in read once command */ + +/* -------------------- Function Pointer ------------------------------- */ +typedef UINT32 (*pFLASHCOMMANDSEQUENCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* Flash initialization */ +typedef UINT32 (*pFLASHINIT) (PFLASH_SSD_CONFIG PSSDConfig); + +/* P-Flash get protection */ +typedef UINT32 (*pPFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +typedef UINT32 (*pPFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +typedef UINT32 (*pFLASHGETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +typedef UINT32 (*pFLASHSETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +typedef UINT32 (*pFLASHGETSECURITYSTATE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +typedef UINT32 (*pFLASHSECURITYBYPASS) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +typedef UINT32 (*pFLASHERASEALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +typedef UINT32 (*pFLASHERASEBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +typedef UINT32 (*pFLASHERASESECTOR) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +typedef UINT32 (*pFLASHERASESUSPEND) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +typedef UINT32 (*pFLASHERASERESUME) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +typedef UINT32 (*pFLASHPROGRAMSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +typedef UINT32 (*pFLASHCHECKSUM) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +typedef UINT32 (*pFLASHVERIFYALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +typedef UINT32 (*pFLASHVERIFYBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +typedef UINT32 (*pFLASHVERIFYSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +typedef UINT32 (*pFLASHREADONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +typedef UINT32 (*pFLASHPROGRAMONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +typedef UINT32 (*pFLASHPROGRAMCHECK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +typedef UINT32 (*pFLASHREADRESOURCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Longword */ +typedef UINT32 (*pFLASHPROGRAMLONGWORD) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* D-Flash get protection */ +typedef UINT32 (*pDFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); +/* D-Flash set protection */ +typedef UINT32 (*pDFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); + +/* EERAM get protection */ +typedef UINT32 (*pEERAMGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* EERAM set protection */ +typedef UINT32 (*pEERAMSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); +/* Flash D/E-Flash Partition */ +typedef UINT32 (*pDEFLASHPARTITION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEDataSizeCode, \ + UINT8 DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash Set EEEEnable */ +typedef UINT32 (*pSETEEEENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEEnable); + +/* EEPROM Emulator Write */ +typedef UINT32 (*pEEEWRITE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source); + +/*---------------- Function Prototypes for Flash SSD --------------------*/ + +/* Flash initialization */ +extern UINT32 FlashInit(PFLASH_SSD_CONFIG PSSDConfig); + +/* Internal function. Called by driver APIs only */ +/* Flash command sequence */ +extern UINT32 FlashCommandSequence(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* P-Flash get protection */ +extern UINT32 PFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +extern UINT32 PFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +extern UINT32 FlashGetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +extern UINT32 FlashSetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +extern UINT32 FlashGetSecurityState(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +extern UINT32 FlashSecurityBypass(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +extern UINT32 FlashEraseAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +extern UINT32 FlashEraseBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +extern UINT32 FlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +extern UINT32 FlashEraseSuspend(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +extern UINT32 FlashEraseResume(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +extern UINT32 FlashProgramSection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +extern UINT32 FlashCheckSum(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +extern UINT32 FlashVerifyAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +extern UINT32 FlashVerifyBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +extern UINT32 FlashVerifySection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +extern UINT32 FlashReadOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +extern UINT32 FlashProgramOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +extern UINT32 FlashProgramCheck(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +extern UINT32 FlashReadResource(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Longword */ +extern UINT32 FlashProgramLongword(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* D-Flash get protection */ +extern UINT32 DFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* D-Flash set protection */ +extern UINT32 DFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); + +/* EERAM get protection */ +extern UINT32 EERAMGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* EERAM set protection */ +extern UINT32 EERAMSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); +/* Flash D/E-Flash Partition */ +extern UINT32 DEFlashPartition(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEDataSizeCode, \ + UINT8 DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash Set EEEEnable */ +extern UINT32 SetEEEEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEEnable); + +/* EEPROM Emulator Write */ +extern UINT32 EEEWrite(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source); + +#endif /* _FTFx_NX_(256_128_96_64)K_32K_2K_2K_1K_H_ */ diff --git a/source/LegacyDrivers/include/SSD_FTFx.h b/source/LegacyDrivers/include/SSD_FTFx.h new file mode 100644 index 0000000..52958fa --- /dev/null +++ b/source/LegacyDrivers/include/SSD_FTFx.h @@ -0,0 +1,101 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2012, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx.h * +* DATE : June 20, 2012 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.1 08.16.2010 FPT Team Update some macros for + FTFx_KX_256K_256K_4K_2K_2K derivative +0.1.2 08.26.2010 FPT Team Removed EEEBlockBase element in + _ssd_config structure, +0.1.3 09.16.2010 FPT Team Updated some macros for + FTFx_KX_256K_256K_4K_2K_2K derivative +0.2.0 09.27.2010 FPT Team Removed some macros that is not + used. +0.2.1 01.28.2011 FPT Team Updated to support + FTFx_KX_512K_0K_0K_2K_0K, + FTFx_JX_128K_32K_2K_1K_1K, + and FTFx_FX_256K_32K_2K_1K_1K + derivatives. +0.2.2 04.18.2011 FPT Team Add Swap state definitions of + FTFx_PFLASH_SWAP. +0.2.2 09.15.2011 FPT Team Add FlashProgramPhrase + Add macros for K70 + Remove unused macros +0.2.3 11.15.2011 FPT Team Updated some macros for + FTFx_KX_1024K_0K_16K_4K_0K derivative. +0.2.4 12.23.2011 FPT Team Update to support more Kinetis derivatives. +0.2.5 04.26.2012 FPT Team Update to support swap in FTFx_KX_512K_0K_0K_2K_0K derivative + Add definition of NULL_SWAP_CALLBACK to + fix incompatible function type of null pointer bug in IAR compiler +0.3.1 05.16.2012 FPT Team Update to support + FTFx_NX_256K_32K_2K_2K_1K + FTFx_NX_128K_32K_2K_2K_1K + FTFx_NX_96K_32K_2K_2K_1K + FTFx_NX_64K_32K_2K_2K_1K + derivatives + Change prototype of FlashReadOnce and FlashProgramOnce functions +0.3.2 06.20.2012 FPT Team Update to support more L2K and L1PT derivatives. + Change format of SSD_FTFx.h +0.3.3 08.10.2012 FPT Team Update to support Anguilla Silver derivatives +*************************************************************************/ +#ifndef _SSD_FTFx_H_ +#define _SSD_FTFx_H_ + +#include "SSD_FTFx_Common.h" + +/* Derivative selection */ +#define FLASH_DERIVATIVE FTFx_KX_256K_256K_4K_2K_2K + +/* Compiler selection */ +#define COMPILER CW + +/* Select file .h for each derivatives */ +#if (FTFx_KX_256K_256K_4K_2K_2K == FLASH_DERIVATIVE) + #include "FTFx_KX_256K_256K_4K_2K_2K.h" +#elif (FTFx_KX_512K_0K_0K_2K_0K == FLASH_DERIVATIVE) + #include "FTFx_KX_512K_0K_0K_2K_0K.h" +#elif (FTFx_JX_128K_32K_2K_1K_1K == FLASH_DERIVATIVE) + #include "FTFx_JX_128K_32K_2K_1K_1K.h" +#elif (FTFx_FX_256K_32K_2K_1K_1K == FLASH_DERIVATIVE) + #include "FTFx_FX_256K_32K_2K_1K_1K.h" +#elif (FTFx_KX_512K_512K_16K_4K_4K == FLASH_DERIVATIVE) + #include "FTFx_KX_512K_512K_16K_4K_4K.h" +#elif (FTFx_KX_1024K_0K_16K_4K_0K == FLASH_DERIVATIVE) + #include "FTFx_KX_1024K_0K_16K_4K_0K.h" +#elif ((FTFx_KX_128K_0K_0K_1K_0K == FLASH_DERIVATIVE)||(FTFx_KX_64K_0K_0K_1K_0K == FLASH_DERIVATIVE)\ + ||(FTFx_KX_32K_0K_0K_1K_0K == FLASH_DERIVATIVE)) + #include "FTFx_KX_(128_64_32)K_0K_0K_1K_0K.h" +#elif ((FTFx_KX_128K_32K_2K_1K_1K == FLASH_DERIVATIVE)||(FTFx_KX_64K_32K_2K_1K_1K == FLASH_DERIVATIVE)\ + ||(FTFx_KX_32K_32K_2K_1K_1K == FLASH_DERIVATIVE)) + #include "FTFx_KX_(128_64_32)K_32K_2K_1K_1K.h" +#elif ((FTFx_KX_256K_32K_2K_2K_1K == FLASH_DERIVATIVE)||(FTFx_KX_128K_32K_2K_2K_1K == FLASH_DERIVATIVE)\ + ||(FTFx_KX_64K_32K_2K_2K_1K == FLASH_DERIVATIVE)) + #include "FTFx_KX_(256_128_64)K_32K_2K_2K_1K.h" +#elif ((FTFx_NX_256K_32K_2K_2K_1K == FLASH_DERIVATIVE)||(FTFx_NX_128K_32K_2K_2K_1K == FLASH_DERIVATIVE)\ + ||(FTFx_NX_96K_32K_2K_2K_1K == FLASH_DERIVATIVE)||(FTFx_NX_64K_32K_2K_2K_1K == FLASH_DERIVATIVE)) + #include "FTFx_NX_(256_128_96_64)K_32K_2K_2K_1K.h" +#elif ((FTFx_LX_128K_0K_0K_1K_0K == FLASH_DERIVATIVE)||(FTFx_LX_64K_0K_0K_1K_0K == FLASH_DERIVATIVE)\ + ||(FTFx_LX_32K_0K_0K_1K_0K == FLASH_DERIVATIVE)||(FTFx_LX_16K_0K_0K_1K_0K == FLASH_DERIVATIVE)\ + ||(FTFx_LX_8K_0K_0K_1K_0K == FLASH_DERIVATIVE)) + #include "FTFx_LX_(128_64_32_16_8)K_0K_0K_1K_0K.h" +#elif ((FTFx_AX_64K_0K_0K_1K_0K == FLASH_DERIVATIVE)||(FTFx_AX_48K_0K_0K_1K_0K == FLASH_DERIVATIVE)\ + ||(FTFx_AX_32K_0K_0K_1K_0K == FLASH_DERIVATIVE)||(FTFx_AX_16K_0K_0K_1K_0K == FLASH_DERIVATIVE)) + #include "FTFx_AX_(64_48_32_16)K_0K_0K_1K_0K.h" +#endif + +#endif /* _SSD_FTFx_H_ */ + diff --git a/source/LegacyDrivers/include/SSD_FTFx_Common.h b/source/LegacyDrivers/include/SSD_FTFx_Common.h new file mode 100644 index 0000000..7bc3451 --- /dev/null +++ b/source/LegacyDrivers/include/SSD_FTFx_Common.h @@ -0,0 +1,176 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2012, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx_Common.h * +* DATE : Jun 20, 2012 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.20.2012 FPT Team Initial Version +*************************************************************************/ +#ifndef _SSD_FTFx_COMMON_H_ +#define _SSD_FTFx_COMMON_H_ +#include "SSD_Types.h" +/*------------------------- Configuration Macros -----------------------*/ +/* Define derivatives with rule: FTFx_KX_Pblocksize_Dblocksize_EERAMsize_Psectorsize_Dsectorsize */ + +#define FTFx_KX_256K_256K_4K_2K_2K 1 /* Kinetis - ARM Cortex M4 core */ +#define FTFx_KX_512K_0K_0K_2K_0K 2 /* Kinetis - ARM Cortex M4 core */ +#define FTFx_JX_128K_32K_2K_1K_1K 3 /* ColdFire core */ +#define FTFx_FX_256K_32K_2K_1K_1K 4 /* ColdFire core */ +#define FTFx_KX_512K_512K_16K_4K_4K 5 /* Kinetis - ARM Cortex M4 core */ +#define FTFx_KX_1024K_0K_16K_4K_0K 6 /* Kinetis - ARM Cortex M4 core */ +#define FTFx_KX_32K_0K_0K_1K_0K 7 /* Kinetis - ARM Cortex M4 core */ +#define FTFx_KX_32K_32K_2K_1K_1K 8 /* Kinetis - ARM Cortex M4 core */ +#define FTFx_KX_64K_0K_0K_1K_0K 9 /* Kinetis - ARM Cortex M4 core */ +#define FTFx_KX_64K_32K_2K_1K_1K 10 /* Kinetis - ARM Cortex M4 core */ +#define FTFx_KX_128K_0K_0K_1K_0K 11 /* Kinetis - ARM Cortex M4 core */ +#define FTFx_KX_128K_32K_2K_1K_1K 12 /* Kinetis - ARM Cortex M4 core */ +#define FTFx_KX_64K_32K_2K_2K_1K 13 /* Kinetis - ARM Cortex M4 core */ +#define FTFx_KX_128K_32K_2K_2K_1K 14 /* Kinetis - ARM Cortex M4 core */ +#define FTFx_KX_256K_32K_2K_2K_1K 15 /* Kinetis - ARM Cortex M4 core */ +#define FTFx_NX_256K_32K_2K_2K_1K 16 /* Nevis2 - 56800EX 32 bit DSC core */ +#define FTFx_NX_128K_32K_2K_2K_1K 17 /* Nevis2 - 56800EX 32 bit DSC core */ +#define FTFx_NX_96K_32K_2K_2K_1K 18 /* Nevis2 - 56800EX 32 bit DSC core */ +#define FTFx_NX_64K_32K_2K_2K_1K 19 /* Nevis2 - 56800EX 32 bit DSC core */ +#define FTFx_LX_128K_0K_0K_1K_0K 20 /* L2K - ARM Cortex M0 core */ +#define FTFx_LX_64K_0K_0K_1K_0K 21 /* L2K - ARM Cortex M0 core */ +#define FTFx_LX_32K_0K_0K_1K_0K 22 /* L2K & L1PT - ARM Cortex M0 core */ +#define FTFx_LX_16K_0K_0K_1K_0K 23 /* L1PT - ARM Cortex M0 core */ +#define FTFx_LX_8K_0K_0K_1K_0K 24 /* L1PT - ARM Cortex M0 core */ +#define FTFx_AX_64K_0K_0K_1K_0K 25 /* Anguilla_Silver - 56800EX 32 bit DSC core */ +#define FTFx_AX_48K_0K_0K_1K_0K 26 /* Anguilla_Silver - 56800EX 32 bit DSC core */ +#define FTFx_AX_32K_0K_0K_1K_0K 27 /* Anguilla_Silver - 56800EX 32 bit DSC core */ +#define FTFx_AX_16K_0K_0K_1K_0K 28 /* Anguilla_Silver - 56800EX 32 bit DSC core */ + +/* Define compiler */ +#define CW 0 /* CodeWarrior Compiler */ +#define IAR 1 /* IAR Compiler */ + +/* Endianness */ +#define BIG_ENDIAN 0 /* Big Endian */ +#define LITTLE_ENDIAN 1 /* Little Endian */ + +/* cpu cores */ +#define COLDFIRE 0 /* ColdFire core */ +#define ARM_CM4 1 /* ARM Cortex M4 core */ +#define DSC_56800EX 2 /* 32 bit DSC core */ +#define ARM_CM0PLUS 3 /* ARM Cortex M0 core */ + +/* Word size */ +#define FTFx_WORD_SIZE 0x0002 /* 2 bytes */ + +/* Longword size */ +#define FTFx_LONGWORD_SIZE 0x0004 /* 4 bytes */ + +/* Phrase size */ +#define FTFx_PHRASE_SIZE 0x0008 /* 8 bytes */ + +/* Double-phrase size */ +#define FTFx_DPHRASE_SIZE 0x0010 /* 16 bytes */ + +/*------------ Return Code Definition for FTFx SSD ---------------------*/ +#define FTFx_OK 0x0000 +#define FTFx_ERR_SIZE 0x0001 +#define FTFx_ERR_RANGE 0x0002 +#define FTFx_ERR_ACCERR 0x0004 +#define FTFx_ERR_PVIOL 0x0008 +#define FTFx_ERR_MGSTAT0 0x0010 +#define FTFx_ERR_CHANGEPROT 0x0020 +#define FTFx_ERR_EEESIZE 0x0040 +#define FTFx_ERR_EFLASHSIZE 0x0080 +#define FTFx_ERR_ADDR 0x0100 +#define FTFx_ERR_NOEEE 0x0200 +#define FTFx_ERR_EFLASHONLY 0x0400 +#define FTFx_ERR_DFLASHONLY 0x0800 +#define FTFx_ERR_RDCOLERR 0x1000 +#define FTFx_ERR_RAMRDY 0x2000 + +/* Flash security status */ +#define FLASH_SECURITY_STATE_KEYEN 0x80 +#define FLASH_SECURITY_STATE_UNSECURED 0x02 + +#define FLASH_NOT_SECURE 0x01 +#define FLASH_SECURE_BACKDOOR_ENABLED 0x02 +#define FLASH_SECURE_BACKDOOR_DISABLED 0x04 + +/* macro for flash configuration field offset */ +#define FLASH_CNFG_START_ADDRESS 0x400 +#define FLASH_CNFG_END_ADDRESS 0x40F + +/* EERAM Function Control Code */ +#define EEE_ENABLE 0x00 +#define EEE_DISABLE 0xFF + +/*-------------- Read/Write/Set/Clear Operation Macros -----------------*/ +#define REG_BIT_SET(address, mask) (*(VUINT8*)(address) |= (mask)) +#define REG_BIT_CLEAR(address, mask) (*(VUINT8*)(address) &= ~(mask)) +#define REG_BIT_TEST(address, mask) (*(VUINT8 *)(address) & (UINT8)(mask)) +#define REG_WRITE(address, value) (*(VUINT8*)(address) = (value)) +#define REG_READ(address) ((UINT8)(*(VUINT8*)(address))) +#define REG_WRITE32(address, value) (*(VUINT32*)(address) = (value)) +#define REG_READ32(address) ((UINT32)(*(VUINT32*)(address))) + +#define WRITE8(address, value) (*(VUINT8*)(address) = (value)) +#define READ8(address) ((UINT8)(*(VUINT8*)(address))) +#define SET8(address, value) (*(VUINT8*)(address) |= (value)) +#define CLEAR8(address, value) (*(VUINT8*)(address) &= ~(value)) +#define TEST8(address, value) (*(VUINT8*)(address) & (value)) + +#define WRITE16(address, value) (*(VUINT16*)(address) = (value)) +#define READ16(address) ((UINT16)(*(VUINT16*)(address))) +#define SET16(address, value) (*(VUINT16*)(address) |= (value)) +#define CLEAR16(address, value) (*(VUINT16*)(address) &= ~(value)) +#define TEST16(address, value) (*(VUINT16*)(address) & (value)) + +#define WRITE32(address, value) (*(VUINT32*)(address) = (value)) +#define READ32(address) ((UINT32)(*(VUINT32*)(address))) +#define SET32(address, value) (*(VUINT32*)(address) |= (value)) +#define CLEAR32(address, value) (*(VUINT32*)(address) &= ~(value)) +#define TEST32(address, value) (*(VUINT32*)(address) & (value)) + +/*--------------------- CallBack function period -----------------------*/ +#define FLASH_CALLBACK_CS 1 /* Check Sum */ + +/*-------------------- Callback function prototype ---------------------*/ +typedef void (* PCALLBACK)(void); +typedef BOOL (* PFLASH_SWAP_CALLBACK)(UINT8); + +/*--------------------Null Callback function defination ----------------*/ +#define NULL_CALLBACK ((PCALLBACK)0xFFFFFFFF) +#define NULL_SWAP_CALLBACK ((PFLASH_SWAP_CALLBACK)0xFFFFFFFF) + +/*---------------- Flash SSD Configuration Structure -------------------*/ +typedef struct _ssd_config +{ + UINT32 ftfxRegBase; /* FTFx control register base */ + UINT32 PFlashBlockBase; /* base address of PFlash block */ + UINT32 PFlashBlockSize; /* size of PFlash block */ + UINT32 DFlashBlockBase; /* base address of DFlash block */ + UINT32 DFlashBlockSize; /* size of DFlash block */ + UINT32 EERAMBlockBase; /* base address of EERAM block */ + UINT32 EERAMBlockSize; /* size of EERAM block */ + UINT32 EEEBlockSize; /* size of EEE block */ + BOOL DebugEnable; /* background debug mode enable bit */ + PCALLBACK CallBack; /* pointer to callback function */ +} FLASH_SSD_CONFIG, *PFLASH_SSD_CONFIG; + +/* PFlash swap states */ +#define FTFx_SWAP_UNINIT 0x00 +#define FTFx_SWAP_READY 0x01 +#define FTFx_SWAP_INIT 0x01 +#define FTFx_SWAP_UPDATE 0x02 +#define FTFx_SWAP_UPDATE_ERASED 0x03 +#define FTFx_SWAP_COMPLETE 0x04 + +#endif /* _SSD_FTFx_COMMON_H_ */ + diff --git a/source/LegacyDrivers/include/SSD_FTFx_Device.h b/source/LegacyDrivers/include/SSD_FTFx_Device.h new file mode 100644 index 0000000..ed91585 --- /dev/null +++ b/source/LegacyDrivers/include/SSD_FTFx_Device.h @@ -0,0 +1,87 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : NormalDemo.h * +* DATE : February 10,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b28216@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 09.21.2010 FPT Team Initial Version +0.1.0 02.10.2011 FPT Team Update to support K40 and K60 +*************************************************************************/ + +#ifndef _NORMALDEMO_H_ +#define _NORMALDEMO_H_ + +// #if (FLASH_DERIVATIVE == FTFx_KX_256K_256K_4K_2K_2K) +// #include "MK40N512VMD100.h" +// #else /* FLASH_DERIVATIVE == FTFx_KX_512K_0K_0K_2K_0K */ +// #include "MK60N512VMD100.h" +// #endif + +#define READ_NORMAL_MARGIN 0x00 +#define READ_USER_MARGIN 0x01 +#define READ_FACTORY_MARGIN 0x02 + +#define EE_ENABLE 0x00 +#define RAM_ENABLE 0xFF +#define DEBUGENABLE 0x00 +#define PFLASH_IFR_ADDR 0x00000000 +#define DFLASH_IFR_ADDR 0x00800000 + +#define SECTOR_SIZE 0x00000800 /* 2 KB size */ +#define BUFFER_SIZE_BYTE 0x10 + +/* FTFL module base */ +#define FTFx_REG_BASE 0x40020000 +#define DFLASH_IFR_BASE 0x10000000 /* unused */ +#define PFLASH_BLOCK_BASE 0x00000000 +#define DEFLASH_BLOCK_BASE 0x10000000 /* There is not DFlash */ +#define EERAM_BLOCK_BASE 0x14000000 + +#define PBLOCK_SIZE 0x00080000 /* 512 KB size */ +#define EERAM_BLOCK_SIZE 0x00004000 /* 16 KB size */ + +#define pFlashInit (FlashInit) +#define pDEFlashPartition (DEFlashPartition) +#define pSetEEEEnable (SetEEEEnable) +#define pPFlashSetProtection (PFlashSetProtection) +#define pPFlashGetProtection (PFlashGetProtection) +#define pFlashVerifySection (FlashVerifySection) +#define pFlashVerifyBlock (FlashVerifyBlock) +#define pFlashVerifyAllBlock (FlashVerifyAllBlock) +#define pFlashSetInterruptEnable (FlashSetInterruptEnable) +#define pFlashSecurityBypass (FlashSecurityBypass) +#define pFlashReadResource (FlashReadResource) +#define pFlashReadOnce (FlashReadOnce) +#define pFlashProgramSection (FlashProgramSection) +#define pFlashProgramOnce (FlashProgramOnce) +#define pFlashProgramLongword (FlashProgramLongword) +#define pFlashProgramCheck (FlashProgramCheck) +#define pFlashGetSecurityState (FlashGetSecurityState) +#define pFlashGetInterruptEnable (FlashGetInterruptEnable) +#define pFlashEraseSuspend (FlashEraseSuspend) +#define pFlashEraseBlock (FlashEraseBlock) +#define pFlashEraseAllBlock (FlashEraseAllBlock) +#define pFlashCommandSequence (FlashCommandSequence) +#define pFlashCheckSum (FlashCheckSum) +#define pEERAMSetProtection (EERAMSetProtection) +#define pEERAMGetProtection (EERAMGetProtection) +#define pEEEWrite (EEEWrite) +#define pDFlashSetProtection (DFlashSetProtection) +#define pDFlashGetProtection (DFlashGetProtection) +#define pFlashEraseResume (FlashEraseResume) +#define pFlashEraseSector (FlashEraseSector) + +void ErrorTrap(unsigned int returnCode); + +#endif /* _ISRDEMO_H_ */ diff --git a/source/LegacyDrivers/include/SSD_FTFx_Internal.h b/source/LegacyDrivers/include/SSD_FTFx_Internal.h new file mode 100644 index 0000000..2b1c6a8 --- /dev/null +++ b/source/LegacyDrivers/include/SSD_FTFx_Internal.h @@ -0,0 +1,178 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_FTFx_Internal.h * +* DATE : April 18, 2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.1 08.16.2010 FPT Team Finalize to 0.1.1 +0.1.2 08.26.2010 FPT Team Finalize to 0.1.2 +0.1.3 09.16.2010 FPT Team Updated to support little endian +0.2.0 06.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated to support + FTFx_KX_512K_0K_0K, + FTFx_JX_128K_32K_2K, + and FTFx_FX_256K_32K_2K + derivatives. +0.2.2 04.18.2011 FPT Team Add swap control code definitions + of FTFx_PFLASH_SWAP. +0.2.3 09.15.2011 FPT Team Add command for program phrase +*************************************************************************/ +#ifndef _SSD_FTFx_INTERNAL_H_ +#define _SSD_FTFx_INTERNAL_H_ + +#include "SSD_FTFx.h" + +/*--------------- FTFx Flash Module Memory Offset Map -----------------*/ +#if(ENDIANNESS == BIG_ENDIAN) /* Big Endian - coldfire CPU */ + /* Flash Status Register (FSTAT)*/ + #define FTFx_SSD_FSTAT_OFFSET 0x00000003 + #define FTFx_SSD_FSTAT_CCIF 0x80 + #define FTFx_SSD_FSTAT_RDCOLERR 0x40 + #define FTFx_SSD_FSTAT_ACCERR 0x20 + #define FTFx_SSD_FSTAT_FPVIOL 0x10 + #define FTFx_SSD_FSTAT_MGSTAT0 0x01 + + /* Flash configuration register (FCNFG)*/ + #define FTFx_SSD_FCNFG_OFFSET 0x00000002 + #define FTFx_SSD_FCNFG_CCIE 0x80 + #define FTFx_SSD_FCNFG_RDCOLLIE 0x40 + #define FTFx_SSD_FCNFG_ERSAREQ 0x20 + #define FTFx_SSD_FCNFG_ERSSUSP 0x10 + #define FTFx_SSD_FCNFG_RAMRDY 0x02 + #define FTFx_SSD_FCNFG_EEERDY 0x01 + + /* Flash security register (FSEC) */ + #define FTFx_SSD_FSEC_OFFSET 0x00000001 + #define FTFx_SSD_FSEC_KEYEN 0xC0 + #define FTFx_SSD_FSEC_FSLACC 0x0C + #define FTFx_SSD_FSEC_SEC 0x03 + + /* Flash Option Register (FOPT) */ + #define FTFx_SSD_FOPT_OFFSET 0x00000000 + + /* Flash common command object registers (FCCOB0-B) */ + #define FTFx_SSD_FCCOB0_OFFSET 0x00000004 + #define FTFx_SSD_FCCOB1_OFFSET 0x00000005 + #define FTFx_SSD_FCCOB2_OFFSET 0x00000006 + #define FTFx_SSD_FCCOB3_OFFSET 0x00000007 + #define FTFx_SSD_FCCOB4_OFFSET 0x00000008 + #define FTFx_SSD_FCCOB5_OFFSET 0x00000009 + #define FTFx_SSD_FCCOB6_OFFSET 0x0000000A + #define FTFx_SSD_FCCOB7_OFFSET 0x0000000B + #define FTFx_SSD_FCCOB8_OFFSET 0x0000000C + #define FTFx_SSD_FCCOB9_OFFSET 0x0000000D + #define FTFx_SSD_FCCOBA_OFFSET 0x0000000E + #define FTFx_SSD_FCCOBB_OFFSET 0x0000000F + + /* P-Flash protection registers (FPROT0-3) */ + #define FTFx_SSD_FPROT0_OFFSET 0x00000010 + #define FTFx_SSD_FPROT1_OFFSET 0x00000011 + #define FTFx_SSD_FPROT2_OFFSET 0x00000012 + #define FTFx_SSD_FPROT3_OFFSET 0x00000013 + + /* D-Flash protection registers (FDPROT) */ + #define FTFx_SSD_FDPROT_OFFSET 0x00000014 + + /* EERAM Protection Register (FEPROT) */ + #define FTFx_SSD_FEPROT_OFFSET 0x00000015 + /* Little Endian - kinetis CPU & Big Endian - Nevis2 CPU */ +#else + /* Flash Status Register (FSTAT)*/ + #define FTFx_SSD_FSTAT_OFFSET 0x00000000 + #define FTFx_SSD_FSTAT_CCIF 0x80 + #define FTFx_SSD_FSTAT_RDCOLERR 0x40 + #define FTFx_SSD_FSTAT_ACCERR 0x20 + #define FTFx_SSD_FSTAT_FPVIOL 0x10 + #define FTFx_SSD_FSTAT_MGSTAT0 0x01 + + /* Flash configuration register (FCNFG)*/ + #define FTFx_SSD_FCNFG_OFFSET 0x00000001 + #define FTFx_SSD_FCNFG_CCIE 0x80 + #define FTFx_SSD_FCNFG_RDCOLLIE 0x40 + #define FTFx_SSD_FCNFG_ERSAREQ 0x20 + #define FTFx_SSD_FCNFG_ERSSUSP 0x10 + #define FTFx_SSD_FCNFG_RAMRDY 0x02 + #define FTFx_SSD_FCNFG_EEERDY 0x01 + + /* Flash security register (FSEC) */ + #define FTFx_SSD_FSEC_OFFSET 0x00000002 + #define FTFx_SSD_FSEC_KEYEN 0xC0 + #define FTFx_SSD_FSEC_FSLACC 0x0C + #define FTFx_SSD_FSEC_SEC 0x03 + + /* Flash Option Register (FOPT) */ + #define FTFx_SSD_FOPT_OFFSET 0x00000003 + + /* Flash common command object registers (FCCOB0-B) */ + #define FTFx_SSD_FCCOB0_OFFSET 0x00000007 + #define FTFx_SSD_FCCOB1_OFFSET 0x00000006 + #define FTFx_SSD_FCCOB2_OFFSET 0x00000005 + #define FTFx_SSD_FCCOB3_OFFSET 0x00000004 + #define FTFx_SSD_FCCOB4_OFFSET 0x0000000B + #define FTFx_SSD_FCCOB5_OFFSET 0x0000000A + #define FTFx_SSD_FCCOB6_OFFSET 0x00000009 + #define FTFx_SSD_FCCOB7_OFFSET 0x00000008 + #define FTFx_SSD_FCCOB8_OFFSET 0x0000000F + #define FTFx_SSD_FCCOB9_OFFSET 0x0000000E + #define FTFx_SSD_FCCOBA_OFFSET 0x0000000D + #define FTFx_SSD_FCCOBB_OFFSET 0x0000000C + + /* P-Flash protection registers (FPROT0-3) */ + #define FTFx_SSD_FPROT0_OFFSET 0x00000013 + #define FTFx_SSD_FPROT1_OFFSET 0x00000012 + #define FTFx_SSD_FPROT2_OFFSET 0x00000011 + #define FTFx_SSD_FPROT3_OFFSET 0x00000010 + + /* D-Flash protection registers (FDPROT) */ + #define FTFx_SSD_FDPROT_OFFSET 0x00000017 + + /* EERAM Protection Register (FEPROT) */ + #define FTFx_SSD_FEPROT_OFFSET 0x00000016 +#endif + +/*------------- Flash hardware algorithm operation commands -------------*/ +#define FTFx_VERIFY_BLOCK 0x00 +#define FTFx_VERIFY_SECTION 0x01 +#define FTFx_PROGRAM_CHECK 0x02 +#define FTFx_READ_RESOURCE 0x03 +#define FTFx_PROGRAM_LONGWORD 0x06 +#define FTFx_PROGRAM_PHRASE 0x07 +#define FTFx_ERASE_BLOCK 0x08 +#define FTFx_ERASE_SECTOR 0x09 +#define FTFx_PROGRAM_SECTION 0x0B +#define FTFx_VERIFY_ALL_BLOCK 0x40 +#define FTFx_READ_ONCE 0x41 +#define FTFx_PROGRAM_ONCE 0x43 +#define FTFx_ERASE_ALL_BLOCK 0x44 +#define FTFx_SECURITY_BY_PASS 0x45 +#define FTFx_PFLASH_SWAP 0x46 +#define FTFx_PROGRAM_PARTITION 0x80 +#define FTFx_SET_EERAM 0x81 + +/* Flash margin read settings */ +#define FTFx_MARGIN_NORMAL 0x0000 +#define FTFx_USER_MARGIN_LEVEL1 0x0001 +#define FTFx_USER_MARGIN_LEVEL0 0x0002 +#define FTFx_FACTORY_MARGIN_LEVEL0 0x0003 +#define FTFx_FACTORY_MARGIN_LEVEL1 0x0004 + +/* PFlash swap control codes */ +#define FTFx_SWAP_SET_INDICATOR_ADDR 0x01 +#define FTFx_SWAP_SET_IN_PREPARE 0x02 +#define FTFx_SWAP_SET_IN_COMPLETE 0x04 +#define FTFx_SWAP_REPORT_STATUS 0x08 + +#endif /* _SSD_FTFx_INTERNAL_H_ */ diff --git a/source/LegacyDrivers/include/SSD_Types.h b/source/LegacyDrivers/include/SSD_Types.h new file mode 100644 index 0000000..1af04bd --- /dev/null +++ b/source/LegacyDrivers/include/SSD_Types.h @@ -0,0 +1,53 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2010, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SSD_Types.h * +* DATE : September 27,2010 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.1 08.16.2010 FPT Team Finalize to 0.1.1 +0.1.2 08.26.2010 FPT Team Finalize to 0.1.2 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +*************************************************************************/ + +#ifndef _SSD_TYPES_H_ +#define _SSD_TYPES_H_ +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +typedef unsigned char BOOL; + +typedef signed char INT8; +typedef unsigned char UINT8; +typedef volatile signed char VINT8; +typedef volatile unsigned char VUINT8; + +typedef signed short INT16; +typedef unsigned short UINT16; +typedef volatile signed short VINT16; +typedef volatile unsigned short VUINT16; + +typedef signed long INT32; +typedef unsigned long UINT32; +typedef volatile signed long VINT32; +typedef volatile unsigned long VUINT32; + +#endif /* _SSD_TYPES_H_ */ diff --git a/source/LegacyDrivers/include/diskio.h b/source/LegacyDrivers/include/diskio.h new file mode 100644 index 0000000..00d8615 --- /dev/null +++ b/source/LegacyDrivers/include/diskio.h @@ -0,0 +1,85 @@ +/*----------------------------------------------------------------------- +/ Low level disk interface modlue include file (C)ChaN, 2013 +/-----------------------------------------------------------------------*/ + +#ifndef _DISKIO_DEFINED +#define _DISKIO_DEFINED + +#ifdef __cplusplus +extern "C" { +#endif + +#include "integer.h" + + +/* Status of Disk Functions */ +typedef BYTE DSTATUS; + +/* Results of Disk Functions */ +typedef enum { + RES_OK = 0, /* 0: Successful */ + RES_ERROR, /* 1: R/W Error */ + RES_WRPRT, /* 2: Write Protected */ + RES_NOTRDY, /* 3: Not Ready */ + RES_PARERR /* 4: Invalid Parameter */ +} DRESULT; + + +/*---------------------------------------*/ +/* Prototypes for disk control functions */ + + +DSTATUS disk_initialize (BYTE pdrv); +DSTATUS disk_status (BYTE pdrv); +DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); +DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); +DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); + + +/* Disk Status Bits (DSTATUS) */ +#define STA_NOINIT 0x01 /* Drive not initialized */ +#define STA_NODISK 0x02 /* No medium in the drive */ +#define STA_PROTECT 0x04 /* Write protected */ + + +/* Command code for disk_ioctrl fucntion */ + +/* Generic command (used by FatFs) */ +#define CTRL_SYNC 0 /* Flush disk cache (for write functions) */ +#define GET_SECTOR_COUNT 1 /* Get media size (for only f_mkfs()) */ +//#define GET_SECTOR_SIZE 2 /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */ +#define GET_BLOCK_SIZE 3 /* Get erase block size (for only f_mkfs()) */ +#define CTRL_ERASE_SECTOR 4 /* Force erased a block of sectors (for only _USE_ERASE) */ + +/* Generic command (not used by FatFs) */ +//#define CTRL_POWER 5 /* Get/Set power status */ +//#define CTRL_LOCK 6 /* Lock/Unlock media removal */ +//#define CTRL_EJECT 7 /* Eject media */ +//#define CTRL_FORMAT 8 /* Create physical format on the media */ + +/* MMC/SDC specific ioctl command */ +#define MMC_GET_TYPE 10 /* Get card type */ +#define MMC_GET_CSD 11 /* Get CSD */ +#define MMC_GET_CID 12 /* Get CID */ +#define MMC_GET_OCR 13 /* Get OCR */ +#define MMC_GET_SDSTAT 14 /* Get SD status */ + +/* ATA/CF specific ioctl command */ +#define ATA_GET_REV 20 /* Get F/W revision */ +#define ATA_GET_MODEL 21 /* Get model name */ +#define ATA_GET_SN 22 /* Get serial number */ + + +/* MMC card type flags (MMC_GET_TYPE) */ +#define CT_MMC 0x01 /* MMC ver 3 */ +#define CT_SD1 0x02 /* SD ver 1 */ +#define CT_SD2 0x04 /* SD ver 2 */ +#define CT_SDC (CT_SD1|CT_SD2) /* SD */ +#define CT_BLOCK 0x08 /* Block addressing */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/LegacyDrivers/include/enet.h b/source/LegacyDrivers/include/enet.h new file mode 100644 index 0000000..ea9ee8d --- /dev/null +++ b/source/LegacyDrivers/include/enet.h @@ -0,0 +1,85 @@ +/* + * File: enet.h + * Purpose: Driver for the ENET controller + * + * Notes: + */ + +#ifndef _ENET_H_ +#define _ENET_H_ + +#include "nbuf.h" + +/********INTERFACE**********/ +typedef enum { + mac_mii, + mac_rmii, +} ENET_INTERFACE; +/********AUTONEG**********/ +typedef enum { + autoneg_on, + autoneg_off +} ENET_AUTONEG; +/********SPEED**********/ +typedef enum { + MII_10BASET, + MII_100BASET +} ENET_SPEED; +/********DUPLEX**********/ +/* MII Duplex Settings */ +typedef enum { + MII_HDX, /*!< half-duplex */ + MII_FDX /*!< full-duplex */ +} ENET_DUPLEX; +/********LOOPBACK**********/ +typedef enum { + INTERNAL_LOOPBACK, + EXTERNAL_LOOPBACK, + NO_LOOPBACK +} ENET_LOOPBACK; +/********EXTERNAL**********/ +typedef enum { + EXTERNAL_NONE, + EXTERNAL_YES +} ENET_EXTERNAL_CONN; + +/* + * FEC Configuration Parameters + */ +typedef struct +{ + uint8_t ch; /* FEC channel */ + ENET_INTERFACE interface; /* Transceiver mode */ + ENET_AUTONEG neg; /* FEC autoneg */ + ENET_SPEED speed; /* Ethernet Speed */ + ENET_DUPLEX duplex; /* Ethernet Duplex */ + ENET_LOOPBACK loopback; /* Loopback Mode */ + ENET_EXTERNAL_CONN external; /* outside test? */ + uint8_t prom; /* Promiscuous Mode? */ + uint8_t mac[6]; /* Ethernet Address */ +} ENET_CONFIG; + +void enet_mib_init(int); + +void enet_mib_dump(int); + +void enet_reg_dump(int); + +void enet_duplex (int, ENET_DUPLEX); + +uint8_t enet_hash_address(const uint8_t*); + +void enet_set_address (int, const uint8_t*); + +void enet_reset (int); + +void enet_init (ENET_CONFIG *config); + +void enet_start (int ch); + +int enet_wait_for_frame_receive(int,int); + + +/********************************************************************/ + +#endif /* _ENET_H_ */ diff --git a/source/LegacyDrivers/include/eth.h b/source/LegacyDrivers/include/eth.h new file mode 100644 index 0000000..2d085d0 --- /dev/null +++ b/source/LegacyDrivers/include/eth.h @@ -0,0 +1,58 @@ +/*! + * \file eth.h + * \brief Definitinos for Ethernet Frames + * \version $Revision: 1.1 $ + * \author Michael Norman + */ + +#ifndef _ETH_H +#define _ETH_H + +/*b06862*/ +//#include "common.h" + +/*******************************************************************/ + +/* Ethernet standard lengths in bytes*/ +#define ETH_ADDR_LEN (6) +#define ETH_TYPE_LEN (2) +#define ETH_CRC_LEN (4) +#define ETH_MAX_DATA (1500) +#define ETH_MIN_DATA (46) +#define ETH_HDR_LEN (ETH_ADDR_LEN * 2 + ETH_TYPE_LEN) + +/* Defined Ethernet Frame Types */ +#define ETH_FRM_IP (0x0800) +#define ETH_FRM_ARP (0x0806) +#define ETH_FRM_RARP (0x8035) +#define ETH_FRM_TEST (0xA5A5) + +/* Maximum and Minimum Ethernet Frame Sizes */ +#define ETH_MAX_FRM (ETH_HDR_LEN + ETH_MAX_DATA + ETH_CRC_LEN) +#define ETH_MIN_FRM (ETH_HDR_LEN + ETH_MIN_DATA + ETH_CRC_LEN) +#define ETH_MTU (ETH_HDR_LEN + ETH_MAX_DATA) + +/* Ethernet Addresses */ +typedef uint8_t ETH_ADDR[ETH_ADDR_LEN]; + +/* 16-bit Ethernet Frame Type, ie. Protocol */ +typedef uint16_t ETH_FRM_TYPE; + +/* Ethernet Frame Header definition */ +typedef struct +{ + ETH_ADDR dest; + ETH_ADDR src; + ETH_FRM_TYPE type; +} ETH_HDR; + +/* Ethernet Frame definition */ +typedef struct +{ + ETH_HDR head; + uint8_t* data; +} ETH_FRAME; + +/*******************************************************************/ + +#endif /* _ETH_H */ diff --git a/source/LegacyDrivers/include/eth_phy.h b/source/LegacyDrivers/include/eth_phy.h new file mode 100644 index 0000000..2e57b9a --- /dev/null +++ b/source/LegacyDrivers/include/eth_phy.h @@ -0,0 +1,176 @@ +/*! + * \file eth.h + * \brief Definitions for Ethernet Physical Layer Interface + * \version $Revision: 1.3 $ + * \author Michael Norman + * \modif b06862 + */ + +#ifndef _ETH_PHY_H +#define _ETH_PHY_H + +#define MII_CHECK_TIMEOUT 0 + +#include "enet.h" + +/*******************************************************************/ + +int +eth_phy_reset(int ch, int phy_addr); + +int +eth_phy_autoneg(int ch, int phy_addr, ENET_SPEED speed, ENET_DUPLEX duplex); + +int +eth_phy_manual(int ch, int phy_addr, ENET_SPEED speed, ENET_DUPLEX duplex, int loop); + +int +eth_phy_get_speed(int, int, int*); + +int +eth_phy_get_duplex(int, int, int*); + +int +eth_phy_get_manual_speed(int, int, int*); + +int +eth_phy_get_manual_duplex(int, int, int*); + +int +eth_phy_set_remote_loopback(int, int, int); + +int +eth_phy_reg_dump(int, int); + +/*******************************************************************/ + +/* MII Register Addresses */ +#define PHY_BMCR (0x00) +#define PHY_BMSR (0x01) +#define PHY_PHYIDR1 (0x02) +#define PHY_PHYIDR2 (0x03) +#define PHY_ANAR (0x04) +#define PHY_ANLPAR (0x05) +#define PHY_ANLPARNP (0x05) +#define PHY_ANER (0x06) +#define PHY_ANNPTR (0x07) +#define PHY_PHYSTS (0x10) +#define PHY_MICR (0x11) +#define PHY_MISR (0x12) +#define PHY_PAGESEL (0x13) + +/*TSI-EVB definition: National Semiconductor*/ +#define PHY_PHYCR2 (0x1C) + +/*TWR definition: Micrel*/ +#define PHY_PHYCTRL1 (0x1E) +#define PHY_PHYCTRL2 (0x1F) + +/* Bit definitions and macros for PHY_BMCR */ +#define PHY_BMCR_RESET (0x8000) +#define PHY_BMCR_LOOP (0x4000) +#define PHY_BMCR_SPEED (0x2000) +#define PHY_BMCR_AN_ENABLE (0x1000) +#define PHY_BMCR_POWERDOWN (0x0800) +#define PHY_BMCR_ISOLATE (0x0400) +#define PHY_BMCR_AN_RESTART (0x0200) +#define PHY_BMCR_FDX (0x0100) +#define PHY_BMCR_COL_TEST (0x0080) + +/* Bit definitions and macros for PHY_BMSR */ +#define PHY_BMSR_100BT4 (0x8000) +#define PHY_BMSR_100BTX_FDX (0x4000) +#define PHY_BMSR_100BTX (0x2000) +#define PHY_BMSR_10BT_FDX (0x1000) +#define PHY_BMSR_10BT (0x0800) +#define PHY_BMSR_NO_PREAMBLE (0x0040) +#define PHY_BMSR_AN_COMPLETE (0x0020) +#define PHY_BMSR_REMOTE_FAULT (0x0010) +#define PHY_BMSR_AN_ABILITY (0x0008) +#define PHY_BMSR_LINK (0x0004) +#define PHY_BMSR_JABBER (0x0002) +#define PHY_BMSR_EXTENDED (0x0001) + +/* Bit definitions and macros for PHY_ANAR */ +#define PHY_ANAR_NEXT_PAGE (0x8001) +#define PHY_ANAR_REM_FAULT (0x2001) +#define PHY_ANAR_PAUSE (0x0401) +#define PHY_ANAR_100BT4 (0x0201) +#define PHY_ANAR_100BTX_FDX (0x0101) +#define PHY_ANAR_100BTX (0x0081) +#define PHY_ANAR_10BT_FDX (0x0041) +#define PHY_ANAR_10BT (0x0021) +#define PHY_ANAR_802_3 (0x0001) + +/* Bit definitions and macros for PHY_ANLPAR */ +#define PHY_ANLPAR_NEXT_PAGE (0x8000) +#define PHY_ANLPAR_ACK (0x4000) +#define PHY_ANLPAR_REM_FAULT (0x2000) +#define PHY_ANLPAR_PAUSE (0x0400) +#define PHY_ANLPAR_100BT4 (0x0200) +#define PHY_ANLPAR_100BTX_FDX (0x0100) +#define PHY_ANLPAR_100BTX (0x0080) +#define PHY_ANLPAR_10BTX_FDX (0x0040) +#define PHY_ANLPAR_10BT (0x0020) + + +/* Bit definitions of PHY_PHYSTS: National */ +#define PHY_PHYSTS_MDIXMODE (0x4000) +#define PHY_PHYSTS_RX_ERR_LATCH (0x2000) +#define PHY_PHYSTS_POL_STATUS (0x1000) +#define PHY_PHYSTS_FALSECARRSENSLAT (0x0800) +#define PHY_PHYSTS_SIGNALDETECT (0x0400) +#define PHY_PHYSTS_PAGERECEIVED (0x0100) +#define PHY_PHYSTS_MIIINTERRUPT (0x0080) +#define PHY_PHYSTS_REMOTEFAULT (0x0040) +#define PHY_PHYSTS_JABBERDETECT (0x0020) +#define PHY_PHYSTS_AUTONEGCOMPLETE (0x0010) +#define PHY_PHYSTS_LOOPBACKSTATUS (0x0008) +#define PHY_PHYSTS_DUPLEXSTATUS (0x0004) +#define PHY_PHYSTS_SPEEDSTATUS (0x0002) +#define PHY_PHYSTS_LINKSTATUS (0x0001) + + +/* Bit definitions of PHY_PHYCR2 */ +#define PHY_PHYCR2_SYNC_ENET_EN (0x2000) +#define PHY_PHYCR2_CLK_OUT_RXCLK (0x1000) +#define PHY_PHYCR2_BC_WRITE (0x0800) +#define PHY_PHYCR2_PHYTER_COMP (0x0400) +#define PHY_PHYCR2_SOFT_RESET (0x0200) +#define PHY_PHYCR2_CLK_OUT_DIS (0x0001) + +/* Bit definition and macros for PHY_PHYCTRL1 */ +#define PHY_PHYCTRL1_LED_MASK (0xC000) +#define PHY_PHYCTRL1_POLARITY (0x2000) +#define PHY_PHYCTRL1_MDX_STATE (0x0800) +#define PHY_PHYCTRL1_REMOTE_LOOP (0x0080) + +/* Bit definition and macros for PHY_PHYCTRL2 */ +#define PHY_PHYCTRL2_HP_MDIX (0x8000) +#define PHY_PHYCTRL2_MDIX_SELECT (0x4000) +#define PHY_PHYCTRL2_PAIRSWAP_DIS (0x2000) +#define PHY_PHYCTRL2_ENERGY_DET (0x1000) +#define PHY_PHYCTRL2_FORCE_LINK (0x0800) +#define PHY_PHYCTRL2_POWER_SAVING (0x0400) +#define PHY_PHYCTRL2_INT_LEVEL (0x0200) +#define PHY_PHYCTRL2_EN_JABBER (0x0100) +#define PHY_PHYCTRL2_AUTONEG_CMPLT (0x0080) +#define PHY_PHYCTRL2_ENABLE_PAUSE (0x0040) +#define PHY_PHYCTRL2_PHY_ISOLATE (0x0020) +#define PHY_PHYCTRL2_OP_MOD_MASK (0x001C) +#define PHY_PHYCTRL2_EN_SQE_TEST (0x0002) +#define PHY_PHYCTRL2_DATA_SCRAM_DIS (0x0001) + + +/* Bit definitions of PHY_PHYCTRL2_OP_MOD_MASK */ +#define PHY_PHYCTRL2_OP_MOD_SHIFT 2 +#define PHY_PHYCTRL2_MODE_OP_MOD_STILL_NEG 0 +#define PHY_PHYCTRL2_MODE_OP_MOD_10MBPS_HD 1 +#define PHY_PHYCTRL2_MODE_OP_MOD_100MBPS_HD 2 +#define PHY_PHYCTRL2_MODE_OP_MOD_10MBPS_FD 5 +#define PHY_PHYCTRL2_MODE_OP_MOD_100MBPS_FD 6 + + +/*******************************************************************/ + +#endif /* _ETH_PHY_H */ diff --git a/source/LegacyDrivers/include/integer.h b/source/LegacyDrivers/include/integer.h new file mode 100644 index 0000000..16ad408 --- /dev/null +++ b/source/LegacyDrivers/include/integer.h @@ -0,0 +1,37 @@ +/*-------------------------------------------*/ +/* Integer type definitions for FatFs module */ +/*-------------------------------------------*/ + +#ifndef _INTEGER +#define _INTEGER + +#ifdef _WIN32 /* FatFs development platform */ + +#include +#include + +#else /* Embedded platform */ + +/* These types must be 16-bit, 32-bit or larger integer */ +typedef int INT; +typedef unsigned int UINT; + +/* These types must be 8-bit integer */ +typedef char CHAR; +typedef unsigned char UCHAR; +typedef unsigned char BYTE; + +/* These types must be 16-bit integer */ +typedef short SHORT; +typedef unsigned short USHORT; +typedef unsigned short WORD; +typedef unsigned short WCHAR; + +/* These types must be 32-bit integer */ +typedef long LONG; +typedef unsigned long ULONG; +typedef unsigned long DWORD; + +#endif + +#endif diff --git a/source/LegacyDrivers/include/mii.h b/source/LegacyDrivers/include/mii.h new file mode 100644 index 0000000..0ce90c6 --- /dev/null +++ b/source/LegacyDrivers/include/mii.h @@ -0,0 +1,30 @@ +/*! + * \file mii.h + * \brief Media Independent Interface (MII) driver + * \version $Revision: 1.2 $ + * \author Michael Norman + * + * \warning + * + */ + +#ifndef _MII_H_ +#define _MII_H_ + +/*******************************************************************/ + +#define MII_TIMEOUT 0x1FFFF +#define MII_LINK_TIMEOUT 0x1FFFF + +void +mii_init(int, int); + +int +mii_write(int, int, int, int); + +int +mii_read(int, int, int, int*); + +/*******************************************************************/ + +#endif /* _MII_H_ */ diff --git a/source/LegacyDrivers/include/nbuf.h b/source/LegacyDrivers/include/nbuf.h new file mode 100644 index 0000000..9d10211 --- /dev/null +++ b/source/LegacyDrivers/include/nbuf.h @@ -0,0 +1,237 @@ +// ---------------------------------------------------------------------- +// File: nbuf.h +// Purpose: Definitions for Network Buffer Allocation. +// +// Notes: +// +// ---------------------------------------------------------------------- + +#ifndef _NBUF_H_ +#define _NBUF_H_ + +// Define number of MACs +#define NUM_CHANNELS 1/*b06862*/ + +// Choose Enhanced Buffer Descriptor or Legacy +#define ENHANCED_BD + +//b06862: define Endianess for Little Endian architectures like ARM. +//Motorola/Freescale uses Big Endian or Register-Endianess +#define NBUF_LITTLE_ENDIAN + +// Transmit packet directly or copy to dedicated buffers. If packets +// are not alligned dedicated Tx buffers can be used +#define USE_DEDICATED_TX_BUFFERS + +// Buffer sizes in bytes (must be divisible by 16) +#define RX_BUFFER_SIZE 1520 +#define TX_BUFFER_SIZE 1520 + +// Number of Receive and Transmit Buffers and Buffer Descriptors +#define NUM_RXBDS 2 +#define NUM_TXBDS 2 + +//typedef unsigned short uint16_t; +//typedef unsigned char uint8_t; +//typedef unsigned int uint32_t; + +// Buffer Descriptor Format +#ifdef ENHANCED_BD + typedef struct + { + uint16_t status; /* control and status */ + uint16_t length; /* transfer length */ + uint8_t *data; /* buffer address */ + uint32_t ebd_status; + uint16_t length_proto_type; + uint16_t payload_checksum; + uint32_t bdu; + uint32_t timestamp; + uint32_t reserverd_word1; + uint32_t reserverd_word2; + } NBUF; +#else + typedef struct + { + uint16_t status; /* control and status */ + uint16_t length; /* transfer length */ + uint8_t *data; /* buffer address */ + } NBUF; +#endif /* ENHANCED_BD */ + +// ---------------------------------------------------------------------- +// Function Declarations +// ---------------------------------------------------------------------- +void +nbuf_alloc(int ch); + +void +nbuf_init(int); + +void +nbuf_start_rx(int); + +void +nbuf_flush(int); + +//NM - return value +void +enet_get_received_packet(int, NBUF *); + +//NM - return value +void +enet_fill_txbds(int, NBUF *); + +void +enet_transmit_packet(int,NBUF *); + +#ifdef NBUF_LITTLE_ENDIAN + +//For Freescale ARM Architecture + +// ---------------------------------------------------------------------- +// TX Buffer Descriptor Bit Definitions +// ---------------------------------------------------------------------- +#define TX_BD_R 0x0080 +#define TX_BD_TO1 0x0040 +#define TX_BD_W 0x0020 +#define TX_BD_TO2 0x0010 +#define TX_BD_L 0x0008 +#define TX_BD_TC 0x0004 +#define TX_BD_ABC 0x0002 + +// ---------------------------------------------------------------------- +// TX Enhanced BD Bit Definitions +// ---------------------------------------------------------------------- +#define TX_BD_INT 0x00000040 +#define TX_BD_TS 0x00000020 +#define TX_BD_PINS 0x00000010 +#define TX_BD_IINS 0x00000008 +#define TX_BD_TXE 0x00800000 +#define TX_BD_UE 0x00200000 +#define TX_BD_EE 0x00100000 +#define TX_BD_FE 0x00080000 +#define TX_BD_LCE 0x00040000 +#define TX_BD_OE 0x00020000 +#define TX_BD_TSE 0x00010000 + +#define TX_BD_BDU 0x00000080 + +// ---------------------------------------------------------------------- +// RX Buffer Descriptor Bit Definitions +// ---------------------------------------------------------------------- + +// Offset 0 flags - status: Big Endian +#define RX_BD_E 0x0080 +#define RX_BD_R01 0x0040 +#define RX_BD_W 0x0020 +#define RX_BD_R02 0x0010 +#define RX_BD_L 0x0008 +#define RX_BD_M 0x0001 +#define RX_BD_BC 0x8000 +#define RX_BD_MC 0x4000 +#define RX_BD_LG 0x2000 +#define RX_BD_NO 0x1000 +#define RX_BD_CR 0x0400 +#define RX_BD_OV 0x0200 +#define RX_BD_TR 0x0100 + +// ---------------------------------------------------------------------- +// RX Enhanced BD Bit Definitions +// ---------------------------------------------------------------------- +#define RX_BD_ME 0x00000080 +#define RX_BD_PE 0x00000004 +#define RX_BD_CE 0x00000002 +#define RX_BD_UC 0x00000001 + +#define RX_BD_INT 0x00008000 + +#define RX_BD_ICE 0x20000000 +#define RX_BD_PCR 0x10000000 +#define RX_BD_VLAN 0x04000000 +#define RX_BD_IPV6 0x02000000 +#define RX_BD_FRAG 0x01000000 + +#define RX_BD_BDU 0x00000080 + +#else + +//For Freescale ColdFire Architecture +// ---------------------------------------------------------------------- +// TX Buffer Descriptor Bit Definitions +// ---------------------------------------------------------------------- +#define TX_BD_R 0x8000 +#define TX_BD_TO1 0x4000 +#define TX_BD_W 0x2000 +#define TX_BD_TO2 0x1000 +#define TX_BD_L 0x0800 +#define TX_BD_TC 0x0400 +#define TX_BD_ABC 0x0200 + +// ---------------------------------------------------------------------- +// TX Enhanced BD Bit Definitions +// ---------------------------------------------------------------------- +#define TX_BD_INT 0x40000000 +#define TX_BD_TS 0x20000000 +#define TX_BD_PINS 0x10000000 +#define TX_BD_IINS 0x08000000 +#define TX_BD_TXE 0x00008000 +#define TX_BD_UE 0x00002000 +#define TX_BD_EE 0x00001000 +#define TX_BD_FE 0x00000800 +#define TX_BD_LCE 0x00000400 +#define TX_BD_OE 0x00000200 +#define TX_BD_TSE 0x00000100 + +#define TX_BD_BDU 0x80000000 + +// ---------------------------------------------------------------------- +// RX Buffer Descriptor Bit Definitions +// ---------------------------------------------------------------------- + +// Offset 0 flags - status +#define RX_BD_E 0x8000 +#define RX_BD_R01 0x4000 +#define RX_BD_W 0x2000 +#define RX_BD_R02 0x1000 +#define RX_BD_L 0x0800 +#define RX_BD_M 0x0100 +#define RX_BD_BC 0x0080 +#define RX_BD_MC 0x0040 +#define RX_BD_LG 0x0020 +#define RX_BD_NO 0x0010 +#define RX_BD_CR 0x0004 +#define RX_BD_OV 0x0002 +#define RX_BD_TR 0x0001 + +// ---------------------------------------------------------------------- +// RX Enhanced BD Bit Definitions +// ---------------------------------------------------------------------- +#define RX_BD_ME 0x80000000 +#define RX_BD_PE 0x04000000 +#define RX_BD_CE 0x02000000 +#define RX_BD_UC 0x01000000 +#define RX_BD_INT 0x00800000 +#define RX_BD_ICE 0x00000020 +#define RX_BD_PCR 0x00000010 +#define RX_BD_VLAN 0x00000004 +#define RX_BD_IPV6 0x00000002 +#define RX_BD_FRAG 0x00000001 + +#define RX_BD_BDU 0x80000000 + + +#endif + +// ---------------------------------------------------------------------- +// Defines for word offsets of various fields of RX Enhanced BDs +// ---------------------------------------------------------------------- +//#define RX_EBD_HEADER_LENGTH_OFFSET 12 +//#define RX_EBD_PROTOCOL_TYPE_OFFSET 12 +//#define RX_EBD_PAYLOAD_CHKSM_OFFSET 14 +//#define RX_EBD_BDU_OFFSET 16 +//#define RX_EBD_TIMESTAMP_MSB_OFFSET 20 +//#define RX_EBD_TIMESTAMP_LSB_OFFSET 22 + + +#endif /* _NBUF_H_ */ diff --git a/source/LegacyDrivers/include/usb_device_descriptor.h b/source/LegacyDrivers/include/usb_device_descriptor.h new file mode 100644 index 0000000..0cdb1b9 --- /dev/null +++ b/source/LegacyDrivers/include/usb_device_descriptor.h @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _USB_DEVICE_DESCRIPTOR_H_ +#define _USB_DEVICE_DESCRIPTOR_H_ 1 + +/******************************************************************************* +* Definitions +******************************************************************************/ +#define USB_DEVICE_SPECIFIC_BCD_VERSION (0x0200) +#define USB_DEVICE_DEMO_BCD_VERSION (0x0101U) + +/* Communication Class Codes */ +#define CDC_COMM_CLASS (0x02) +/* Data Class Codes */ +#define CDC_DATA_CLASS (0x0A) + +/* Communication Class SubClass Codes */ +#define USB_CDC_DIRECT_LINE_CONTROL_MODEL (0x01) +#define USB_CDC_ABSTRACT_CONTROL_MODEL (0x02) +#define USB_CDC_TELEPHONE_CONTROL_MODEL (0x03) +#define USB_CDC_MULTI_CHANNEL_CONTROL_MODEL (0x04) +#define USB_CDC_CAPI_CONTROL_MOPDEL (0x05) +#define USB_CDC_ETHERNET_NETWORKING_CONTROL_MODEL (0x06) +#define USB_CDC_ATM_NETWORKING_CONTROL_MODEL (0x07) +#define USB_CDC_WIRELESS_HANDSET_CONTROL_MODEL (0x08) +#define USB_CDC_DEVICE_MANAGEMENT (0x09) +#define USB_CDC_MOBILE_DIRECT_LINE_MODEL (0x0A) +#define USB_CDC_OBEX (0x0B) +#define USB_CDC_ETHERNET_EMULATION_MODEL (0x0C) + +/* Communication Class Protocol Codes */ +#define USB_CDC_NO_CLASS_SPECIFIC_PROTOCOL (0x00) /*also for Data Class Protocol Code */ +#define USB_CDC_AT_250_PROTOCOL (0x01) +#define USB_CDC_AT_PCCA_101_PROTOCOL (0x02) +#define USB_CDC_AT_PCCA_101_ANNEX_O (0x03) +#define USB_CDC_AT_GSM_7_07 (0x04) +#define USB_CDC_AT_3GPP_27_007 (0x05) +#define USB_CDC_AT_TIA_CDMA (0x06) +#define USB_CDC_ETHERNET_EMULATION_PROTOCOL (0x07) +#define USB_CDC_EXTERNAL_PROTOCOL (0xFE) +#define USB_CDC_VENDOR_SPECIFIC (0xFF) /*also for Data Class Protocol Code */ + +/* Data Class Protocol Codes */ +#define USB_CDC_PYHSICAL_INTERFACE_PROTOCOL (0x30) +#define USB_CDC_HDLC_PROTOCOL (0x31) +#define USB_CDC_TRANSPARENT_PROTOCOL (0x32) +#define USB_CDC_MANAGEMENT_PROTOCOL (0x50) +#define USB_CDC_DATA_LINK_Q931_PROTOCOL (0x51) +#define USB_CDC_DATA_LINK_Q921_PROTOCOL (0x52) +#define USB_CDC_DATA_COMPRESSION_V42BIS (0x90) +#define USB_CDC_EURO_ISDN_PROTOCOL (0x91) +#define USB_CDC_RATE_ADAPTION_ISDN_V24 (0x92) +#define USB_CDC_CAPI_COMMANDS (0x93) +#define USB_CDC_HOST_BASED_DRIVER (0xFD) +#define USB_CDC_UNIT_FUNCTIONAL (0xFE) + +/* Descriptor SubType in Communications Class Functional Descriptors */ +#define USB_CDC_HEADER_FUNC_DESC (0x00) +#define USB_CDC_CALL_MANAGEMENT_FUNC_DESC (0x01) +#define USB_CDC_ABSTRACT_CONTROL_FUNC_DESC (0x02) +#define USB_CDC_DIRECT_LINE_FUNC_DESC (0x03) +#define USB_CDC_TELEPHONE_RINGER_FUNC_DESC (0x04) +#define USB_CDC_TELEPHONE_REPORT_FUNC_DESC (0x05) +#define USB_CDC_UNION_FUNC_DESC (0x06) +#define USB_CDC_COUNTRY_SELECT_FUNC_DESC (0x07) +#define USB_CDC_TELEPHONE_MODES_FUNC_DESC (0x08) +#define USB_CDC_TERMINAL_FUNC_DESC (0x09) +#define USB_CDC_NETWORK_CHANNEL_FUNC_DESC (0x0A) +#define USB_CDC_PROTOCOL_UNIT_FUNC_DESC (0x0B) +#define USB_CDC_EXTENSION_UNIT_FUNC_DESC (0x0C) +#define USB_CDC_MULTI_CHANNEL_FUNC_DESC (0x0D) +#define USB_CDC_CAPI_CONTROL_FUNC_DESC (0x0E) +#define USB_CDC_ETHERNET_NETWORKING_FUNC_DESC (0x0F) +#define USB_CDC_ATM_NETWORKING_FUNC_DESC (0x10) +#define USB_CDC_WIRELESS_CONTROL_FUNC_DESC (0x11) +#define USB_CDC_MOBILE_DIRECT_LINE_FUNC_DESC (0x12) +#define USB_CDC_MDLM_DETAIL_FUNC_DESC (0x13) +#define USB_CDC_DEVICE_MANAGEMENT_FUNC_DESC (0x14) +#define USB_CDC_OBEX_FUNC_DESC (0x15) +#define USB_CDC_COMMAND_SET_FUNC_DESC (0x16) +#define USB_CDC_COMMAND_SET_DETAIL_FUNC_DESC (0x17) +#define USB_CDC_TELEPHONE_CONTROL_FUNC_DESC (0x18) +#define USB_CDC_OBEX_SERVICE_ID_FUNC_DESC (0x19) + +/* usb descriptor length */ +#define USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL (67) +#define USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC (5) +#define USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG (5) +#define USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT (4) +#define USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC (5) + +/* Configuration, interface and endpoint. */ +#define USB_DEVICE_CONFIGURATION_COUNT (1) +#define USB_DEVICE_STRING_COUNT (3) +#define USB_DEVICE_LANGUAGE_COUNT (1) + +#define USB_CDC_VCOM_CONFIGURE_INDEX (1) + +#define USB_CDC_VCOM_ENDPOINT_CIC_COUNT (1) +#define USB_CDC_VCOM_ENDPOINT_DIC_COUNT (2) +#define USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT (1) +#define USB_CDC_VCOM_BULK_IN_ENDPOINT (2) +#define USB_CDC_VCOM_BULK_OUT_ENDPOINT (3) +#define USB_CDC_VCOM_INTERFACE_COUNT (2) +#define USB_CDC_VCOM_COMM_INTERFACE_INDEX (0) +#define USB_CDC_VCOM_DATA_INTERFACE_INDEX (1) + +/* Packet size. */ +#define HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE (16) +#define FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE (16) +#define HS_CDC_VCOM_INTERRUPT_IN_INTERVAL (0x07) /* 2^(7-1) = 8ms */ +#define FS_CDC_VCOM_INTERRUPT_IN_INTERVAL (0x08) +#define HS_CDC_VCOM_BULK_IN_PACKET_SIZE (512) +#define FS_CDC_VCOM_BULK_IN_PACKET_SIZE (64) +#define HS_CDC_VCOM_BULK_OUT_PACKET_SIZE (512) +#define FS_CDC_VCOM_BULK_OUT_PACKET_SIZE (64) + +/* String descriptor length. */ +#define USB_DESCRIPTOR_LENGTH_STRING0 (4) +#define USB_DESCRIPTOR_LENGTH_STRING1 (38) +#define USB_DESCRIPTOR_LENGTH_STRING2 (42) + +#define USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE (0x24) +#define USB_DESCRIPTOR_TYPE_CDC_CS_ENDPOINT (0x25) + +/* Class code. */ +#define USB_DEVICE_CLASS (0x02) +#define USB_DEVICE_SUBCLASS (0x00) +#define USB_DEVICE_PROTOCOL (0x00) + +#define USB_DEVICE_MAX_POWER (0x32) + +#define USB_CDC_VCOM_CIC_CLASS (CDC_COMM_CLASS) +#define USB_CDC_VCOM_CIC_SUBCLASS (USB_CDC_ABSTRACT_CONTROL_MODEL) +#define USB_CDC_VCOM_CIC_PROTOCOL (USB_CDC_NO_CLASS_SPECIFIC_PROTOCOL) + +#define USB_CDC_VCOM_DIC_CLASS (CDC_DATA_CLASS) +#define USB_CDC_VCOM_DIC_SUBCLASS (0x00) +#define USB_CDC_VCOM_DIC_PROTOCOL (USB_CDC_NO_CLASS_SPECIFIC_PROTOCOL) + +/******************************************************************************* +* API +******************************************************************************/ +/*! + * @brief USB device set speed function. + * + * This function sets the speed of the USB device. + * + * Due to the difference of HS and FS descriptors, the device descriptors and configurations need to be updated to match + * current speed. + * As the default, the device descriptors and configurations are configured by using FS parameters for both EHCI and + * KHCI. + * When the EHCI is enabled, the application needs to call this fucntion to update device by using current speed. + * The updated information includes endpoint max packet size, endpoint interval, etc. + * + * @param handle The USB device handle. + * @param speed Speed type. USB_SPEED_HIGH/USB_SPEED_FULL/USB_SPEED_LOW. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DeviceSetSpeed(usb_device_handle handle, uint8_t speed); +/*! + * @brief USB device get device descriptor function. + * + * This function gets the device descriptor of the USB device. + * + * @param handle The USB device handle. + * @param deviceDescriptor The pointer to the device descriptor structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DeviceGetDeviceDescriptor(usb_device_handle handle, + usb_device_get_device_descriptor_struct_t *deviceDescriptor); +/*! + * @brief USB device get string descriptor function. + * + * This function gets the string descriptor of the USB device. + * + * @param handle The USB device handle. + * @param stringDescriptor Pointer to the string descriptor structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceGetStringDescriptor(usb_device_handle handle, + usb_device_get_string_descriptor_struct_t *stringDescriptor); +/*! + * @brief USB device get configuration descriptor function. + * + * This function gets the configuration descriptor of the USB device. + * + * @param handle The USB device handle. + * @param configurationDescriptor The pointer to the configuration descriptor structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DeviceGetConfigurationDescriptor( + usb_device_handle handle, usb_device_get_configuration_descriptor_struct_t *configurationDescriptor); +#endif /* _USB_DEVICE_DESCRIPTOR_H_ */ diff --git a/source/LegacyDrivers/source/DEFlashPartition.c b/source/LegacyDrivers/source/DEFlashPartition.c new file mode 100644 index 0000000..c7459c3 --- /dev/null +++ b/source/LegacyDrivers/source/DEFlashPartition.c @@ -0,0 +1,79 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : DEFlashPartition.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : DEFlashPartition.c +* Description : This function prepares the D/E-Flash block for use +* as D-Flash, E-Flash or a combination of both and +* initializes the EERAM. +* Arguments : PFLASH_SSD_CONFIG, UINT8,UINT8, pFLASHCOMMANDSEQUENCE +* Return Value : UINT32 +* +*************************************************************************/ + +UINT32 DEFlashPartition(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEDataSizeCode, \ + UINT8 DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +{ + UINT8 pCommandArray[6]; /* command sequence array */ + UINT32 returnCode; /* return code variable */ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* preparing passing parameter to program partition command */ + pCommandArray[0] = FTFx_PROGRAM_PARTITION; + pCommandArray[4] = EEEDataSizeCode; + pCommandArray[5] = DEPartitionCode; + + /* calling flash command sequence function to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 5, pCommandArray); + + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +/* end of file */ \ No newline at end of file diff --git a/source/LegacyDrivers/source/DFlashGetProtection.c b/source/LegacyDrivers/source/DFlashGetProtection.c new file mode 100644 index 0000000..f88d10d --- /dev/null +++ b/source/LegacyDrivers/source/DFlashGetProtection.c @@ -0,0 +1,79 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : DFlashGetProtection.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************* +* +* Function Name : DFlashGetProtection.c +* Description : This function retrieves current D-Flash protection status. +* Arguments : PFLASH_SSD_CONFIG, UINT8* +* Return Value : UINT32 +* +*************************************************************************/ + +UINT32 DFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, UINT8* protectStatus) +{ + UINT32 returnCode; /* return code variable */ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* Check if size of DFlash = 0 */ + if(PSSDConfig->DFlashBlockSize == 0) + { + returnCode = FTFx_ERR_EFLASHONLY; + goto EXIT; + } + else + { + /* Do nothing */ + } + + *protectStatus = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FDPROT_OFFSET); + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +/* end of file */ \ No newline at end of file diff --git a/source/LegacyDrivers/source/DFlashSetProtection.c b/source/LegacyDrivers/source/DFlashSetProtection.c new file mode 100644 index 0000000..8092b50 --- /dev/null +++ b/source/LegacyDrivers/source/DFlashSetProtection.c @@ -0,0 +1,110 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : DFlashSetProtection.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.2.2 09.15.2011 FPT Team Add code for checking CCIF bit +*************************************************************************/ + +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : DFlashSetProtection.c +* Description : This function sets the D-Flash protection to the +* intended protection status +* Arguments : PFLASH_SSD_CONFIG, UINT8 +* Return Value : UINT32 +* +*************************************************************************/ + +UINT32 DFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, UINT8 protectStatus) +{ + UINT8 registerValue; /* store data read from flash register */ + UINT32 returnCode; /* return code variable */ + UINT8 temp; + + /* set the default return as FTFx_OK */ + returnCode = FTFx_OK; + /* check CCIF bit of the flash status register, it's impossible to write to DPROT if command is in progress */ + if(FALSE == (REG_BIT_TEST(PSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET, FTFx_SSD_FSTAT_CCIF))) + { + returnCode = FTFx_ERR_CHANGEPROT; + goto EXIT; + } + /* Check if size of DFlash = 0 */ + if(PSSDConfig->DFlashBlockSize == 0) + { + returnCode = FTFx_ERR_EFLASHONLY; + goto EXIT; + } + else + { + /* Do nothing */ + } + + /* Read the value of FDPROT register */ + registerValue = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FDPROT_OFFSET); + + /* Check if normal mode */ + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FDPROT_OFFSET, 0xFF); + + if(REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FDPROT_OFFSET) != 0xFF) + { + /* if normal mode */ + temp = (UINT8)(protectStatus ^ registerValue); + if(!(temp & protectStatus)) + { + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FDPROT_OFFSET, protectStatus); + } + else + { + returnCode = FTFx_ERR_CHANGEPROT; + } + goto EXIT; + } + /* if unprotected or special mode */ + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FDPROT_OFFSET, protectStatus); + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +/* end of file */ \ No newline at end of file diff --git a/source/LegacyDrivers/source/EEEWrite.c b/source/LegacyDrivers/source/EEEWrite.c new file mode 100644 index 0000000..99d7c3e --- /dev/null +++ b/source/LegacyDrivers/source/EEEWrite.c @@ -0,0 +1,118 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : EEEWrite.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.1.4 09.20.2010 FPT Team Added protection violation error + checking. +0.2.0 09.27.2010 FPT Team Added the checking for protection + violation error. +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.3.1 05.16.2012 FPT Team Update to support Nevis2 devices +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : EEEWrite.c +* Description : This function is used to write data to EERAM +* when it is used as EEPROM emulator +* Arguments : PFLASH_SSD_CONFIG,UINT32 ,UINT32 ,UINT32 +* Return Value : UINT32 +* +************************************************************************/ + +UINT32 EEEWrite(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source) +{ + UINT32 returnCode; /* Return code variable */ + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + /* Check if EEE is enabled */ + if(REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET) & FTFx_SSD_FCNFG_EEERDY) + { + if(destination < PSSDConfig->EERAMBlockBase || \ + ((destination + size) > (PSSDConfig->EERAMBlockBase + PSSDConfig->EERAMBlockSize))) + { + returnCode = FTFx_ERR_RANGE; + goto EXIT; + } + else + { +#if DSC_56800EX == CPU_CORE + /* Convert word address to byte address in Nevis2 */ + destination *=2; +#endif + while(size > 0) + { + + WRITE8(destination,READ8(source)); + + while(FALSE == REG_BIT_TEST(PSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET, FTFx_SSD_FCNFG_EEERDY)) + { + /* wait till EEERDY bit is set */ + } + /* Check for protection violation error */ + if(REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET) & FTFx_SSD_FSTAT_FPVIOL) + { + returnCode = FTFx_ERR_PVIOL; + break; + } + + /* update destination address for next iteration */ + destination += 1; + /* update size for next iteration */ + size -= 1; + + /* increment the source adress by 1 */ + source += 1; + } + } + } + else + { + returnCode = FTFx_ERR_NOEEE; + goto EXIT; + } + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + return(returnCode); +} +/* end of file */ \ No newline at end of file diff --git a/source/LegacyDrivers/source/EERAMGetProtection.c b/source/LegacyDrivers/source/EERAMGetProtection.c new file mode 100644 index 0000000..a03c6ec --- /dev/null +++ b/source/LegacyDrivers/source/EERAMGetProtection.c @@ -0,0 +1,77 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : EERAMGetProtection.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" +/************************************************************************ +* +* Function Name : EERAMGetProtection.c +* Description : This function retrieves current EERAM protection status. +* Arguments : PFLASH_SSD_CONFIG, UINT8* +* Return Value : UINT32 +* +*************************************************************************/ + +UINT32 EERAMGetProtection(PFLASH_SSD_CONFIG PSSDConfig, UINT8* protectStatus) +{ + UINT32 returnCode; /* return code variable */ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* Check if EERAM is set for EEE */ + if(REG_BIT_TEST(PSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET, FTFx_SSD_FCNFG_EEERDY)) + { + /* EERAM is set for EEE */ + *protectStatus = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FEPROT_OFFSET); + } + else + { + returnCode = FTFx_ERR_NOEEE; + goto EXIT; + } + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +/* end of file */ \ No newline at end of file diff --git a/source/LegacyDrivers/source/EERAMSetProtection.c b/source/LegacyDrivers/source/EERAMSetProtection.c new file mode 100644 index 0000000..aa99c3e --- /dev/null +++ b/source/LegacyDrivers/source/EERAMSetProtection.c @@ -0,0 +1,108 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : EERAMGetProtection.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.2.2 09.15.2011 FPT Team Add code for checking CCIF bit +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" +/************************************************************************ +* +* Function Name : EERAMGetProtection.c +* Description : This function retrieves current EERAM protection status. +* Arguments : PFLASH_SSD_CONFIG, UINT8 +* Return Value : UINT32 +* +*************************************************************************/ + +UINT32 EERAMSetProtection(PFLASH_SSD_CONFIG PSSDConfig, UINT8 protectStatus) +{ + UINT8 registerValue; /* store data read from flash register */ + UINT32 returnCode; /* return code variable */ + UINT8 temp; + + /* set the default return as FTFx_OK */ + returnCode = FTFx_OK; + /* check CCIF bit of the flash status register, it's impossible to write to FEPROT if command is in progress */ + if(FALSE == (REG_BIT_TEST(PSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET, FTFx_SSD_FSTAT_CCIF))) + { + returnCode = FTFx_ERR_CHANGEPROT; + goto EXIT; + } + /* Check if EERAM is set for EEE */ + if(!(REG_BIT_TEST(PSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET, FTFx_SSD_FCNFG_EEERDY))) + { + /* EERAM is not set for EEE */ + returnCode = FTFx_ERR_NOEEE; + goto EXIT; + } + else + { + /* Do nothing */ + } + + /* Read the value of FDPROT register */ + registerValue = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FEPROT_OFFSET); + + /* Check if normal mode */ + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FEPROT_OFFSET, 0xFF); + + if(REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FEPROT_OFFSET) != 0xFF) + { + /* if normal mode */ + temp = (UINT8)(protectStatus ^ registerValue); + if(!(temp & protectStatus)) + { + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FEPROT_OFFSET, protectStatus); + } + else + { + returnCode = FTFx_ERR_CHANGEPROT; + } + goto EXIT; + } + /* if unprotected or special mode */ + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FEPROT_OFFSET, protectStatus); + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +/* end of file */ \ No newline at end of file diff --git a/source/LegacyDrivers/source/FTFx_KX_256K_256K_4K_2K_2K.h b/source/LegacyDrivers/source/FTFx_KX_256K_256K_4K_2K_2K.h new file mode 100644 index 0000000..a836b8c --- /dev/null +++ b/source/LegacyDrivers/source/FTFx_KX_256K_256K_4K_2K_2K.h @@ -0,0 +1,390 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2012, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FTFx_KX_256K_256K_4K_2K_2K.h * +* DATE : June 19, 2012 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.19.2012 FPT Team Initial Version +*************************************************************************/ + +#ifndef _FTFx_KX_256K_256K_4K_2K_2K_H_ +#define _FTFx_KX_256K_256K_4K_2K_2K_H_ + +#include "SSD_FTFx_Common.h" + +#define BYTE2WORD(x) (x) + +/* Endianness */ +#define ENDIANNESS LITTLE_ENDIAN + +/* cpu core */ +#define CPU_CORE ARM_CM4 + +/* PFlash sector size */ +#define FTFx_PSECTOR_SIZE 0x00000800 /* 2 KB size */ +/* DFlash sector size */ +#define FTFx_DSECTOR_SIZE 0x00000800 /* 2 KB size */ +#define DEBLOCK_SIZE 0x00040000 /* 256 KB size */ + +/* EEE Data Set Size Field Description */ +#define EEESIZE_0000 0x00000000 /* Reserved */ +#define EEESIZE_0001 0x00000000 /* Reserved */ +#define EEESIZE_0010 0x00001000 +#define EEESIZE_0011 0x00000800 +#define EEESIZE_0100 0x00000400 +#define EEESIZE_0101 0x00000200 +#define EEESIZE_0110 0x00000100 +#define EEESIZE_0111 0x00000080 +#define EEESIZE_1000 0x00000040 +#define EEESIZE_1001 0x00000020 +#define EEESIZE_1010 0x00000000 /* Reserved */ +#define EEESIZE_1011 0x00000000 /* Reserved */ +#define EEESIZE_1100 0x00000000 /* Reserved */ +#define EEESIZE_1101 0x00000000 /* Reserved */ +#define EEESIZE_1110 0x00000000 /* Reserved */ +#define EEESIZE_1111 0x00000000 /* Default value */ + +/* D/E-Flash Partition Code Field Description */ +#define DEPART_0000 0x00040000 +#define DEPART_0001 0x00040000 /* Reserved */ +#define DEPART_0010 0x0003C000 +#define DEPART_0011 0x00038000 +#define DEPART_0100 0x00030000 +#define DEPART_0101 0x00020000 +#define DEPART_0110 0x00000000 +#define DEPART_0111 0x00040000 /* Reserved */ +#define DEPART_1000 0x00000000 +#define DEPART_1001 0x00040000 /* Reserved */ +#define DEPART_1010 0x00004000 +#define DEPART_1011 0x00008000 +#define DEPART_1100 0x00010000 +#define DEPART_1101 0x00020000 +#define DEPART_1110 0x00040000 +#define DEPART_1111 0x00040000 /* Reserved */ +/*destination to read Dflash IFR area*/ +#define DFLASH_IFR_READRESOURCE_ADDRESS 0x8000FC + +/* Address offset and size of PFlash IFR and DFlash IFR */ +#define PFLASH_IFR_OFFSET 0x00000000 +#define PFLASH_IFR_SIZE 0x00000100 +#define DFLASH_IFR_OFFSET 0x00000000 +#define DFLASH_IFR_SIZE 0x00000100 + +/* Size for checking alignment of a section */ +#define ERSBLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of erase block function */ +#define PGMCHK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of program check function */ +#define PPGMSEC_ALIGN_SIZE FTFx_PHRASE_SIZE /* check align of program section function */ +#define DPGMSEC_ALIGN_SIZE FTFx_PHRASE_SIZE /* check align of program section function */ +#define RD1BLK_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of verify block function */ +#define PRD1SEC_ALIGN_SIZE FTFx_PHRASE_SIZE /* check align of verify section function */ +#define DRD1SEC_ALIGN_SIZE FTFx_PHRASE_SIZE /* check align of verify section function */ +#define SWAP_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of swap function*/ +#define RDRSRC_ALIGN_SIZE FTFx_LONGWORD_SIZE /* check align of read resource function */ +#define RDONCE_INDEX_MAX 0xF /* maximum index in read once command */ + +/* -------------------- Function Pointer ------------------------------- */ +typedef UINT32 (*pFLASHCOMMANDSEQUENCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* Flash initialization */ +typedef UINT32 (*pFLASHINIT) (PFLASH_SSD_CONFIG PSSDConfig); + +/* P-Flash get protection */ +typedef UINT32 (*pPFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +typedef UINT32 (*pPFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +typedef UINT32 (*pFLASHGETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +typedef UINT32 (*pFLASHSETINTERRUPTENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +typedef UINT32 (*pFLASHGETSECURITYSTATE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +typedef UINT32 (*pFLASHSECURITYBYPASS) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +typedef UINT32 (*pFLASHERASEALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +typedef UINT32 (*pFLASHERASEBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +typedef UINT32 (*pFLASHERASESECTOR) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +typedef UINT32 (*pFLASHERASESUSPEND) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +typedef UINT32 (*pFLASHERASERESUME) (PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +typedef UINT32 (*pFLASHPROGRAMSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +typedef UINT32 (*pFLASHCHECKSUM) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +typedef UINT32 (*pFLASHVERIFYALLBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +typedef UINT32 (*pFLASHVERIFYBLOCK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +typedef UINT32 (*pFLASHVERIFYSECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +typedef UINT32 (*pFLASHREADONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +typedef UINT32 (*pFLASHPROGRAMONCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +typedef UINT32 (*pFLASHPROGRAMCHECK) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +typedef UINT32 (*pFLASHREADRESOURCE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program Longword */ +typedef UINT32 (*pFLASHPROGRAMLONGWORD) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* D-Flash get protection */ +typedef UINT32 (*pDFLASHGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); +/* D-Flash set protection */ +typedef UINT32 (*pDFLASHSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); + +/* EERAM get protection */ +typedef UINT32 (*pEERAMGETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* EERAM set protection */ +typedef UINT32 (*pEERAMSETPROTECTION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); +/* Flash D/E-Flash Partition */ +typedef UINT32 (*pDEFLASHPARTITION) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEDataSizeCode, \ + UINT8 DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash Set EEEEnable */ +typedef UINT32 (*pSETEEEENABLE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEEnable); + +/* EEPROM Emulator Write */ +typedef UINT32 (*pEEEWRITE) (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source); +/*---------------- Function Prototypes for Flash SSD --------------------*/ + +/* Flash initialization */ +extern UINT32 FlashInit(PFLASH_SSD_CONFIG PSSDConfig); + +/* Internal function. Called by driver APIs only */ +/* Flash command sequence */ +extern UINT32 FlashCommandSequence(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray); + +/* P-Flash get protection */ +extern UINT32 PFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32* protectStatus); + +/* P-Flash set protection */ +extern UINT32 PFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus); + +/* Flash get interrupt enable */ +extern UINT32 FlashGetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* interruptState); + +/* Flash set interrupt enable */ +extern UINT32 FlashSetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 interruptState); + +/* Flash get security state */ +extern UINT32 FlashGetSecurityState(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* securityState); + +/* Flash security bypass */ +extern UINT32 FlashSecurityBypass(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase all Block */ +extern UINT32 FlashEraseAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase Block */ +extern UINT32 FlashEraseBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase sector */ +extern UINT32 FlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash erase suspend */ +extern UINT32 FlashEraseSuspend(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash erase resume */ +extern UINT32 FlashEraseResume(PFLASH_SSD_CONFIG PSSDConfig); + +/* Flash program Section */ +extern UINT32 FlashProgramSection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash checksum */ +extern UINT32 FlashCheckSum(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum); + +/* Flash verify all block */ +extern UINT32 FlashVerifyAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify block */ +extern UINT32 FlashVerifyBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash verify section*/ +extern UINT32 FlashVerifySection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read once */ +extern UINT32 FlashReadOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program once */ +extern UINT32 FlashProgramOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash program check */ +extern UINT32 FlashProgramCheck(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash read resource */ +extern UINT32 FlashReadResource(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* Flash program Longword */ +extern UINT32 FlashProgramLongword(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/* D-Flash get protection */ +extern UINT32 DFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* D-Flash set protection */ +extern UINT32 DFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); + +/* EERAM get protection */ +extern UINT32 EERAMGetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* protectStatus); + +/* EERAM set protection */ +extern UINT32 EERAMSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 protectStatus); +/* Flash D/E-Flash Partition */ +extern UINT32 DEFlashPartition(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEDataSizeCode, \ + UINT8 DEPartitionCode, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); +/* Flash Set EEEEnable */ +extern UINT32 SetEEEEnable(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 EEEEnable); + +/* EEPROM Emulator Write */ +extern UINT32 EEEWrite(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source); + +#endif /* _FTFx_KX_256K_256K_4K_2K_2K_H_ */ diff --git a/source/LegacyDrivers/source/FlashCheckSum.c b/source/LegacyDrivers/source/FlashCheckSum.c new file mode 100644 index 0000000..0b344ef --- /dev/null +++ b/source/LegacyDrivers/source/FlashCheckSum.c @@ -0,0 +1,167 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashCheckSum.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.2.2 02.21.2011 FPT Team Fixed boundary condition +0.3.1 05.16.2012 FPT Team Update to support Nevis2 devices +0.3.3 08.03.2012 FPT Team Optimize code sizefor L2K/L1PT + Nevis2, adn Anguilla Silver +************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" +#if (CPU_CORE == DSC_56800EX) + #define WORD2BYTE(x) ((x)<<1) +#else + #define WORD2BYTE(x) (x) +#endif +/*********************************************************************** +* +* Function Name : FlashCheckSum.c +* Description : This function is used to calculate checksum value +* for the specified flash range. +* Arguments : PFLASH_SSD_CONFIG,UINT32 ,UINT32 ,UINT32* +* Return Value : UINT32 +* +************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4"))) FlashCheckSum(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum) +#else +UINT32 FlashCheckSum(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32* PSum) +#endif +{ + UINT32 counter; /* Counter for callback operation */ + UINT32 data; /* Data read from Flash address */ + UINT32 returnCode; /* Return code variable */ + UINT32 endAddress; /* P Flash end address */ + + /* initialize counter variable */ + counter = 0; + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* calculating Flash end address */ + endAddress = WORD2BYTE(destination) + size; + + /* check for valid range of the target addresses */ + if((destination < PSSDConfig->PFlashBlockBase) || \ + (endAddress > (WORD2BYTE(PSSDConfig->PFlashBlockBase) + PSSDConfig->PFlashBlockSize))) + { +#if(DEBLOCK_SIZE) + if((destination < PSSDConfig->DFlashBlockBase) || \ + (endAddress > (WORD2BYTE(PSSDConfig->DFlashBlockBase) + PSSDConfig->DFlashBlockSize))) + { +#endif /* End of if(DEBLOCK_SIZE) */ + /* return an error code FTFx_ERR_RANGE */ + returnCode = FTFx_ERR_RANGE; + goto EXIT; +#if(DEBLOCK_SIZE) + } + else + { + /* No Error: Do nothing */ + } +#endif /* End of if(DEBLOCK_SIZE) */ + } + else + { + /* No Error: Do nothing */ + } +#if DSC_56800EX == CPU_CORE + destination *=2; + endAddress = destination + size; +#endif + if(FTFx_OK == returnCode) + { + *PSum = 0; + /* doing sum operation */ + while(destination < endAddress) + { + data = READ8(destination); + *PSum += (UINT32)data; + destination += 1; + size -= 1; + + /* Check if need to serve callback function */ + if((++counter) >= FLASH_CALLBACK_CS) + { + /* serve callback function if counter reaches limitation */ + if(NULL_CALLBACK != PSSDConfig->CallBack) + { + (PSSDConfig->CallBack)(); + } + else + { + /* do nothing */ + } + + /* Reset counter */ + counter = 0; + } + else + { + /* do nothing */ + } + } + } + else + { + /* error occurred */ + } + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ diff --git a/source/LegacyDrivers/source/FlashCommandSequence.c b/source/LegacyDrivers/source/FlashCommandSequence.c new file mode 100644 index 0000000..2d8eaf6 --- /dev/null +++ b/source/LegacyDrivers/source/FlashCommandSequence.c @@ -0,0 +1,157 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2010, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashCommandSequence.c * +* DATE : September 27,2010 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.3.3 08.03.2012 FPT Team Optimize code size for L1PT, L2K, + Nevis2, adn Anguilla Silver +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashCommandSequence +* Description : Perform command write sequence for flash operation +* Arguments : PFLASH_SSD_CONFIG, UINT8, UINT8* +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4"))) FlashCommandSequence (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray) +#else + +UINT32 FlashCommandSequence (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 index, \ + UINT8* pCommandArray) +#endif +{ + UINT8 counter; /* for loop counter variable */ + UINT8 registerValue; /* store data read from flash register */ + UINT32 returnCode; /* return code variable */ + + /* set the default return as FTFx_OK */ + returnCode = FTFx_OK; + + /* check CCIF bit of the flash status register */ + + while(FALSE == (REG_BIT_TEST(PSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET, FTFx_SSD_FSTAT_CCIF))) + { + /* wait till CCIF bit is set */ + } + + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */ + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET, \ + (FTFx_SSD_FSTAT_RDCOLERR | FTFx_SSD_FSTAT_ACCERR | FTFx_SSD_FSTAT_FPVIOL)); + + /* load FCCOB registers */ + for(counter=0; counter<=index; counter++) + { + switch (counter) + { + case 0: REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET, pCommandArray[counter]); + break; + case 1: REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET, pCommandArray[counter]); + break; + case 2: REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB2_OFFSET, pCommandArray[counter]); + break; + case 3: REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB3_OFFSET, pCommandArray[counter]); + break; + case 4: REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB4_OFFSET, pCommandArray[counter]); + break; + case 5: REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET, pCommandArray[counter]); + break; + case 6: REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB6_OFFSET, pCommandArray[counter]); + break; + case 7: REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB7_OFFSET, pCommandArray[counter]); + break; + case 8: REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB8_OFFSET, pCommandArray[counter]); + break; + case 9: REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB9_OFFSET, pCommandArray[counter]); + break; + case 10: REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOBA_OFFSET, pCommandArray[counter]); + break; + case 11: REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOBB_OFFSET, pCommandArray[counter]); + break; + default: break; + } + } + + /* clear CCIF bit */ + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET, FTFx_SSD_FSTAT_CCIF); + + /* check CCIF bit */ + while(FALSE == (REG_BIT_TEST(PSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET, FTFx_SSD_FSTAT_CCIF))) + { + /* wait till CCIF bit is set */ + /* serve callback function if counter reaches limitation */ + if(NULL_CALLBACK != PSSDConfig->CallBack) + { + (PSSDConfig->CallBack)(); + } + else + { + /* do nothing */ + } + } + + /* Check error bits */ + /*Get flash status register value */ + registerValue = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET); + + /* checking access error */ + if(0 != (registerValue & FTFx_SSD_FSTAT_ACCERR)) + { + /* return an error code FTFx_ERR_ACCERR */ + returnCode = FTFx_ERR_ACCERR; + } + /* checking protection error */ + else if(0 != (registerValue & FTFx_SSD_FSTAT_FPVIOL)) + { + /* return an error code FTFx_ERR_PVIOL */ + returnCode = FTFx_ERR_PVIOL; + } + /* checking MGSTAT0 non-correctable error */ + else if(0 != (registerValue & FTFx_SSD_FSTAT_MGSTAT0)) + { + /* return an error code FTFx_ERR_MGSTAT0 */ + returnCode = FTFx_ERR_MGSTAT0; + } + else + { + /* do nothing*/ + } + + return(returnCode); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ + diff --git a/source/LegacyDrivers/source/FlashEraseAllBlock.c b/source/LegacyDrivers/source/FlashEraseAllBlock.c new file mode 100644 index 0000000..01043e8 --- /dev/null +++ b/source/LegacyDrivers/source/FlashEraseAllBlock.c @@ -0,0 +1,93 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashEraseAllBlock.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.3.3 08.03.2012 FPT Team Optimize code size for L2K/L1PT + Nevis2, and Anguilla Silver +*************************************************************************/ + +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashEraseAllBlock.c +* Description : The Erase All Blocks operation will erase all Flash + memory, initialize the EERAM, verify all memory + contents, then release MCU security. +* Arguments : PFLASH_SSD_CONFIG, pFLASHCOMMANDSEQUENCE +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4"))) FlashEraseAllBlock (PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#else +UINT32 FlashEraseAllBlock (PFLASH_SSD_CONFIG PSSDConfig, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#endif +{ + UINT8 commandArray[1]; /* command sequence array */ + UINT32 returnCode; /* return code variable */ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* preparing passing parameter to erase all flash blocks */ + /* 1st element for the FCCOB register */ + commandArray[0] = FTFx_ERASE_ALL_BLOCK; + + /* calling flash command sequence function to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 0, commandArray); + + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif + +/* end of file */ \ No newline at end of file diff --git a/source/LegacyDrivers/source/FlashEraseBlock.c b/source/LegacyDrivers/source/FlashEraseBlock.c new file mode 100644 index 0000000..3ba0e6f --- /dev/null +++ b/source/LegacyDrivers/source/FlashEraseBlock.c @@ -0,0 +1,123 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashEraseBlock.c * +* DATE : Dec 27,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.2.2 09.15.2011 FPT Team Update the address alignment checking. +0.2.3 12.27.2011 FPT Team Update to support more Kinetis derivatives. +0.3.1 05.16.2012 FPT Team Update to support Nevis2 devices +0.3.3 08.10.2012 FPT Team Update to support Anguilla Silver derivatives +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashEraseBlock.c +* Description : The Erase Flash Block operation will erase all addresses in a single P-Flash or D-Flash block. +* Arguments : PFLASH_SSD_CONFIG, UINT32, pFLASHCOMMANDSEQUENCE +* Return Value : UINT32 +* +*************************************************************************/ + +UINT32 FlashEraseBlock (PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +{ + UINT8 pCommandArray[4]; /* command sequence array */ + UINT32 returnCode; /* return code variable */ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* check if the destination is longword aligned or not */ + if (0 != (destination % ERSBLK_ALIGN_SIZE)) + { + /* return an error code FTFx_ERR_ADDR */ + returnCode = FTFx_ERR_ADDR; + goto EXIT; + } + + /* check for valid range of the target addresses */ + if((destination < PSSDConfig->PFlashBlockBase) || \ + (destination >= (PSSDConfig->PFlashBlockBase + BYTE2WORD(PSSDConfig->PFlashBlockSize)))) + { + if((destination < PSSDConfig->DFlashBlockBase) || \ + (destination >= (PSSDConfig->DFlashBlockBase + BYTE2WORD(PSSDConfig->DFlashBlockSize)))) + { + /* return an error code FTFx_ERR_RANGE */ + returnCode = FTFx_ERR_RANGE; + goto EXIT; + } + else + { + /* Convert System memory address to FTFx internal memory address */ +#if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->DFlashBlockBase)+ 0x800000); +#else + destination = destination - PSSDConfig->DFlashBlockBase + 0x800000; +#endif + } + } + else + { + /* Convert System memory address to FTFx internal memory address */ +#if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->PFlashBlockBase)); +#else + destination -= PSSDConfig->PFlashBlockBase; +#endif + } + + /* preparing passing parameter to erase a flash block */ + pCommandArray[0] = FTFx_ERASE_BLOCK; + pCommandArray[1] = (UINT8)(destination >> 16); + pCommandArray[2] = (UINT8)((destination >> 8) & 0xFF); + pCommandArray[3] = (UINT8)(destination & 0xFF); + + /* calling flash command sequence function to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 3, pCommandArray); + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} + + +/* end of file */ diff --git a/source/LegacyDrivers/source/FlashEraseResume.c b/source/LegacyDrivers/source/FlashEraseResume.c new file mode 100644 index 0000000..9bdff62 --- /dev/null +++ b/source/LegacyDrivers/source/FlashEraseResume.c @@ -0,0 +1,92 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashEraseResume.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.3.3 08.03.2012 FPT Team Optimize code size for L2K/L1PT + Nevis2, and Anguilla Silver +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashEraseResume.c +* Description : This function is used to resume a previous suspended +* operation of flash erase sector command. +* Arguments : PFLASH_SSD_CONFIG +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4"))) FlashEraseResume(PFLASH_SSD_CONFIG PSSDConfig) +#else +UINT32 FlashEraseResume(PFLASH_SSD_CONFIG PSSDConfig) +#endif +{ + + UINT32 returnCode; /* return code variable */ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + /* check ERSSUSP bit of the flash configuration register */ + if(TRUE == (REG_BIT_TEST(PSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET, FTFx_SSD_FCNFG_ERSSUSP))) + { + /* If the ERSSUSP bit is set, */ + /* Clear CCIF bit to resumimg the previous suspended Erasing */ + REG_BIT_CLEAR(PSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET, FTFx_SSD_FSTAT_CCIF); + } + else + { + /* Do nothing */ + } + + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ \ No newline at end of file diff --git a/source/LegacyDrivers/source/FlashEraseSector.c b/source/LegacyDrivers/source/FlashEraseSector.c new file mode 100644 index 0000000..94d1f34 --- /dev/null +++ b/source/LegacyDrivers/source/FlashEraseSector.c @@ -0,0 +1,175 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashEraseSector.c * +* DATE : Dec 27,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.2.2 12.27.2011 FPT Team Update to support more Kinetis derivatives. +0.3.1 05.16.2012 FPT Team Update to support Nevis2 devices +0.3.3 08.03.2012 FPT Team Optimized for L2K/L1PT + Update to support Anguilla Silver derivatives +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/**************************************************************************** +* +* Function Name : FlashEraseSector +* Description : Perform erase operation on Flash +* Arguments : PFLASH_SSD_CONFIG, UINT32, UINT32, pFLASHCOMMANDSEQUENCE +* Return Value : UINT32 +* +*****************************************************************************/ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4"))) FlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#else +UINT32 FlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#endif +{ + UINT8 pCommandArray[4]; /* command sequence array */ + UINT32 returnCode; /* return code variable */ + UINT32 endAddress; /* storing end address */ + UINT32 sectorSize; /* size of one sector */ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* calculating Flash end address */ + endAddress = destination + BYTE2WORD(size); + /* check for valid range of the target addresses */ + if((destination < PSSDConfig->PFlashBlockBase) || \ + (endAddress > (PSSDConfig->PFlashBlockBase + BYTE2WORD(PSSDConfig->PFlashBlockSize)))) + { +#if (DEBLOCK_SIZE) + if((destination < PSSDConfig->DFlashBlockBase) || \ + (endAddress > (PSSDConfig->DFlashBlockBase + BYTE2WORD(PSSDConfig->DFlashBlockSize)))) + { +#endif /* End of if(DEBLOCK_SIZE) */ + /* return an error code FTFx_ERR_RANGE */ + returnCode = FTFx_ERR_RANGE; + goto EXIT; +#if (DEBLOCK_SIZE) + } + else + { + /* Convert System memory address to FTFx internal memory address */ + #if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->DFlashBlockBase)+ 0x800000); + #else + destination = destination - PSSDConfig->DFlashBlockBase + 0x800000; + #endif + sectorSize = FTFx_DSECTOR_SIZE; + } +#endif /* End of #if(DEBLOCK_SIZE) */ + } + else + { + /* Convert System memory address to FTFx internal memory address */ +#if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->PFlashBlockBase)); +#else + destination -= PSSDConfig->PFlashBlockBase; +#endif + sectorSize = FTFx_PSECTOR_SIZE; + } + + /* check if the destination is sector aligned or not */ + if (destination & (sectorSize-1)) + { + /* return an error code FTFx_ERR_ADDR */ + returnCode = FTFx_ERR_ADDR; + goto EXIT; + } + + /* check if the size is sector alignment or not */ + if(size & (sectorSize-1)) + { + /* return an error code FTFx_ERR_SIZE */ + returnCode = FTFx_ERR_SIZE; + goto EXIT; + } + + /* check for error return code */ + if(FTFx_OK == returnCode) + { + + while(size > 0) + { + /* preparing passing parameter to erase a flash block */ + pCommandArray[0] = FTFx_ERASE_SECTOR; + pCommandArray[1] = (UINT8)(destination >> 16); + pCommandArray[2] = (UINT8)((destination >> 8) & 0xFF); + pCommandArray[3] = (UINT8)(destination & 0xFF); + + /* calling flash command sequence function to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 3, pCommandArray); + + /* checking the success of command execution */ + if(FTFx_OK != returnCode) + { + break; + } + else + { + /* update size and destination address */ + size -= sectorSize; + destination += sectorSize; + } + } + } + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ + diff --git a/source/LegacyDrivers/source/FlashEraseSuspend.c b/source/LegacyDrivers/source/FlashEraseSuspend.c new file mode 100644 index 0000000..3f5eaf5 --- /dev/null +++ b/source/LegacyDrivers/source/FlashEraseSuspend.c @@ -0,0 +1,97 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashEraseSuspend.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.3.1 06.06.2012 FPT Team Add waiting for CCIF bit after setting ERSSUSP +0.3.3 08.03.2012 FPT Team Optimize code size for L2K/L1PT + Nevis2, and Anguilla Silver +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashEraseSuspend.c +* Description : This function is used to suspend a current operation +* of flash erase sector command. +* Arguments : PFLASH_SSD_CONFIG +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4"))) FlashEraseSuspend(PFLASH_SSD_CONFIG PSSDConfig) +#else +UINT32 FlashEraseSuspend(PFLASH_SSD_CONFIG PSSDConfig) +#endif +{ + UINT32 returnCode; /* return code variable */ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* check CCIF bit of the flash status register */ + if(FALSE == (REG_BIT_TEST(PSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET, FTFx_SSD_FSTAT_CCIF))) + { + /* If the command write sequence in progressing, */ + /* Set ERSSUSP bit in FCNFG register */ + REG_BIT_SET(PSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET, FTFx_SSD_FCNFG_ERSSUSP); + while(FALSE == (REG_BIT_TEST(PSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET, FTFx_SSD_FSTAT_CCIF))) + { + /* wait till CCIF bit is set */ + } + } + else + { + /* Do nothing */ + } + + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ \ No newline at end of file diff --git a/source/LegacyDrivers/source/FlashGetInterruptEnable.c b/source/LegacyDrivers/source/FlashGetInterruptEnable.c new file mode 100644 index 0000000..f5e65fc --- /dev/null +++ b/source/LegacyDrivers/source/FlashGetInterruptEnable.c @@ -0,0 +1,90 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashGetInterruptEnable.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.3.3 08.03.2012 FPT Team Optimize code size for L2K/L1PT + Nevis2, and Anguilla Silver +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashGetInterruptEnable +* Description : This function will read the FCNFG register and +* return the interrupt enable states for Flash +* interrupt types. +* Arguments : PFLASH_SSD_CONFIG, UINT8* +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4"))) FlashGetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, UINT8* interruptState) +#else +UINT32 FlashGetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, UINT8* interruptState) +#endif +{ + /* store data read from flash register */ + UINT8 registerValue; + + /* Initial interrupt state value */ + *interruptState = 0; + + /*Get flash configration register value */ + registerValue = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET); + + /* Add command complete interrupt enable bit value */ + /* CCIE bit of the FCNFG register */ + *interruptState |= (registerValue & (FTFx_SSD_FCNFG_CCIE | FTFx_SSD_FCNFG_RDCOLLIE)); + + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(FTFx_OK); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ + diff --git a/source/LegacyDrivers/source/FlashGetSecurityState.c b/source/LegacyDrivers/source/FlashGetSecurityState.c new file mode 100644 index 0000000..f788223 --- /dev/null +++ b/source/LegacyDrivers/source/FlashGetSecurityState.c @@ -0,0 +1,103 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashGetSecurityState.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.3.3 08.03.2012 FPT Team Optimize code size for L2K/L1PT + Nevis2, and Anguilla Silver +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" +/************************************************************************ +* +* Function Name : FlashGetSecurityState.c +* Description : This function retrieves the current Flash security +* status, including the security enabling state and +* the backdoor key enabling state. +* Arguments : PFLASH_SSD_CONFIG, UINT8* +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4"))) FlashGetSecurityState(PFLASH_SSD_CONFIG PSSDConfig, UINT8* securityState) +#else +UINT32 FlashGetSecurityState(PFLASH_SSD_CONFIG PSSDConfig, UINT8* securityState) +#endif +{ + /* store data read from flash register */ + UINT8 registerValue; + + /*Get flash security register value */ + registerValue = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FSEC_OFFSET); + + /* check the status of the flash security bits in the security register */ + if(FLASH_SECURITY_STATE_UNSECURED == (registerValue & FTFx_SSD_FSEC_SEC)) + { + /* Flash in unsecured state */ + *securityState = FLASH_NOT_SECURE; + } + else + { + /* Flash in secured state */ + /* check for backdoor key security enable bit */ + if(FLASH_SECURITY_STATE_KEYEN == (registerValue & FTFx_SSD_FSEC_KEYEN)) + { + /* Backdoor key security enabled */ + *securityState = FLASH_SECURE_BACKDOOR_ENABLED; + } + else + { + /* Backdoor key security disabled */ + *securityState = FLASH_SECURE_BACKDOOR_DISABLED; + } + } + + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(FTFx_OK); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ diff --git a/source/LegacyDrivers/source/FlashInit.c b/source/LegacyDrivers/source/FlashInit.c new file mode 100644 index 0000000..1a11615 --- /dev/null +++ b/source/LegacyDrivers/source/FlashInit.c @@ -0,0 +1,178 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashInit.c * +* DATE : Dec 27, 2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.2.2 08.03.2011 FPT Team Fix a bug of missing writing 0 + to FCCOB8 to select IFR for + Read Resource +0.2.3 09.15.2011 FPT Team Add to support K70 +0.2.4 12.27.2011 FPT Team Update to support more Kinetis derivatives. +0.3.3 08.03.2012 FPT Team Optimize code size for L2K/L1PT + Nevis2, and Anguilla Silver +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashInit +* Description : Initialize the Flash memory. +* Arguments : PFLASH_SSD_CONFIG +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4"))) FlashInit (PFLASH_SSD_CONFIG PSSDConfig) +#else +UINT32 FlashInit (PFLASH_SSD_CONFIG PSSDConfig) +#endif +{ +#if (DEBLOCK_SIZE != 0) + UINT8 EEEDataSetSize; /* store EEE Data Set Size */ + UINT8 DEPartitionCode; /* store D/E-Flash Partition Code */ +#endif + UINT32 returnCode; /* return code variable */ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + +#if (DEBLOCK_SIZE != 0) + + while(FALSE == (REG_BIT_TEST(PSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET, FTFx_SSD_FSTAT_CCIF))) + { + /* wait till CCIF bit is set */ + } + + /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */ + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET, \ + (FTFx_SSD_FSTAT_RDCOLERR | FTFx_SSD_FSTAT_ACCERR | FTFx_SSD_FSTAT_FPVIOL)); + + /* Write Command Code to FCCOB0 */ + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET, FTFx_READ_RESOURCE); + /* Write address to FCCOB1/2/3 */ + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB1_OFFSET, ((UINT8)(DFLASH_IFR_READRESOURCE_ADDRESS >> 16))); + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB2_OFFSET, ((UINT8)((DFLASH_IFR_READRESOURCE_ADDRESS >> 8) & 0xFF))); + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB3_OFFSET, ((UINT8)(DFLASH_IFR_READRESOURCE_ADDRESS & 0xFF))); + + /* Write Resource Select Code of 0 to FCCOB8 to select IFR. Without this, */ + /* an access error may occur if the register contains data from a previous command. */ +#if (FTFx_KX_512K_512K_16K_4K_4K == FLASH_DERIVATIVE) + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB4_OFFSET, 0); +#else + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB8_OFFSET, 0); +#endif + /* clear CCIF bit */ + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET, FTFx_SSD_FSTAT_CCIF); + + /* check CCIF bit */ + while((REG_BIT_TEST(PSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET, FTFx_SSD_FSTAT_CCIF)) == FALSE) + { + /* wait till CCIF bit is set */ + } + + /* Read returned value of FCCOB6/7 or FCCOBA,B to the variables */ +#if (FTFx_KX_512K_512K_16K_4K_4K == FLASH_DERIVATIVE) + EEEDataSetSize = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOBA_OFFSET); + DEPartitionCode = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOBB_OFFSET); +#else + EEEDataSetSize = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB6_OFFSET); + DEPartitionCode = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB7_OFFSET); +#endif + /* Calculate D-Flash size and EEE size */ + switch (DEPartitionCode & 0x0F) + { + case 0: PSSDConfig->DFlashBlockSize = DEPART_0000; break; + case 1: PSSDConfig->DFlashBlockSize = DEPART_0001; break; + case 2: PSSDConfig->DFlashBlockSize = DEPART_0010; break; + case 3: PSSDConfig->DFlashBlockSize = DEPART_0011; break; + case 4: PSSDConfig->DFlashBlockSize = DEPART_0100; break; + case 5: PSSDConfig->DFlashBlockSize = DEPART_0101; break; + case 6: PSSDConfig->DFlashBlockSize = DEPART_0110; break; + case 7: PSSDConfig->DFlashBlockSize = DEPART_0111; break; + case 8: PSSDConfig->DFlashBlockSize = DEPART_1000; break; + case 9: PSSDConfig->DFlashBlockSize = DEPART_1001; break; + case 10: PSSDConfig->DFlashBlockSize = DEPART_1010; break; + case 11: PSSDConfig->DFlashBlockSize = DEPART_1011; break; + case 12: PSSDConfig->DFlashBlockSize = DEPART_1100; break; + case 13: PSSDConfig->DFlashBlockSize = DEPART_1101; break; + case 14: PSSDConfig->DFlashBlockSize = DEPART_1110; break; + case 15: PSSDConfig->DFlashBlockSize = DEPART_1111; break; + default: break; + } + + switch (EEEDataSetSize & 0x0F) + { + case 0: PSSDConfig->EEEBlockSize = EEESIZE_0000; break; + case 1: PSSDConfig->EEEBlockSize = EEESIZE_0001; break; + case 2: PSSDConfig->EEEBlockSize = EEESIZE_0010; break; + case 3: PSSDConfig->EEEBlockSize = EEESIZE_0011; break; + case 4: PSSDConfig->EEEBlockSize = EEESIZE_0100; break; + case 5: PSSDConfig->EEEBlockSize = EEESIZE_0101; break; + case 6: PSSDConfig->EEEBlockSize = EEESIZE_0110; break; + case 7: PSSDConfig->EEEBlockSize = EEESIZE_0111; break; + case 8: PSSDConfig->EEEBlockSize = EEESIZE_1000; break; + case 9: PSSDConfig->EEEBlockSize = EEESIZE_1001; break; + case 10: PSSDConfig->EEEBlockSize = EEESIZE_1010; break; + case 11: PSSDConfig->EEEBlockSize = EEESIZE_1011; break; + case 12: PSSDConfig->EEEBlockSize = EEESIZE_1100; break; + case 13: PSSDConfig->EEEBlockSize = EEESIZE_1101; break; + case 14: PSSDConfig->EEEBlockSize = EEESIZE_1110; break; + case 15: PSSDConfig->EEEBlockSize = EEESIZE_1111; break; + default: break; + } +#else /* DEBLOCK_SIZE == 0 */ + /* If size of D/E-Flash = 0 */ + PSSDConfig->DFlashBlockSize = 0; + PSSDConfig->EEEBlockSize = 0; +#endif /* of DEBLOCK_SIZE */ + + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ diff --git a/source/LegacyDrivers/source/FlashProgramCheck.c b/source/LegacyDrivers/source/FlashProgramCheck.c new file mode 100644 index 0000000..0799754 --- /dev/null +++ b/source/LegacyDrivers/source/FlashProgramCheck.c @@ -0,0 +1,244 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashProgramCheck.c * +* DATE : Dec 27,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Updated to support little endian, + changed returnCode of checking + size alignment from + FTFx_ERR_ADDR to FTFx_ERR_SIZE +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.2.2 09.15.2011 FPT Team Update to support K70: do not get + failedData from FCCOB register +0.2.3 11.15.2011 FPT Team Updated to support FTFx_KX_1024K_0K_16K_4K_0K + derivative. +0.2.4 12.27.2011 FPT Team Update to support more Kinetis derivatives. +0.3.1 05.16.2012 FPT Team Update to support Nevis2 devices +0.3.2 07.17.2012 FPT Team Update to support L2K and L1PT derivatives +0.3.3 08.03.2012 FPT Team Optimized for L2K/L1PT + Update to support Anguilla Silver derivatives +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashProgramCheck.c +* Description : The Program Check command tests a previously +* programmed P-Flash or D-Flash longword to see +* if it reads correctly at the specifed margin level. +* Arguments : PFLASH_SSD_CONFIG, UINT32,UINT32, UINT8*, UINT32*, +* UINT8*, UINT8, pFLASHCOMMANDSEQUENCE +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4"))) FlashProgramCheck(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#else +UINT32 FlashProgramCheck(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT8* pExpectedData, \ + UINT32* pFailAddr, \ + UINT8* pFailData, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#endif +{ + UINT8 pCommandArray[12]; /* command sequence array */ + UINT32 returnCode; /* return code variable */ +#if DSC_56800EX == CPU_CORE + UINT8 PFlashFlag; +#endif + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* check if the destination is Longword aligned or not */ + if ((destination & (PGMCHK_ALIGN_SIZE - 1))) + { + /* return an error code FTFx_ERR_ADDR */ + returnCode = FTFx_ERR_ADDR; + goto EXIT; + } + + /* check if the size is Longword aligned or not */ +#if DSC_56800EX == CPU_CORE + if (size & (2*PGMCHK_ALIGN_SIZE - 1)) +#else + if (size & (PGMCHK_ALIGN_SIZE - 1)) +#endif + { + /* return an error code FTFx_ERR_ADDR */ + returnCode = FTFx_ERR_SIZE; + goto EXIT; + } + + /* check for valid range of the target addresses */ + if((destination < PSSDConfig->PFlashBlockBase) || \ + ((destination+BYTE2WORD(size)) > (PSSDConfig->PFlashBlockBase + BYTE2WORD(PSSDConfig->PFlashBlockSize)))) + { +#if(DEBLOCK_SIZE) + if((destination < PSSDConfig->DFlashBlockBase) || \ + ((destination+BYTE2WORD(size)) > (PSSDConfig->DFlashBlockBase + BYTE2WORD(PSSDConfig->DFlashBlockSize)))) + { +#endif /* End of #if(DEBLOCK_SIZE) */ + /* return an error code FTFx_ERR_RANGE */ + returnCode = FTFx_ERR_RANGE; + goto EXIT; +#if (DEBLOCK_SIZE) + } + else + { + /* Convert System memory address to FTFx internal memory address */ + #if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->DFlashBlockBase)+ 0x800000); + PFlashFlag = 0; + #else + destination = destination - PSSDConfig->DFlashBlockBase + 0x800000; + #endif + } +#endif /* End of #if(DEBLOCK_SIZE) */ + } + else + { + /* Convert System memory address to FTFx internal memory address */ +#if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->PFlashBlockBase)); + PFlashFlag = 1; +#else + destination -= PSSDConfig->PFlashBlockBase; +#endif + } + while (size) + { + /* check for error return code */ + if(FTFx_OK == returnCode) + { + /* preparing passing parameter to program check the flash block */ + pCommandArray[0] = FTFx_PROGRAM_CHECK; + pCommandArray[1] = (UINT8)(destination >> 16); + pCommandArray[2] = (UINT8)((destination >> 8) & 0xFF); + pCommandArray[3] = (UINT8)(destination & 0xFF); + pCommandArray[4] = marginLevel; +#if (ENDIANNESS == BIG_ENDIAN) /* Big Endian */ + pCommandArray[8] = *pExpectedData; + pCommandArray[9] = *(pExpectedData+1); + pCommandArray[10] = *(pExpectedData+2); + pCommandArray[11] = *(pExpectedData+3); +#else /* Little Endian */ + pCommandArray[8] = *(pExpectedData+3); + pCommandArray[9] = *(pExpectedData+2); + pCommandArray[10] = *(pExpectedData+1); + pCommandArray[11] = *pExpectedData; +#endif + /* calling flash command sequence function to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 11, pCommandArray); + + /* checking for the success of command execution */ + if(FTFx_OK != returnCode) + { +#if DSC_56800EX == CPU_CORE + /* Convert to global address in Nevis2 */ + if(PFlashFlag) + { + *pFailAddr = (destination >>1) + PSSDConfig->PFlashBlockBase; + } +#if (DEBLOCK_SIZE) + else + { + *pFailAddr = (destination>>1) + PSSDConfig->DFlashBlockBase - 0x400000; + } +#endif +#else + *pFailAddr = destination; +#endif + /* Read fail returned data: if K70, Nevis2, L1PT, L2K are selected */ +#if ((FTFx_KX_512K_512K_16K_4K_4K == FLASH_DERIVATIVE) || (FTFx_KX_1024K_0K_16K_4K_0K == FLASH_DERIVATIVE)\ + ||(FTFx_NX_256K_32K_2K_2K_1K == FLASH_DERIVATIVE)||(FTFx_NX_128K_32K_2K_2K_1K == FLASH_DERIVATIVE)\ + ||(FTFx_NX_96K_32K_2K_2K_1K == FLASH_DERIVATIVE)||(FTFx_NX_64K_32K_2K_2K_1K == FLASH_DERIVATIVE)\ + ||(FTFx_LX_128K_0K_0K_1K_0K == FLASH_DERIVATIVE)||(FTFx_LX_96K_0K_0K_1K_0K == FLASH_DERIVATIVE)\ + ||(FTFx_LX_64K_0K_0K_1K_0K == FLASH_DERIVATIVE)||(FTFx_LX_32K_0K_0K_1K_0K == FLASH_DERIVATIVE)\ + ||(FTFx_LX_8K_0K_0K_1K_0K == FLASH_DERIVATIVE)) + *pFailData = 0x0; + *(pFailData+1) = 0x0; + *(pFailData+2) = 0x0; + *(pFailData+3) = 0x0; +#else /*other derivative */ +#if (ENDIANNESS == BIG_ENDIAN) /* Big Endian */ + *pFailData = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB4_OFFSET); + *(pFailData+1) = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET); + *(pFailData+2) = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB6_OFFSET); + *(pFailData+3) = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB7_OFFSET); +#else /* Little Endian */ + *(pFailData+3) = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB4_OFFSET); + *(pFailData+2) = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET); + *(pFailData+1) = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB6_OFFSET); + *pFailData = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB7_OFFSET); +#endif /*of ENDIANNESS */ +#endif /* of FLASH_DERIVATIVE */ + goto EXIT; + } + } + size-=FTFx_LONGWORD_SIZE; + pExpectedData+=FTFx_LONGWORD_SIZE; + destination+= FTFx_LONGWORD_SIZE; + } + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ + + diff --git a/source/LegacyDrivers/source/FlashProgramLongword.c b/source/LegacyDrivers/source/FlashProgramLongword.c new file mode 100644 index 0000000..a08dd74 --- /dev/null +++ b/source/LegacyDrivers/source/FlashProgramLongword.c @@ -0,0 +1,191 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashProgramLongword.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Updated to support little endian +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.3.1 05.16.2012 FPT Team Update to support Nevis2 devices +0.3.3 08.03.2012 FPT Team Optimized for L2K/L1PT + Update to support Anguilla Silver derivatives +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashProgramLongword.c +* Description : Program data into Flash +* Arguments : PFLASH_SSD_CONFIG, UINT32, UINT32, UINT32, +* pFLASHCOMMANDSEQUENCE +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4"))) FlashProgramLongword(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#else +UINT32 FlashProgramLongword(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#endif +{ + UINT8 pCommandArray[8]; /* command sequence array */ + UINT32 returnCode; /* return code variable */ + UINT32 endAddress; /* storing end address */ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* calculating Flash end address */ + endAddress = destination + BYTE2WORD(size); + + /* check if the destination is Longword aligned or not */ + if (destination & (BYTE2WORD(FTFx_LONGWORD_SIZE)-1)) + { + /* return an error code FTFx_ERR_ADDR */ + returnCode = FTFx_ERR_ADDR; + goto EXIT; + } + + /* check if the size is Longword alignment or not */ + if(size & (FTFx_LONGWORD_SIZE-1)) + { + /* return an error code FTFx_ERR_SIZE */ + returnCode = FTFx_ERR_SIZE; + goto EXIT; + } + + /* check for valid range of the target addresses */ + if((destination < PSSDConfig->PFlashBlockBase) || \ + (endAddress > (PSSDConfig->PFlashBlockBase + BYTE2WORD(PSSDConfig->PFlashBlockSize)))) + { +#if(DEBLOCK_SIZE) + if((destination < PSSDConfig->DFlashBlockBase) || \ + (endAddress > (PSSDConfig->DFlashBlockBase + BYTE2WORD(PSSDConfig->DFlashBlockSize)))) + { +#endif /* End of #if(DEBLOCK_SIZE) */ + /* return an error code FTFx_ERR_RANGE */ + returnCode = FTFx_ERR_RANGE; + goto EXIT; +#if(DEBLOCK_SIZE) + } + else + { + /* Convert System memory address to FTFx internal memory address */ + #if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->DFlashBlockBase)+ 0x800000); + #else + destination = destination - PSSDConfig->DFlashBlockBase + 0x800000; + #endif + } +#endif /* End of #if(DEBLOCK_SIZE) */ + } + else + { + /* Convert System memory address to FTFx internal memory address */ +#if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->PFlashBlockBase)); +#else + destination -= PSSDConfig->PFlashBlockBase; +#endif + } + + /* check for error return code */ + if(FTFx_OK == returnCode) + { + while(size > 0) + { + /* preparing passing parameter to program the flash block */ + pCommandArray[0] = FTFx_PROGRAM_LONGWORD; + pCommandArray[1] = (UINT8)(destination >> 16); + pCommandArray[2] = (UINT8)((destination >> 8) & 0xFF); + pCommandArray[3] = (UINT8)(destination & 0xFF); + +#if (ENDIANNESS == BIG_ENDIAN) /* Big Endian */ + pCommandArray[4] = READ8(source); + pCommandArray[5] = READ8(source + 1); + pCommandArray[6] = READ8(source + 2); + pCommandArray[7] = READ8(source + 3); +#else /* Little Endian */ + pCommandArray[4] = READ8(source + 3); + pCommandArray[5] = READ8(source + 2); + pCommandArray[6] = READ8(source + 1); + pCommandArray[7] = READ8(source); +#endif + + /* calling flash command sequence function to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 7, pCommandArray); + + /* checking for the success of command execution */ + if(FTFx_OK != returnCode) + { + break; + } + else + { + /* update destination address for next iteration */ + destination += FTFx_LONGWORD_SIZE; + /* update size for next iteration */ + size -= FTFx_LONGWORD_SIZE; + /* increment the source adress by 1 */ + source += FTFx_LONGWORD_SIZE; + } + } + } + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ + + diff --git a/source/LegacyDrivers/source/FlashProgramOnce.c b/source/LegacyDrivers/source/FlashProgramOnce.c new file mode 100644 index 0000000..b73b889 --- /dev/null +++ b/source/LegacyDrivers/source/FlashProgramOnce.c @@ -0,0 +1,129 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashProgramOnce.c * +* DATE : Dec 27,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Updated to support little endian +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.2.2 02.21.2011 FPT Team Removed endianness condition + preprocessor +0.2.3 09.15.2011 FPT Team Update to support K70 +0.2.4 11.15.2011 FPT Team Update to support FTFx_KX_1024K_0K_16K_4K_0K + derivative. +0.2.5 12.27.2011 FPT Team Update to support more Kinetis derivatives. +0.3.1 06.01.2012 FPT Team Update to program a data record (4 or 8 bytes) + specified by recordIndex + instead of entire 64 byte OTP region +0.3.3 08.03.2012 FPT Team Optimize code size for L2K/L1PT + Nevis2, and Anguilla Silver +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" +/************************************************************************ +* +* Function Name : FlashProgramOnce.c +* Description : Program a data record into a dedicated 64 bytes +* (divided into 16 data records) region in +* the P-Flash IFR which stores critical information +* for the user +* Arguments : PFLASH_SSD_CONFIG, UINT8 , UINT8*, pFLASHCOMMANDSEQUENCE +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4"))) FlashProgramOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#else +UINT32 FlashProgramOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#endif +{ +#if ((FTFx_KX_512K_512K_16K_4K_4K == FLASH_DERIVATIVE) || (FTFx_KX_1024K_0K_16K_4K_0K == FLASH_DERIVATIVE)) + UINT8 pCommandArray[0xC]; /* command sequence array */ +#else + UINT8 pCommandArray[0x8]; /* command sequence array */ +#endif + UINT32 returnCode; /* return code variable */ + UINT8 commandArraySize = 0x07; + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + /* set the counter value for 0 */ + + /* preparing passing parameter for program once command */ + /* 1st element for the FCCOB register */ + pCommandArray[0] = FTFx_PROGRAM_ONCE; + + /* preparing the rest of the parameters to be passed for the FCCOB registers */ + pCommandArray[1] = recordIndex; + pCommandArray[2] = 0x00; + pCommandArray[3] = 0x00; + pCommandArray[4] = pDataArray[0]; + pCommandArray[5] = pDataArray[1]; + pCommandArray[6] = pDataArray[2]; + pCommandArray[7] = pDataArray[3]; +#if ((FTFx_KX_512K_512K_16K_4K_4K == FLASH_DERIVATIVE) || (FTFx_KX_1024K_0K_16K_4K_0K == FLASH_DERIVATIVE)) + pCommandArray[8] = pDataArray[4]; + pCommandArray[9] = pDataArray[5]; + pCommandArray[10] = pDataArray[6]; + pCommandArray[11] = pDataArray[7]; + commandArraySize = 0xB; +#endif + + /* calling flash command sequence API to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, commandArraySize, pCommandArray); + + + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ + + diff --git a/source/LegacyDrivers/source/FlashProgramPhrase.c b/source/LegacyDrivers/source/FlashProgramPhrase.c new file mode 100644 index 0000000..f3e5ebe --- /dev/null +++ b/source/LegacyDrivers/source/FlashProgramPhrase.c @@ -0,0 +1,167 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashProgramLongword.c * +* DATE : September 15, 2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 09.15.2011 FPT Team Initial Version + +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashProgramPhrase.c +* Description : Program data into Flash +* Arguments : PFLASH_SSD_CONFIG, UINT32, UINT32, UINT32, +* pFLASHCOMMANDSEQUENCE +* Return Value : UINT32 +* +*************************************************************************/ + +UINT32 FlashProgramPhrase(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT32 size, \ + UINT32 source, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +{ + UINT8 pCommandArray[12]; /* command sequence array */ + UINT32 returnCode; /* return code variable */ + UINT32 endAddress; /* storing end address */ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* calculating Flash end address */ + endAddress = destination + BYTE2WORD(size); + + /* check if the destination is Longword aligned or not */ + + if (0 != (destination % BYTE2WORD(FTFx_PHRASE_SIZE))) + { + /* return an error code FTFx_ERR_ADDR */ + returnCode = FTFx_ERR_ADDR; + goto EXIT; + } + + /* check if the size is Longword alignment or not */ + if(0 != (size % FTFx_PHRASE_SIZE)) + { + /* return an error code FTFx_ERR_SIZE */ + returnCode = FTFx_ERR_SIZE; + goto EXIT; + } + + /* check for valid range of the target addresses */ + if((destination < PSSDConfig->PFlashBlockBase) || \ + (endAddress > (PSSDConfig->PFlashBlockBase + BYTE2WORD(PSSDConfig->PFlashBlockSize)))) + { + if((destination < PSSDConfig->DFlashBlockBase) || \ + (endAddress > (PSSDConfig->DFlashBlockBase + BYTE2WORD(PSSDConfig->DFlashBlockSize)))) + { + /* return an error code FTFx_ERR_RANGE */ + returnCode = FTFx_ERR_RANGE; + goto EXIT; + } + else + { + /* Convert System memory address to FTFx internal memory address */ + #if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->DFlashBlockBase)+ 0x800000); + #else + destination = destination - PSSDConfig->DFlashBlockBase + 0x800000; + #endif + } + } + else + { + /* Convert System memory address to FTFx internal memory address */ +#if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->PFlashBlockBase)); +#else + destination -= PSSDConfig->PFlashBlockBase; +#endif + } + + /* check for error return code */ + if(FTFx_OK == returnCode) + { + while(size > 0) + { + /* preparing passing parameter to program the flash block */ + pCommandArray[0] = FTFx_PROGRAM_PHRASE; + pCommandArray[1] = (UINT8)(destination >> 16); + pCommandArray[2] = (UINT8)((destination >> 8) & 0xFF); + pCommandArray[3] = (UINT8)(destination & 0xFF); + +#if (ENDIANNESS == BIG_ENDIAN) /* Big Endian */ + pCommandArray[4] = READ8(source); + pCommandArray[5] = READ8(source + 1); + pCommandArray[6] = READ8(source + 2); + pCommandArray[7] = READ8(source + 3); + pCommandArray[8] = READ8(source + 4); + pCommandArray[9] = READ8(source + 5); + pCommandArray[10] = READ8(source + 6); + pCommandArray[11] = READ8(source + 7); +#else /* Little Endian */ + pCommandArray[4] = READ8(source + 3); + pCommandArray[5] = READ8(source + 2); + pCommandArray[6] = READ8(source + 1); + pCommandArray[7] = READ8(source); + pCommandArray[8] = READ8(source + 7); + pCommandArray[9] = READ8(source + 6); + pCommandArray[10] = READ8(source + 5); + pCommandArray[11] = READ8(source + 4); +#endif + + /* calling flash command sequence function to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 11, pCommandArray); + + /* checking for the success of command execution */ + if(FTFx_OK != returnCode) + { + break; + } + else + { + /* update destination address for next iteration */ + destination += FTFx_PHRASE_SIZE; + /* update size for next iteration */ + size -= FTFx_PHRASE_SIZE; + /* increment the source adress by 1 */ + source += FTFx_PHRASE_SIZE; + } + } + } + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +/* end of file */ + + diff --git a/source/LegacyDrivers/source/FlashProgramSection.c b/source/LegacyDrivers/source/FlashProgramSection.c new file mode 100644 index 0000000..82a35ed --- /dev/null +++ b/source/LegacyDrivers/source/FlashProgramSection.c @@ -0,0 +1,174 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashProgramSection.c * +* DATE : Dec 27,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Changed type of AlignedChecking + variable from UINT32 to UINT8 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Used SECTION_ALIGN_SIZE instead + of AlignedChecking variable for + checking alignment +0.2.2 12.27.2011 FPT Team Update to support more Kinetis derivatives. +0.3.1 05.16.2012 FPT Team Update to support Nevis2 devices +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashProgramSection.c +* Description : Program data into Flash +* Arguments : PFLASH_SSD_CONFIG, UINT32, UINT16, +* pFLASHCOMMANDSEQUENCE +* Return Value : UINT32 +* +*************************************************************************/ + +UINT32 FlashProgramSection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +{ + UINT8 pCommandArray[6]; /* command sequence array */ + UINT32 returnCode; /* return code variable */ + UINT32 endAddress; /* storing end address */ + UINT32 sectionAlign; /* storing the aligned size condition of destination*/ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* check RAMRDY bit of the flash configuration register */ + while(FALSE == (REG_BIT_TEST(PSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET, FTFx_SSD_FCNFG_RAMRDY))) + { + /* return an error code FTFx_ERR_RAMRDY */ + returnCode = FTFx_ERR_RAMRDY; + goto EXIT; + } + + /* check for valid range of the destination */ + if((destination >= PSSDConfig->PFlashBlockBase) && \ + (destination < (PSSDConfig->PFlashBlockBase + BYTE2WORD(PSSDConfig->PFlashBlockSize)))) + { + /* calculating Flash end address */ + endAddress = destination + Number * PPGMSEC_ALIGN_SIZE; + } + else if((destination >= PSSDConfig->DFlashBlockBase) && \ + (destination < (PSSDConfig->DFlashBlockBase + BYTE2WORD(PSSDConfig->DFlashBlockSize)))) + { + /* calculating Flash end address */ + endAddress = destination + Number * DPGMSEC_ALIGN_SIZE; + } + else /* destination does not fall within Pflash or Dflash range */ + { + /* return an error code FTFx_ERR_RANGE */ + returnCode = FTFx_ERR_RANGE; + goto EXIT; + } + + /* check for valid range of the target addresses */ + if((endAddress >= PSSDConfig->PFlashBlockBase) && \ + (endAddress <= (PSSDConfig->PFlashBlockBase + BYTE2WORD(PSSDConfig->PFlashBlockSize)))) + { + /* Convert System memory address to FTFx internal memory address */ +#if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->PFlashBlockBase)); +#else + destination -= PSSDConfig->PFlashBlockBase; +#endif + sectionAlign = PPGMSEC_ALIGN_SIZE; + } + else if((endAddress >= PSSDConfig->DFlashBlockBase) || \ + (endAddress <= (PSSDConfig->DFlashBlockBase + BYTE2WORD(PSSDConfig->DFlashBlockSize)))) + { + /* Convert System memory address to FTFx internal memory address */ +#if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->DFlashBlockBase)+ 0x800000); +#else + destination = destination - PSSDConfig->DFlashBlockBase + 0x800000; +#endif + sectionAlign = DPGMSEC_ALIGN_SIZE; + } + else /* end address does not fall within Pflash or Dflash range */ + { + /* return an error code FTFx_ERR_RANGE */ + returnCode = FTFx_ERR_RANGE; + goto EXIT; + } + + /* check alignment of the destination*/ +#if DSC_56800EX == CPU_CORE + if (0 != (destination % (2*sectionAlign))) +#else + if (0 != (destination % sectionAlign)) +#endif + { + /* return an error code FTFx_ERR_ADDR */ + returnCode = FTFx_ERR_ADDR; + goto EXIT; + } + + /* check for error return code */ + if(FTFx_OK == returnCode) + { + /* preparing passing parameter to program the flash block */ + pCommandArray[0] = FTFx_PROGRAM_SECTION; + pCommandArray[1] = (UINT8)(destination >> 16); + pCommandArray[2] = (UINT8)((destination >> 8) & 0xFF); + pCommandArray[3] = (UINT8)(destination & 0xFF); + pCommandArray[4] = (UINT8)(Number >> 8); + pCommandArray[5] = (UINT8)(Number & 0xFF); + + /* calling flash command sequence function to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 5, pCommandArray); + + /* checking for the success of command execution */ + if(FTFx_OK != returnCode) + { + goto EXIT; + } + else + { + /* do nothing */ + } + } + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +/* end of file */ + + diff --git a/source/LegacyDrivers/source/FlashReadOnce.c b/source/LegacyDrivers/source/FlashReadOnce.c new file mode 100644 index 0000000..1f02f26 --- /dev/null +++ b/source/LegacyDrivers/source/FlashReadOnce.c @@ -0,0 +1,126 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashReadOnce.c * +* DATE : Dec 27,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Updated to support little endian +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.2.2 02.21.2011 FPT Team Removed endianness condition + preprocessor +0.2.3 09.15.2011 FPT Team Update to support K70 +0.2.4 11.15.2011 FPT Team Update to support FTFx_KX_1024K_0K_16K_4K_0K + derivative. +0.2.5 12.27.2011 FPT Team Update to support more Kinetis derivatives. +0.3.1 06.01.2012 FPT Team Update to read out a data record (4 or 8 bytes) + specified by recordIndex + instead of entire 64 byte OTP region +0.3.3 08.03.2012 FPT Team Optimize code size for L2K/L1PT + Nevis2, and Anguilla Silver +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashReadOnce.c +* Description : This function is used to read access to a reserved +* 64 byte field located in the P-Flash IFR. +* Arguments : PFLASH_SSD_CONFIG, UINT8*, pFLASHCOMMANDSEQUENCE +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4"))) FlashReadOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#else +UINT32 FlashReadOnce(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 recordIndex,\ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#endif +{ + UINT8 pCommandArray[2]; /* command sequence array */ + UINT32 returnCode; /* return code variable */ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* preparing passing parameter for read once command */ + /* 1st element for the FCCOB register */ + pCommandArray[0] = FTFx_READ_ONCE; + + /* 2nd element for the FCCOB register */ + pCommandArray[1] = recordIndex; + + /* calling flash command sequence API to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 1, pCommandArray); + + /* checking for the success of command execution */ + if(FTFx_OK == returnCode) + { + /* Read the data from the FCCOB registers into the pDataArray */ + pDataArray[0] = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB4_OFFSET); + pDataArray[1] = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET); + pDataArray[2] = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB6_OFFSET); + pDataArray[3] = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB7_OFFSET); +#if ((FTFx_KX_512K_512K_16K_4K_4K == FLASH_DERIVATIVE) || (FTFx_KX_1024K_0K_16K_4K_0K == FLASH_DERIVATIVE)) + pDataArray[4] = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB8_OFFSET); + pDataArray[5] = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB9_OFFSET); + pDataArray[6] = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOBA_OFFSET); + pDataArray[7] = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOBB_OFFSET); +#endif + } + else + { + /* do nothing */ + } + + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ diff --git a/source/LegacyDrivers/source/FlashReadResource.c b/source/LegacyDrivers/source/FlashReadResource.c new file mode 100644 index 0000000..d0ac914 --- /dev/null +++ b/source/LegacyDrivers/source/FlashReadResource.c @@ -0,0 +1,178 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashReadResource.c * +* DATE : Dec 27,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.2.2 09.15.2011 FPT Team Update to support K70 + Update the address alignment checking + Update the range checking + Add code to convert from system address to internal address +0.2.3 11.15.2011 FPT Team Update to support FTFx_KX_1024K_0K_16K_4K_0K + derivative. +0.2.4 12.27.2011 FPT Team Update to support more Kinetis derivatives. +0.3.1 05.16.2012 FPT Team Update to support Nevis2 devices +0.3.3 08.03.2012 FPT Team Optimize code size for L2K/L1PT + Nevis2, and Anguilla Silver +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashReadResource.c +* Description : This function is provided for the user to read data +* from P-Flash IFR and D-Flash IFR space. +* Arguments : PFLASH_SSD_CONFIG, UINT32, UINT8*, pFLASHCOMMANDSEQUENCE +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4")))FlashReadResource(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#else +UINT32 FlashReadResource(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8* pDataArray, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#endif +{ + UINT8 pCommandArray[9]; /* command sequence array */ + UINT32 returnCode; /* return code variable */ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* check if the destination is longword aligned or not */ + if (destination & (RDRSRC_ALIGN_SIZE-1)) + { + /* return an error code FTFx_ERR_ADDR */ + returnCode = FTFx_ERR_ADDR; + goto EXIT; + } + + /* check for valid range of the target addresses */ + if((destination < ( PSSDConfig->PFlashBlockBase + BYTE2WORD(PFLASH_IFR_OFFSET) )) || \ + (destination >= ( PSSDConfig->PFlashBlockBase + BYTE2WORD(PFLASH_IFR_SIZE )))) + { +#if(DEBLOCK_SIZE) + if((destination < ( PSSDConfig->DFlashBlockBase + BYTE2WORD(DFLASH_IFR_OFFSET) )) || \ + (destination >= ( PSSDConfig->DFlashBlockBase + BYTE2WORD(DFLASH_IFR_SIZE)))) + { + +#endif /* End of #if(DEBLOCK_SIZE) */ + /* return an error code FTFx_ERR_RANGE */ + returnCode = FTFx_ERR_RANGE; + goto EXIT; +#if(DEBLOCK_SIZE) + } + else + { + /* Convert System memory address to FTFx internal memory address */ +#if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->DFlashBlockBase)+ 0x800000); +#else + destination = destination - PSSDConfig->DFlashBlockBase + 0x800000; +#endif + } +#endif /* End of if(DEBLOCK_SIZE) */ + } + else + { + /* Convert System memory address to FTFx internal memory address */ +#if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->PFlashBlockBase)); +#else + destination -= PSSDConfig->PFlashBlockBase; +#endif + } + + /* preparing passing parameter for read resource command */ + /* 1st element for the FCCOB register */ + pCommandArray[0] = FTFx_READ_RESOURCE; + pCommandArray[1] = (UINT8)(destination >> 16); + pCommandArray[2] = (UINT8)((destination >> 8) & 0xFF); + pCommandArray[3] = (UINT8)(destination & 0xFF); +#if ((FTFx_KX_512K_512K_16K_4K_4K == FLASH_DERIVATIVE) || (FTFx_KX_1024K_0K_16K_4K_0K == FLASH_DERIVATIVE)) + pCommandArray[4] = 0x00; + /* calling flash command sequence API to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 4, pCommandArray); +#else + pCommandArray[8] = 0x00; + /* calling flash command sequence API to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 8, pCommandArray); +#endif + + /* checking for the success of command execution */ + if(FTFx_OK != returnCode) + { + goto EXIT; + } + else + { + /* do nothing */ + } + + /* Read the data from the FCCOB registers into the pDataArray */ + pDataArray[0] = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB4_OFFSET); + pDataArray[1] = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET); + pDataArray[2] = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB6_OFFSET); + pDataArray[3] = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB7_OFFSET); +#if ((FTFx_KX_512K_512K_16K_4K_4K == FLASH_DERIVATIVE) || (FTFx_KX_1024K_0K_16K_4K_0K == FLASH_DERIVATIVE)) + pDataArray[4] = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB8_OFFSET); + pDataArray[5] = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB9_OFFSET); + pDataArray[6] = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOBA_OFFSET); + pDataArray[7] = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOBB_OFFSET); +#endif + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ diff --git a/source/LegacyDrivers/source/FlashSecurityBypass.c b/source/LegacyDrivers/source/FlashSecurityBypass.c new file mode 100644 index 0000000..46a0401 --- /dev/null +++ b/source/LegacyDrivers/source/FlashSecurityBypass.c @@ -0,0 +1,108 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashSecurityBypass.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.3.3 08.03.2012 FPT Team Optimize code size for L2K/L1PT + Nevis2, and Anguilla Silver +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashSecurityBypass.c +* Description : If the MCU is secured state, this function will +* unsecure the MCU by comparing the provided backdoor +* key with ones in the Flash Configuration Field. +* Arguments : PFLASH_SSD_CONFIG, UINT8*, pFLASHCOMMANDSEQUENCE +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4"))) FlashSecurityBypass(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#else +UINT32 FlashSecurityBypass(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8* keyBuffer, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#endif +{ + UINT8 pCommandArray[12]; /* command sequence array */ + UINT8 registerValue; /* registerValue */ + UINT32 returnCode; /* return code variable */ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /*Get flash security register value */ + registerValue = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FSEC_OFFSET); + + if (0x02 != (registerValue & 0x03)) + { + /* preparing passing parameter to erase a flash block */ + pCommandArray[0] = FTFx_SECURITY_BY_PASS; + pCommandArray[4] = keyBuffer[0]; + pCommandArray[5] = keyBuffer[1]; + pCommandArray[6] = keyBuffer[2]; + pCommandArray[7] = keyBuffer[3]; + pCommandArray[8] = keyBuffer[4]; + pCommandArray[9] = keyBuffer[5]; + pCommandArray[10] = keyBuffer[6]; + pCommandArray[11] = keyBuffer[7]; + + /* calling flash command sequence function to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 11, pCommandArray); + } + + /* Giving Control to BDM if enabled */ + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ \ No newline at end of file diff --git a/source/LegacyDrivers/source/FlashSetInterruptEnable.c b/source/LegacyDrivers/source/FlashSetInterruptEnable.c new file mode 100644 index 0000000..a1d7248 --- /dev/null +++ b/source/LegacyDrivers/source/FlashSetInterruptEnable.c @@ -0,0 +1,99 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashSetInterruptEnable.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.3.1 06.06.2012 FPT Team Add waiting for setting bits affected +0.3.3 08.03.2012 FPT Team Optimize code size for L2K/L1PT + Nevis2, and Anguilla Silver +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashSetInterruptEnable +* Description : This function sets the Flash interrupt enable +* bits in the Flash module configuration register. +* Other bits in the FCNFG register won’t be affected. +* Arguments : PFLASH_SSD_CONFIG, UINT8 +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4")))FlashSetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, UINT8 interruptState) +#else +UINT32 FlashSetInterruptEnable(PFLASH_SSD_CONFIG PSSDConfig, UINT8 interruptState) +#endif +{ + /* store data read from flash register */ + UINT8 registerValue; + UINT16 i; + + /* Mask off unused bits in interruptState */ + interruptState &= (FTFx_SSD_FCNFG_CCIE | FTFx_SSD_FCNFG_RDCOLLIE); + + /*Get flash configration register value */ + registerValue = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET); + + /* Set register value with desired interrupt state */ + registerValue &= ~(FTFx_SSD_FCNFG_CCIE | FTFx_SSD_FCNFG_RDCOLLIE); + registerValue |= interruptState; + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FCNFG_OFFSET, registerValue); + /* wait for setting bits affected */ + for (i = 0x1000; i >0; i++){} + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(FTFx_OK); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ + + + + + + diff --git a/source/LegacyDrivers/source/FlashVerifyAllBlock.c b/source/LegacyDrivers/source/FlashVerifyAllBlock.c new file mode 100644 index 0000000..41b147c --- /dev/null +++ b/source/LegacyDrivers/source/FlashVerifyAllBlock.c @@ -0,0 +1,96 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashVerifyAllBlock.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.3.3 08.03.2012 FPT Team Optimize code size for L2K/L1PT + Nevis2, and Anguilla Silver +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashVerifyAllBlock.c +* Description : This function will check to see if the P-Flash +* and D-Flash blocks as well as EERAM, E-Flash records +* and D-Flash IFR have been erased to the specifed read +* margin level, if applicable, and will release security +* if the readout passes. +* Arguments : PFLASH_SSD_CONFIG,UINT8, pFLASHCOMMANDSEQUENCE +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4")))FlashVerifyAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#else +UINT32 FlashVerifyAllBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#endif +{ + UINT8 pCommandArray[2]; /* command sequence array */ + UINT32 returnCode; /* return code variable */ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* preparing passing parameter to verify all block command*/ + pCommandArray[0] = FTFx_VERIFY_ALL_BLOCK; + pCommandArray[1] = marginLevel; + + /* calling flash command sequence function to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 1, pCommandArray); + + /* Giving Control to BDM if enabled */ + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ \ No newline at end of file diff --git a/source/LegacyDrivers/source/FlashVerifyBlock.c b/source/LegacyDrivers/source/FlashVerifyBlock.c new file mode 100644 index 0000000..629a430 --- /dev/null +++ b/source/LegacyDrivers/source/FlashVerifyBlock.c @@ -0,0 +1,124 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashVerifyBlock.c * +* DATE : Dec 27,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.2.2 09.15.2011 FPT Team Update the address alignment checking +0.2.3 12.27.2011 FPT Team Update to support more Kinetis derivatives. +0.3.1 05.16.2012 FPT Team Update to support Nevis2 devices +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashVerifyBlock.c +* Description : This function will check to see if an entire +* P-Flash or D-Flash block has been erased to the +* specifed margin level. +* Arguments : PFLASH_SSD_CONFIG, UINT32,UINT8, pFLASHCOMMANDSEQUENCE +* Return Value : UINT32 +* +*************************************************************************/ + +UINT32 FlashVerifyBlock(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +{ + UINT8 pCommandArray[5]; /* command sequence array */ + UINT32 returnCode; /* return code variable */ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* check if the destination is longword aligned or not */ + if (0 != (destination % RD1BLK_ALIGN_SIZE)) + { + /* return an error code FTFx_ERR_ADDR */ + returnCode = FTFx_ERR_ADDR; + goto EXIT; + } + + /* check for valid range of the target addresses */ + if((destination < PSSDConfig->PFlashBlockBase) || \ + (destination >= (PSSDConfig->PFlashBlockBase + BYTE2WORD(PSSDConfig->PFlashBlockSize)))) + { + if((destination < PSSDConfig->DFlashBlockBase) || \ + (destination >= (PSSDConfig->DFlashBlockBase + BYTE2WORD(PSSDConfig->DFlashBlockSize)))) + { + /* return an error code FTFx_ERR_RANGE */ + returnCode = FTFx_ERR_RANGE; + goto EXIT; + } + else + { + /* Convert System memory address to FTFx internal memory address */ + #if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->DFlashBlockBase)+ 0x800000); + #else + destination = destination - PSSDConfig->DFlashBlockBase + 0x800000; + #endif + } + } + else + { + /* Convert System memory address to FTFx internal memory address */ +#if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->PFlashBlockBase)); +#else + destination -= PSSDConfig->PFlashBlockBase; +#endif + } + + /* preparing passing parameter to verify block command */ + pCommandArray[0] = FTFx_VERIFY_BLOCK; + pCommandArray[1] = (UINT8)(destination >> 16); + pCommandArray[2] = (UINT8)((destination >> 8) & 0xFF); + pCommandArray[3] = (UINT8)(destination & 0xFF); + pCommandArray[4] = marginLevel; + + /* calling flash command sequence function to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 4, pCommandArray); + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +/* end of file */ diff --git a/source/LegacyDrivers/source/FlashVerifySection.c b/source/LegacyDrivers/source/FlashVerifySection.c new file mode 100644 index 0000000..00c3874 --- /dev/null +++ b/source/LegacyDrivers/source/FlashVerifySection.c @@ -0,0 +1,171 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : FlashVerifySection.c * +* DATE : Dec 27,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Changed type of AlignedChecking + variable from UINT32 to UINT8 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Used SECTION_ALIGN_SIZE instead + of AlignedChecking variable for + checking alignment +0.2.2 12.27.2011 FPT Team Update to support more Kinetis derivatives. +0.3.1 05.16.2012 FPT Team Update to support Nevis2 devices +0.3.3 08.03.2012 FPT Team Optimized for L2K/L1PT + Update to support Anguilla Silver derivatives +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : FlashVerifySection.c +* Description : This function will check to see if a section of +* P-Flash or D-Flash memory is erased to the specifed +* read margin level. +* Arguments : PFLASH_SSD_CONFIG,UINT32,UINT16,UINT8, pFLASHCOMMANDSEQUENCE +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4")))FlashVerifySection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#else +UINT32 FlashVerifySection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + UINT16 Number, \ + UINT8 marginLevel, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +#endif +{ + UINT8 pCommandArray[7]; /* command sequence array */ + UINT32 returnCode; /* return code variable */ + UINT32 endAddress; /* storing end address. This is the starting point of the next block */ + UINT32 sectionAlign; + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* check for valid range of the destination */ + if((UINT32)(destination - PSSDConfig->PFlashBlockBase) < BYTE2WORD(PSSDConfig->PFlashBlockSize)) + { + /* calculating Flash end address */ + endAddress = destination + Number * PRD1SEC_ALIGN_SIZE; + } +#if(DEBLOCK_SIZE) + else if((UINT32)(destination - PSSDConfig->DFlashBlockBase) DFlashBlockSize)) + { + /* calculating Flash end address */ + endAddress = destination + Number * DRD1SEC_ALIGN_SIZE; + } +#endif /* End of #if(DEBLOCK_SIZE) */ + else + { + /* return an error code FTFx_ERR_RANGE */ + returnCode = FTFx_ERR_RANGE; + goto EXIT; + } + + /* check for valid range of end address */ + if((UINT32)(destination - PSSDConfig->PFlashBlockBase) < BYTE2WORD(PSSDConfig->PFlashBlockSize)) + { + /* Convert System memory address to FTFx internal memory address */ +#if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->PFlashBlockBase)); +#else + destination -= PSSDConfig->PFlashBlockBase; +#endif + sectionAlign = PRD1SEC_ALIGN_SIZE; + } +#if(DEBLOCK_SIZE) + else if((UINT32)(destination - PSSDConfig->DFlashBlockBase) < BYTE2WORD(PSSDConfig->DFlashBlockSize)) + { + /* Convert System memory address to FTFx internal memory address */ +#if DSC_56800EX == CPU_CORE + destination = (2*(destination - PSSDConfig->DFlashBlockBase)+ 0x800000); +#else + destination = destination - PSSDConfig->DFlashBlockBase + 0x800000; +#endif + sectionAlign = DRD1SEC_ALIGN_SIZE; + } +#endif /* End of #if(DEBLOCK_SIZE */ + else + { + /* return an error code FTFx_ERR_RANGE */ + returnCode = FTFx_ERR_RANGE; + goto EXIT; + } + + /* check if the destination is aligned or not */ +#if DSC_56800EX == CPU_CORE + if (destination &(2*sectionAlign-1)) +#else + if (destination & (sectionAlign-1)) +#endif + { + /* return an error code FTFx_ERR_ADDR */ + returnCode = FTFx_ERR_ADDR; + goto EXIT; + } + + /* preparing passing parameter to verify section command */ + pCommandArray[0] = FTFx_VERIFY_SECTION; + pCommandArray[1] = (UINT8)(destination >> 16); + pCommandArray[2] = (UINT8)((destination >> 8) & 0xFF); + pCommandArray[3] = (UINT8)(destination & 0xFF); + pCommandArray[4] = (UINT8)(Number >> 8); + pCommandArray[5] = (UINT8)(Number & 0xFF); + pCommandArray[6] = marginLevel; + + /* calling flash command sequence function to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 6, pCommandArray); + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ diff --git a/source/LegacyDrivers/source/NormalDemo.h b/source/LegacyDrivers/source/NormalDemo.h new file mode 100644 index 0000000..ebe251f --- /dev/null +++ b/source/LegacyDrivers/source/NormalDemo.h @@ -0,0 +1,87 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : NormalDemo.h * +* DATE : February 10,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b28216@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 09.21.2010 FPT Team Initial Version +0.1.0 02.10.2011 FPT Team Update to support K40 and K60 +*************************************************************************/ + +#ifndef _NORMALDEMO_H_ +#define _NORMALDEMO_H_ + +// #if (FLASH_DERIVATIVE == FTFx_KX_256K_256K_4K_2K_2K) +// #include "MK40N512VMD100.h" +// #else /* FLASH_DERIVATIVE == FTFx_KX_512K_0K_0K_2K_0K */ +// #include "MK60N512VMD100.h" +// #endif + +#define READ_NORMAL_MARGIN 0x00 +#define READ_USER_MARGIN 0x01 +#define READ_FACTORY_MARGIN 0x02 + +#define EE_ENABLE 0x00 +#define RAM_ENABLE 0xFF +#define DEBUGENABLE 0x00 +#define PFLASH_IFR_ADDR 0x00000000 +#define DFLASH_IFR_ADDR 0x00800000 + +#define SECTOR_SIZE 0x00000800 /* 2 KB size */ +#define BUFFER_SIZE_BYTE 0x10 + +/* FTFL module base */ +#define FTFx_REG_BASE 0x40020000 +#define DFLASH_IFR_BASE 0x10000000 /* unused */ +#define PFLASH_BLOCK_BASE 0x00000000 +#define DEFLASH_BLOCK_BASE 0x10000000 /* There is not DFlash */ +#define EERAM_BLOCK_BASE 0x14000000 + +#define PBLOCK_SIZE 0x00080000 /* 512 KB size */ +#define EERAM_BLOCK_SIZE 0x00004000 /* 16 KB size */ + +#define pFlashInit (FlashInit) +#define pDEFlashPartition (DEFlashPartition) +#define pSetEEEEnable (SetEEEEnable) +#define pPFlashSetProtection (PFlashSetProtection) +#define pPFlashGetProtection (PFlashGetProtection) +#define pFlashVerifySection (FlashVerifySection) +#define pFlashVerifyBlock (FlashVerifyBlock) +#define pFlashVerifyAllBlock (FlashVerifyAllBlock) +#define pFlashSetInterruptEnable (FlashSetInterruptEnable) +#define pFlashSecurityBypass (FlashSecurityBypass) +#define pFlashReadResource (FlashReadResource) +#define pFlashReadOnce (FlashReadOnce) +#define pFlashProgramSection (FlashProgramSection) +#define pFlashProgramOnce (FlashProgramOnce) +#define pFlashProgramLongword (FlashProgramLongword) +#define pFlashProgramCheck (FlashProgramCheck) +#define pFlashGetSecurityState (FlashGetSecurityState) +#define pFlashGetInterruptEnable (FlashGetInterruptEnable) +#define pFlashEraseSuspend (FlashEraseSuspend) +#define pFlashEraseBlock (FlashEraseBlock) +#define pFlashEraseAllBlock (FlashEraseAllBlock) +#define pFlashCommandSequence (FlashCommandSequence) +#define pFlashCheckSum (FlashCheckSum) +#define pEERAMSetProtection (EERAMSetProtection) +#define pEERAMGetProtection (EERAMGetProtection) +#define pEEEWrite (EEEWrite) +#define pDFlashSetProtection (DFlashSetProtection) +#define pDFlashGetProtection (DFlashGetProtection) +#define pFlashEraseResume (FlashEraseResume) +#define pFlashEraseSector (FlashEraseSector) + +void ErrorTrap(UINT32 returnCode); + +#endif /* _ISRDEMO_H_ */ diff --git a/source/LegacyDrivers/source/PFlashGetProtection.c b/source/LegacyDrivers/source/PFlashGetProtection.c new file mode 100644 index 0000000..ab8c628 --- /dev/null +++ b/source/LegacyDrivers/source/PFlashGetProtection.c @@ -0,0 +1,89 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : PFlashGetProtection.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.3.3 08.03.2012 FPT Team Optimize code size for L2K/L1PT + Nevis2, and Anguilla Silver +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : PFlashGetProtection.c +* Description : This function retrieves current P-Flash protection status. +* Arguments : PFLASH_SSD_CONFIG, UINT32* +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4"))) PFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, UINT32* protectStatus) +#else +UINT32 PFlashGetProtection(PFLASH_SSD_CONFIG PSSDConfig, UINT32* protectStatus) +#endif +{ + UINT32 registerValue0; + UINT32 registerValue1; + UINT32 registerValue2; + UINT32 registerValue3; + + registerValue0=(UINT32)(REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT0_OFFSET)); + registerValue1=(UINT32)(REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT1_OFFSET)); + registerValue2=(UINT32)(REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT2_OFFSET)); + registerValue3=(UINT32)(REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT3_OFFSET)); + + *protectStatus = ((registerValue0 << 24 ) | \ + (registerValue1 << 16 ) | \ + (registerValue2 << 8 ) | \ + registerValue3); + + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(FTFx_OK); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ \ No newline at end of file diff --git a/source/LegacyDrivers/source/PFlashGetSwapStatus.c b/source/LegacyDrivers/source/PFlashGetSwapStatus.c new file mode 100644 index 0000000..173707b --- /dev/null +++ b/source/LegacyDrivers/source/PFlashGetSwapStatus.c @@ -0,0 +1,124 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : PFlashGetSwapStatus.c * +* DATE : Dec 27, 2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 04.13.2011 FPT Team Initial Version +0.0.2 04.20.2011 FPT Team Fix bug when flash range is out + of Pflash 0 (lower area) +0.1.0 04.28.2011 FPT Team Finalize to this version +0.1.1 09.15.2011 FPT Team Add code to convert sytem address + to FTFx internal memory address + Update the address alignment checking +0.1.2 12.27.2011 FPT Team Update to support more Kinetis derivatives. +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : PFlashGetSwapStatus.c +* Description : Retrieve current swap status from the swap system +* +* +* Arguments : PFLASH_SSD_CONFIG, UINT32, UINT8*, UINT8*, UINT8* +* pFLASHCOMMANDSEQUENCE +* +* Return Value : UINT32 +* +*************************************************************************/ + +UINT32 PFlashGetSwapStatus(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + UINT8* pCurrentSwapMode, \ + UINT8* pCurrentSwapBlockStatus, \ + UINT8* pNextSwapBlockStatus, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +{ + UINT8 pCommandArray[8]; /* Command sequence array */ + UINT32 returnCode; /* Return code */ + + /* Set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* Check if the destination is not Longword aligned */ + if (0 != (flashAddress % SWAP_ALIGN_SIZE)) + { + /* Return error code FTFx_ERR_ADDR */ + returnCode = FTFx_ERR_ADDR; + goto EXIT; + } + + /* Check if the flash address is not in the P-Flash block 0 */ + if (!(flashAddress >= PSSDConfig->PFlashBlockBase) || \ + !(flashAddress < (PSSDConfig->PFlashBlockBase + (PSSDConfig->PFlashBlockSize / 2)))) + { + /* Return error code FTFx_ERR_RANGE */ + returnCode = FTFx_ERR_RANGE; + goto EXIT; + } + /* Convert System memory address to FTFx internal memory address */ + flashAddress -= PSSDConfig->PFlashBlockBase; + /* Check if the flash address is in the P-Flash block 0 but is in Flash Configuration Field */ + if ((flashAddress >= FLASH_CNFG_START_ADDRESS) && (flashAddress <= FLASH_CNFG_END_ADDRESS)) + { + /* Return error code FTFx_ERR_RANGE */ + returnCode = FTFx_ERR_RANGE; + goto EXIT; + } + + /* Prepare passing parameter */ + pCommandArray[0] = FTFx_PFLASH_SWAP; + pCommandArray[1] = (UINT8)(flashAddress >> 16); + pCommandArray[2] = (UINT8)((flashAddress >> 8) & 0xFF); + pCommandArray[3] = (UINT8)(flashAddress & 0xFF); + pCommandArray[4] = FTFx_SWAP_REPORT_STATUS; /* Swap control code */ + pCommandArray[5] = 0xFF; + pCommandArray[6] = 0xFF; + pCommandArray[7] = 0xFF; + + /* Call flash command sequence function to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 7, pCommandArray); + + /* Check for the success of command execution */ + if (FTFx_OK == returnCode) + { + *pCurrentSwapMode = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET); + *pCurrentSwapBlockStatus = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB6_OFFSET); + *pNextSwapBlockStatus = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB7_OFFSET); + + goto EXIT; + } + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* Enter Debug state */ + ); +#endif + } + + return(returnCode); +} + +/* end of file */ + + diff --git a/source/LegacyDrivers/source/PFlashSetProtection.c b/source/LegacyDrivers/source/PFlashSetProtection.c new file mode 100644 index 0000000..03f78f6 --- /dev/null +++ b/source/LegacyDrivers/source/PFlashSetProtection.c @@ -0,0 +1,129 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : PFlashSetProtection.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +0.2.2 09.15.2011 FPT Team Add code for checking CCIF bit +0.3.3 08.03.2012 FPT Team Optimize code size for L2K/L1PT + Nevis2, and Anguilla Silver +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : PFlashSetProtection.c +* Description : This function sets the P-Flash protection to the +* intended protection status +* Arguments : PFLASH_SSD_CONFIG, UINT32 +* Return Value : UINT32 +* +*************************************************************************/ +/* Enable size optimization for Anguilla Silver and Nevis2 derivatives */ +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size on +#pragma optimization_level 4 +#endif +/* Enable size optimization for L2K and L1PT derivatives */ +#if((CPU_CORE == ARM_CM0PLUS)&&(COMPILER == CW)) +UINT32 __attribute__((optimize("O4"))) PFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus) +#else +UINT32 PFlashSetProtection(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 protectStatus) +#endif +{ + UINT32 registerValue; /* store data read from flash register */ + UINT32 returnCode; /* return code variable */ + UINT32 temp; + UINT32 registerValue0; + UINT32 registerValue1; + UINT32 registerValue2; + UINT32 registerValue3; + + /* set the default return as FTFx_OK */ + returnCode = FTFx_OK; + /* check CCIF bit of the flash status register, it's impossible to write to FPROT if command is in progress */ + if(FALSE == (REG_BIT_TEST(PSSDConfig->ftfxRegBase + FTFx_SSD_FSTAT_OFFSET, FTFx_SSD_FSTAT_CCIF))) + { + returnCode = FTFx_ERR_CHANGEPROT; + goto EXIT; + } + /* Read the value of FPPROT registers */ + registerValue0=(UINT32)(REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT0_OFFSET)); + registerValue1=(UINT32)(REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT1_OFFSET)); + registerValue2=(UINT32)(REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT2_OFFSET)); + registerValue3=(UINT32)(REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT3_OFFSET)); + + registerValue = ((registerValue0 << 24 ) | \ + (registerValue1 << 16 ) | \ + (registerValue2 << 8 ) | \ + registerValue3); + + /* Check if normal mode */ + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT0_OFFSET, 0xFF); + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT1_OFFSET, 0xFF); + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT2_OFFSET, 0xFF); + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT3_OFFSET, 0xFF); + + /* Read the value of FPPROT registers */ + registerValue0=(UINT32)(REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT0_OFFSET)); + registerValue1=(UINT32)(REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT1_OFFSET)); + registerValue2=(UINT32)(REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT2_OFFSET)); + registerValue3=(UINT32)(REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT3_OFFSET)); + + if((registerValue0 != 0xFF) || (registerValue1 != 0xFF) || \ + (registerValue2 != 0xFF) || (registerValue3 != 0xFF)) + { + /* if normal mode */ + temp = protectStatus ^ registerValue; + if(temp & protectStatus) + { + returnCode = FTFx_ERR_CHANGEPROT; + goto EXIT; + } + } + /* if unprotected or special mode */ + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT0_OFFSET, (UINT8)(protectStatus >> 24)); + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT1_OFFSET, (UINT8)(protectStatus >> 16)); + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT2_OFFSET, (UINT8)(protectStatus >> 8)); + REG_WRITE(PSSDConfig->ftfxRegBase + FTFx_SSD_FPROT3_OFFSET, (UINT8)protectStatus); + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +#if((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) +#pragma optimize_for_size reset +#endif +/* end of file */ diff --git a/source/LegacyDrivers/source/PFlashSwap.c b/source/LegacyDrivers/source/PFlashSwap.c new file mode 100644 index 0000000..6b96b5e --- /dev/null +++ b/source/LegacyDrivers/source/PFlashSwap.c @@ -0,0 +1,344 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : PFlashSwap.c * +* DATE : April 20, 2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 04.13.2011 FPT Team Initial Version +0.0.2 04.20.2011 FPT Team Fix bug when flash range is out + of Pflash 0 (lower area) +0.1.0 04.27.2011 FPT Team Add code to erase swap indicator +0.1.1 09.15.2011 FPT Team Add code to convert sytem address + to FTFx internal memory address + Update the address alignment checking +0.1.2 11.16.2011 FPT Team Update the checking for transition condition + Use _PFlashEraseSector() instead of FlashEraseSector() + API in driver +0.1.3 02.20.2012 FPT Team Changed function prototype to + require one more parameter - + PFLASH_SWAP_CALLBACK. +0.2.0 04.26.2012 FPT Team Change NULL_CALLBACK to NULL_SWAP_CALLBACK to + fix incompatible function type of null pointer bug in IAR compiler +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : _PFlashSwapCtl +* Description : Execute swap command represented by a control code +* +* +* Arguments : PFLASH_SSD_CONFIG, UINT32, UINT8, +* pFLASHCOMMANDSEQUENCE +* +* Return Value : UINT32 +* +*************************************************************************/ +static UINT32 _PFlashSwapCtl(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 addr, \ + UINT8 swapcmd, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/************************************************************************ +* +* Function Name : _PFlashEraseSector +* Description : Erase a flash sector at the given address +* +* +* Arguments : PFLASH_SSD_CONFIG, UINT32, pFLASHCOMMANDSEQUENCE +* +* Return Value : UINT32 +* +*************************************************************************/ +static UINT32 _PFlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/************************************************************************ +* +* Function Name : _ReportSwapState +* Description : Report the current swap state via callback +* +* +* Arguments : PFLASH_SSD_CONFIG, UINT32, UINT8*, PFLASH_SWAP_CALLBACK, +* BOOL*, pFLASHCOMMANDSEQUENCE +* +* Return Value : UINT32 +* +*************************************************************************/ +static UINT32 _ReportSwapState(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + UINT8* currentSwapMode, \ + PFLASH_SWAP_CALLBACK pSwapCallback, \ + BOOL* swapContinue, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence); + +/************************************************************************ +* +* Function Name : PFlashSwap.c +* Description : Perform a swap between P-Flash block 0 and +* P-Flash block 1 +* +* +* Arguments : PFLASH_SSD_CONFIG, UINT32, pFLASHCOMMANDSEQUENCE, +* PSWAP_CALLBACK +* +* Return Value : UINT32 +* +*************************************************************************/ +UINT32 PFlashSwap(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + PFLASH_SWAP_CALLBACK pSwapCallback, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +{ + UINT32 returnCode; /* Return code */ + UINT8 currentSwapMode = 0xFF; + BOOL swapContinue = TRUE; + + /* Set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* Check if the destination is not Longword aligned */ + if (0 != (flashAddress % SWAP_ALIGN_SIZE)) + { + /* Return error code FTFx_ERR_ADDR */ + returnCode = FTFx_ERR_ADDR; + goto EXIT; + } + + /* Check if the flash address is not in the P-Flash block 0 */ + if (!(flashAddress >= PSSDConfig->PFlashBlockBase) || \ + !(flashAddress < (PSSDConfig->PFlashBlockBase + (PSSDConfig->PFlashBlockSize / 2)))) + { + /* Return error code FTFx_ERR_RANGE */ + returnCode = FTFx_ERR_RANGE; + goto EXIT; + } + /* Convert System memory address to FTFx internal memory address */ + flashAddress -= PSSDConfig->PFlashBlockBase; + /* Check if the flash address is in the P-Flash block 0 but is in Flash Configuration Field */ + if ((flashAddress >= FLASH_CNFG_START_ADDRESS) && (flashAddress <= FLASH_CNFG_END_ADDRESS)) + { + /* Return error code FTFx_ERR_RANGE */ + returnCode = FTFx_ERR_RANGE; + goto EXIT; + } + + /* Report current swap state */ + returnCode = _ReportSwapState(PSSDConfig, flashAddress, \ + ¤tSwapMode, pSwapCallback, &swapContinue, FlashCommandSequence); + + if (FTFx_OK != returnCode || !swapContinue) + { + goto EXIT; + } + + /* If current swap mode is Uninitialized */ + if (FTFx_SWAP_UNINIT == currentSwapMode) + { + /* Initialize Swap to Initialized/READY state */ + returnCode = _PFlashSwapCtl(PSSDConfig, flashAddress, FTFx_SWAP_SET_INDICATOR_ADDR, FlashCommandSequence); + + /* Check for the success of command execution */ + if (FTFx_OK != returnCode) + { + goto EXIT; + } + + /* Wait for state transition from Uninitialized to expected state */ + while (((currentSwapMode = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET)) != FTFx_SWAP_READY) && + ((currentSwapMode = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET)) != FTFx_SWAP_UPDATE) && + ((currentSwapMode = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET)) != FTFx_SWAP_UPDATE_ERASED)); + + /* Report current swap state */ + returnCode = _ReportSwapState(PSSDConfig, flashAddress, \ + ¤tSwapMode, pSwapCallback, &swapContinue, FlashCommandSequence); + + if (FTFx_OK != returnCode || !swapContinue) + { + goto EXIT; + } + } + + /* If current swap mode is Initialized/Ready */ + if (FTFx_SWAP_READY == currentSwapMode) + { + /* Progress Swap to UPDATE state */ + returnCode = _PFlashSwapCtl(PSSDConfig, flashAddress, FTFx_SWAP_SET_IN_PREPARE, FlashCommandSequence); + + /* Check for the success of command execution */ + if (FTFx_OK != returnCode) + { + goto EXIT; + } + + /* Wait for state transition from Initialized/Ready to others */ + while (((currentSwapMode = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET)) != FTFx_SWAP_UPDATE) && + ((currentSwapMode = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET)) != FTFx_SWAP_UPDATE_ERASED)); + + /* Report current swap state */ + returnCode = _ReportSwapState(PSSDConfig, flashAddress, \ + ¤tSwapMode, pSwapCallback, &swapContinue, FlashCommandSequence); + + if (FTFx_OK != returnCode || !swapContinue) + { + goto EXIT; + } + } + + /* If current swap mode is Update or Update-Erased */ + if ((FTFx_SWAP_UPDATE == currentSwapMode) || (FTFx_SWAP_UPDATE_ERASED == currentSwapMode)) + { + if (FTFx_SWAP_UPDATE_ERASED != currentSwapMode) + { + /* If the current swap mode is not update-erase, erase swap indicator in non-active block + by erasing the sector contains the swap indicator */ + returnCode = _PFlashEraseSector(PSSDConfig, \ + flashAddress + (PSSDConfig->PFlashBlockSize) / 2, \ + FlashCommandSequence); + if (FTFx_OK != returnCode) + { + goto EXIT; + } + + /* Now the swap state must be Update-Erased, so report current swap state */ + returnCode = _ReportSwapState(PSSDConfig, flashAddress, \ + ¤tSwapMode, pSwapCallback, &swapContinue, FlashCommandSequence); + + if (FTFx_OK != returnCode || !swapContinue) + { + goto EXIT; + } + } + /* Progress Swap to COMPLETE State */ + returnCode = _PFlashSwapCtl(PSSDConfig, flashAddress, FTFx_SWAP_SET_IN_COMPLETE, FlashCommandSequence); + + /* Check for the success of command execution */ + if (FTFx_OK != returnCode) + { + goto EXIT; + } + + /* Wait for state transition from Update-Erased to Complete */ + while ((currentSwapMode = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET)) != FTFx_SWAP_COMPLETE); + + /* Report current swap state */ + returnCode = _ReportSwapState(PSSDConfig, flashAddress, \ + ¤tSwapMode, pSwapCallback, &swapContinue, FlashCommandSequence); + + if (FTFx_OK != returnCode || !swapContinue) + { + goto EXIT; + } + } + +EXIT: + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* Enter Debug state */ + ); +#endif + } + + return(returnCode); +} + +/* Function to execute the swap control code */ +static UINT32 _PFlashSwapCtl(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 addr, \ + UINT8 swapcmd, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +{ + UINT8 pCommandArray[8]; /* Command sequence array */ + UINT32 returnCode; /* Return code variable */ + + /* Set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* Preparing passing parameter to execute the swap control code */ + pCommandArray[0] = FTFx_PFLASH_SWAP; + pCommandArray[1] = (UINT8)((addr & 0x00FF0000) >> 16); + pCommandArray[2] = (UINT8)((addr & 0x0000FF00) >> 8); + pCommandArray[3] = (UINT8)(addr & 0x000000FF); + pCommandArray[4] = swapcmd; + pCommandArray[5] = 0xFF; + pCommandArray[6] = 0xFF; + pCommandArray[7] = 0xFF; + + /* Call FlashCommandSequence to execute the command code */ + returnCode = FlashCommandSequence(PSSDConfig, 7, pCommandArray); + + return (returnCode); +} + +/* Function to execute Pflash erase sector */ +static UINT32 _PFlashEraseSector(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 destination, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +{ + UINT8 pCommandArray[4]; /* Command sequence array */ + UINT32 returnCode; /* Return code variable */ + + /* Set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* preparing passing parameter to erase a flash block */ + pCommandArray[0] = FTFx_ERASE_SECTOR; + pCommandArray[1] = (UINT8)(destination >> 16); + pCommandArray[2] = (UINT8)((destination >> 8) & 0xFF); + pCommandArray[3] = (UINT8)(destination & 0xFF); + + /* calling flash command sequence function to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 3, pCommandArray); + + return (returnCode); +} + +/* Report swap state via callback */ +static UINT32 _ReportSwapState(PFLASH_SSD_CONFIG PSSDConfig, \ + UINT32 flashAddress, \ + UINT8* currentSwapMode, \ + PFLASH_SWAP_CALLBACK pSwapCallback, \ + BOOL* swapContinue, \ + pFLASHCOMMANDSEQUENCE FlashCommandSequence) +{ + UINT32 returnCode = FTFx_OK; + + /* Get current swap state using REPORT command */ + returnCode = _PFlashSwapCtl(PSSDConfig, flashAddress, FTFx_SWAP_REPORT_STATUS, FlashCommandSequence); + if (FTFx_OK != returnCode) + { + return returnCode; + } + + /* Get current swap mode from FCCOB5 register */ + *currentSwapMode = REG_READ(PSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB5_OFFSET); + + /* Report the current swap state to user via callback */ + if (NULL_SWAP_CALLBACK != pSwapCallback) + { + *swapContinue = pSwapCallback(*currentSwapMode); + } + + return returnCode; +} + +/* end of file */ diff --git a/source/LegacyDrivers/source/SetEEEEnable.c b/source/LegacyDrivers/source/SetEEEEnable.c new file mode 100644 index 0000000..d3aaeda --- /dev/null +++ b/source/LegacyDrivers/source/SetEEEEnable.c @@ -0,0 +1,76 @@ +/************************************************************************ +* (c) Copyright Freescale Semiconductor, Inc 2011, All Rights Reserved * +************************************************************************* + +************************************************************************* +* * +* Standard Software Flash Driver For FTFx * +* * +* FILE NAME : SetEEEEnable.c * +* DATE : January 28,2011 * +* * +* AUTHOR : FPT Team * +* E-mail : b39392@freescale.com * +* * +*************************************************************************/ + +/************************** CHANGES ************************************* +0.0.1 06.09.2010 FPT Team Initial Version +0.1.0 06.11.2010 FPT Team Finalize to 0.1.0 +0.1.3 09.16.2010 FPT Team Finalize to 0.1.3 +0.2.0 09.27.2010 FPT Team Finalize to 0.2.0 +0.2.1 01.28.2011 FPT Team Updated the preprocesor + condition to enter Debug state +*************************************************************************/ +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" + +/************************************************************************ +* +* Function Name : SetEEEEnable.c +* Description : This function is used to change the function of +* the EERAM. When not partitioned for EEE, the EERAM +* is typically used as traditional RAM. When partitioned +* for EEE, the EERAM is typically used to store EEE data. +* Arguments : PFLASH_SSD_CONFIG, UINT8 +* Return Value : UINT32 +* +*************************************************************************/ + +UINT32 SetEEEEnable(PFLASH_SSD_CONFIG PSSDConfig, UINT8 EEEEnable) +{ + UINT8 pCommandArray[2]; /* command sequence array */ + UINT32 returnCode; /* return code variable */ + + /* set the default return code as FTFx_OK */ + returnCode = FTFx_OK; + + /* preparing passing parameter to set EEPROM Enabled command */ + pCommandArray[0] = FTFx_SET_EERAM; + pCommandArray[1] = EEEEnable; + + /* calling flash command sequence function to execute the command */ + returnCode = FlashCommandSequence(PSSDConfig, 1, pCommandArray); + + /* Enter Debug state if enabled */ + if (TRUE == (PSSDConfig->DebugEnable)) + { +#if ((CPU_CORE == ARM_CM4) && (COMPILER == IAR)) /* Kx Products */ + asm + ( + " BKPT #0 \n " /* enter Debug state */ + ); +#endif +#if ((CPU_CORE == DSC_56800EX)&&(COMPILER == CW)) + asm + ( + debughlt /* enter Debug state */ + ); +#endif + } + + return(returnCode); +} +/* end of file */ \ No newline at end of file diff --git a/source/LegacyDrivers/source/usb_device_descriptor.c b/source/LegacyDrivers/source/usb_device_descriptor.c new file mode 100644 index 0000000..c314a45 --- /dev/null +++ b/source/LegacyDrivers/source/usb_device_descriptor.c @@ -0,0 +1,488 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device.h" +#include "usb_device_class.h" +#include "usb_device_cdc_acm.h" +#include "usb_device_descriptor.h" + +/******************************************************************************* +* Variables +******************************************************************************/ +/* Define endpoint for communication class */ +usb_device_endpoint_struct_t g_UsbDeviceCdcVcomCicEndpoints[USB_CDC_VCOM_ENDPOINT_CIC_COUNT] = { + { + USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT | (USB_IN << 7U), USB_ENDPOINT_INTERRUPT, + FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE, + }, +}; + +/* Define endpoint for data class */ +usb_device_endpoint_struct_t g_UsbDeviceCdcVcomDicEndpoints[USB_CDC_VCOM_ENDPOINT_DIC_COUNT] = { + { + USB_CDC_VCOM_BULK_IN_ENDPOINT | (USB_IN << 7U), USB_ENDPOINT_BULK, FS_CDC_VCOM_BULK_IN_PACKET_SIZE, + }, + { + USB_CDC_VCOM_BULK_OUT_ENDPOINT | (USB_OUT << 7U), USB_ENDPOINT_BULK, FS_CDC_VCOM_BULK_OUT_PACKET_SIZE, + }}; + +/* Define interface for communication class */ +usb_device_interface_struct_t g_UsbDeviceCdcVcomCommunicationInterface[] = { + {0, + { + USB_CDC_VCOM_ENDPOINT_CIC_COUNT, g_UsbDeviceCdcVcomCicEndpoints, + }, + NULL}}; + +/* Define interface for data class */ +usb_device_interface_struct_t g_UsbDeviceCdcVcomDataInterface[] = { + {0, + { + USB_CDC_VCOM_ENDPOINT_DIC_COUNT, g_UsbDeviceCdcVcomDicEndpoints, + }, + NULL}}; + +/* Define interfaces for virtual com */ +usb_device_interfaces_struct_t g_UsbDeviceCdcVcomInterfaces[USB_CDC_VCOM_INTERFACE_COUNT] = { + {USB_CDC_VCOM_CIC_CLASS, USB_CDC_VCOM_CIC_SUBCLASS, USB_CDC_VCOM_CIC_PROTOCOL, USB_CDC_VCOM_COMM_INTERFACE_INDEX, + g_UsbDeviceCdcVcomCommunicationInterface, + sizeof(g_UsbDeviceCdcVcomCommunicationInterface) / sizeof(usb_device_interfaces_struct_t)}, + {USB_CDC_VCOM_DIC_CLASS, USB_CDC_VCOM_DIC_SUBCLASS, USB_CDC_VCOM_DIC_PROTOCOL, USB_CDC_VCOM_DATA_INTERFACE_INDEX, + g_UsbDeviceCdcVcomDataInterface, sizeof(g_UsbDeviceCdcVcomDataInterface) / sizeof(usb_device_interfaces_struct_t)}, +}; + +/* Define configurations for virtual com */ +usb_device_interface_list_t g_UsbDeviceCdcVcomInterfaceList[USB_DEVICE_CONFIGURATION_COUNT] = { + { + USB_CDC_VCOM_INTERFACE_COUNT, g_UsbDeviceCdcVcomInterfaces, + }, +}; + +/* Define class information for virtual com */ +usb_device_class_struct_t g_UsbDeviceCdcVcomConfig = { + g_UsbDeviceCdcVcomInterfaceList, kUSB_DeviceClassTypeCdc, USB_DEVICE_CONFIGURATION_COUNT, +}; + +/* Define device descriptor */ +uint8_t g_UsbDeviceDescriptor[USB_DESCRIPTOR_LENGTH_DEVICE] = { + /* Size of this descriptor in bytes */ + USB_DESCRIPTOR_LENGTH_DEVICE, + /* DEVICE Descriptor Type */ + USB_DESCRIPTOR_TYPE_DEVICE, + /* USB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). */ + USB_SHORT_GET_LOW(USB_DEVICE_SPECIFIC_BCD_VERSION), USB_SHORT_GET_HIGH(USB_DEVICE_SPECIFIC_BCD_VERSION), + /* Class code (assigned by the USB-IF). */ + USB_DEVICE_CLASS, + /* Subclass code (assigned by the USB-IF). */ + USB_DEVICE_SUBCLASS, + /* Protocol code (assigned by the USB-IF). */ + USB_DEVICE_PROTOCOL, + /* Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid) */ + USB_CONTROL_MAX_PACKET_SIZE, + /* Vendor ID (assigned by the USB-IF) */ + 0xC9U, 0x1FU, + /* Product ID (assigned by the manufacturer) */ + 0x94, 0x00, + /* Device release number in binary-coded decimal */ + USB_SHORT_GET_LOW(USB_DEVICE_DEMO_BCD_VERSION), USB_SHORT_GET_HIGH(USB_DEVICE_DEMO_BCD_VERSION), + /* Index of string descriptor describing manufacturer */ + 0x01, + /* Index of string descriptor describing product */ + 0x02, + /* Index of string descriptor describing the device's serial number */ + 0x00, + /* Number of possible configurations */ + USB_DEVICE_CONFIGURATION_COUNT, +}; + +/* Define configuration descriptor */ +uint8_t g_UsbDeviceConfigurationDescriptor[USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL] = { + /* Size of this descriptor in bytes */ + USB_DESCRIPTOR_LENGTH_CONFIGURE, + /* CONFIGURATION Descriptor Type */ + USB_DESCRIPTOR_TYPE_CONFIGURE, + /* Total length of data returned for this configuration. */ + USB_SHORT_GET_LOW(USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL), + USB_SHORT_GET_HIGH(USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL), + /* Number of interfaces supported by this configuration */ + USB_CDC_VCOM_INTERFACE_COUNT, + /* Value to use as an argument to the SetConfiguration() request to select this configuration */ + USB_CDC_VCOM_CONFIGURE_INDEX, + /* Index of string descriptor describing this configuration */ + 0, + /* Configuration characteristics D7: Reserved (set to one) D6: Self-powered D5: Remote Wakeup D4...0: Reserved + (reset to zero) */ + (USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_MASK) | + (USB_DEVICE_CONFIG_SELF_POWER << USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_SHIFT) | + (USB_DEVICE_CONFIG_REMOTE_WAKEUP << USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_SHIFT), + /* Maximum power consumption of the USB * device from the bus in this specific * configuration when the device is + fully * operational. Expressed in 2 mA units * (i.e., 50 = 100 mA). */ + USB_DEVICE_MAX_POWER, + + /* Communication Interface Descriptor */ + USB_DESCRIPTOR_LENGTH_INTERFACE, USB_DESCRIPTOR_TYPE_INTERFACE, USB_CDC_VCOM_COMM_INTERFACE_INDEX, 0x00, + USB_CDC_VCOM_ENDPOINT_CIC_COUNT, USB_CDC_VCOM_CIC_CLASS, USB_CDC_VCOM_CIC_SUBCLASS, USB_CDC_VCOM_CIC_PROTOCOL, + 0x00, /* Interface Description String Index*/ + + /* CDC Class-Specific descriptor */ + USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC, /* Size of this descriptor in bytes */ + USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */ + USB_CDC_HEADER_FUNC_DESC, 0x10, + 0x01, /* USB Class Definitions for Communications the Communication specification version 1.10 */ + + USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG, /* Size of this descriptor in bytes */ + USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */ + USB_CDC_CALL_MANAGEMENT_FUNC_DESC, + 0x01, /*Bit 0: Whether device handle call management itself 1, Bit 1: Whether device can send/receive call + management information over a Data Class Interface 0 */ + 0x01, /* Indicates multiplexed commands are handled via data interface */ + + USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT, /* Size of this descriptor in bytes */ + USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */ + USB_CDC_ABSTRACT_CONTROL_FUNC_DESC, + 0x06, /* Bit 0: Whether device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and + Get_Comm_Feature 0, Bit 1: Whether device supports the request combination of Set_Line_Coding, + Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State 1, Bit ... */ + + USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC, /* Size of this descriptor in bytes */ + USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE, /* CS_INTERFACE Descriptor Type */ + USB_CDC_UNION_FUNC_DESC, 0x00, /* The interface number of the Communications or Data Class interface */ + 0x01, /* Interface number of subordinate interface in the Union */ + + /*Notification Endpoint descriptor */ + USB_DESCRIPTOR_LENGTH_ENDPOINT, USB_DESCRIPTOR_TYPE_ENDPOINT, USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT | (USB_IN << 7U), + USB_ENDPOINT_INTERRUPT, USB_SHORT_GET_LOW(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE), + USB_SHORT_GET_HIGH(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE), FS_CDC_VCOM_INTERRUPT_IN_INTERVAL, + + /* Data Interface Descriptor */ + USB_DESCRIPTOR_LENGTH_INTERFACE, USB_DESCRIPTOR_TYPE_INTERFACE, USB_CDC_VCOM_DATA_INTERFACE_INDEX, 0x00, + USB_CDC_VCOM_ENDPOINT_DIC_COUNT, USB_CDC_VCOM_DIC_CLASS, USB_CDC_VCOM_DIC_SUBCLASS, USB_CDC_VCOM_DIC_PROTOCOL, + 0x00, /* Interface Description String Index*/ + + /*Bulk IN Endpoint descriptor */ + USB_DESCRIPTOR_LENGTH_ENDPOINT, USB_DESCRIPTOR_TYPE_ENDPOINT, USB_CDC_VCOM_BULK_IN_ENDPOINT | (USB_IN << 7U), + USB_ENDPOINT_BULK, USB_SHORT_GET_LOW(FS_CDC_VCOM_BULK_IN_PACKET_SIZE), + USB_SHORT_GET_HIGH(FS_CDC_VCOM_BULK_IN_PACKET_SIZE), 0x00, /* The polling interval value is every 0 Frames */ + + /*Bulk OUT Endpoint descriptor */ + USB_DESCRIPTOR_LENGTH_ENDPOINT, USB_DESCRIPTOR_TYPE_ENDPOINT, USB_CDC_VCOM_BULK_OUT_ENDPOINT | (USB_OUT << 7U), + USB_ENDPOINT_BULK, USB_SHORT_GET_LOW(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE), + USB_SHORT_GET_HIGH(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE), 0x00, /* The polling interval value is every 0 Frames */ +}; + +/* Define string descriptor */ +uint8_t g_UsbDeviceString0[USB_DESCRIPTOR_LENGTH_STRING0] = {sizeof(g_UsbDeviceString0), USB_DESCRIPTOR_TYPE_STRING, + 0x09, 0x04}; + +uint8_t g_UsbDeviceString1[USB_DESCRIPTOR_LENGTH_STRING1] = { + sizeof(g_UsbDeviceString1), + USB_DESCRIPTOR_TYPE_STRING, + 'M', + 0x00U, + 'D', + 0x00U, + ' ', + 0x00U, + 'A', + 0x00U, + 'U', + 0x00U, + 'T', + 0x00U, + 'O', + 0x00U, + 'M', + 0x00U, + 'O', + 0x00U, + 'T', + 0x00U, + 'I', + 0x00U, + 'V', + 0x00U, + 'E', + 0x00U, + ' ', + 0x00U, + 'C', + 0x00U, + 'O', + 0x00U, + 'N', + 0x00U, + '.', + 0x00U, +}; + +uint8_t g_UsbDeviceString2[USB_DESCRIPTOR_LENGTH_STRING2] = {sizeof(g_UsbDeviceString2), + USB_DESCRIPTOR_TYPE_STRING, + 'E', + 0, + 'C', + 0, + 'U', + 0, + 'H', + 0, + 'O', + 0, + 'S', + 0, + 'T', + 0, + ' ', + 0, + 'M', + 0, + 'K', + 0, + '6', + 0, + '4', + 0, + ' ', + 0, + 'V', + 0, + 'C', + 0, + 'O', + 0, + 'M', + 0, + ' ', + 0, + ' ', + 0, + ' ', + 0}; + +uint8_t *g_UsbDeviceStringDescriptorArray[USB_DEVICE_STRING_COUNT] = {g_UsbDeviceString0, g_UsbDeviceString1, + g_UsbDeviceString2}; + +/* Define string descriptor size */ +uint32_t g_UsbDeviceStringDescriptorLength[USB_DEVICE_STRING_COUNT] = { + sizeof(g_UsbDeviceString0), sizeof(g_UsbDeviceString1), sizeof(g_UsbDeviceString2)}; +usb_language_t g_UsbDeviceLanguage[USB_DEVICE_LANGUAGE_COUNT] = {{ + g_UsbDeviceStringDescriptorArray, g_UsbDeviceStringDescriptorLength, (uint16_t)0x0409, +}}; + +usb_language_list_t g_UsbDeviceLanguageList = { + g_UsbDeviceString0, sizeof(g_UsbDeviceString0), g_UsbDeviceLanguage, USB_DEVICE_LANGUAGE_COUNT, +}; + +/******************************************************************************* +* Code +******************************************************************************/ +/*! + * @brief USB device get device descriptor function. + * + * This function gets the device descriptor of the USB device. + * + * @param handle The USB device handle. + * @param deviceDescriptor The pointer to the device descriptor structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceGetDeviceDescriptor(usb_device_handle handle, + usb_device_get_device_descriptor_struct_t *deviceDescriptor) +{ + deviceDescriptor->buffer = g_UsbDeviceDescriptor; + deviceDescriptor->length = USB_DESCRIPTOR_LENGTH_DEVICE; + return kStatus_USB_Success; +} + +/*! + * @brief USB device get configuration descriptor function. + * + * This function gets the configuration descriptor of the USB device. + * + * @param handle The USB device handle. + * @param configurationDescriptor The pointer to the configuration descriptor structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceGetConfigurationDescriptor( + usb_device_handle handle, usb_device_get_configuration_descriptor_struct_t *configurationDescriptor) +{ + if (USB_CDC_VCOM_CONFIGURE_INDEX > configurationDescriptor->configuration) + { + configurationDescriptor->buffer = g_UsbDeviceConfigurationDescriptor; + configurationDescriptor->length = USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL; + return kStatus_USB_Success; + } + return kStatus_USB_InvalidRequest; +} + +/*! + * @brief USB device get string descriptor function. + * + * This function gets the string descriptor of the USB device. + * + * @param handle The USB device handle. + * @param stringDescriptor Pointer to the string descriptor structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceGetStringDescriptor(usb_device_handle handle, + usb_device_get_string_descriptor_struct_t *stringDescriptor) +{ + if (stringDescriptor->stringIndex == 0U) + { + stringDescriptor->buffer = (uint8_t *)g_UsbDeviceLanguageList.languageString; + stringDescriptor->length = g_UsbDeviceLanguageList.stringLength; + } + else + { + uint8_t languageId = 0U; + uint8_t languageIndex = USB_DEVICE_STRING_COUNT; + + for (; languageId < USB_DEVICE_LANGUAGE_COUNT; languageId++) + { + if (stringDescriptor->languageId == g_UsbDeviceLanguageList.languageList[languageId].languageId) + { + if (stringDescriptor->stringIndex < USB_DEVICE_STRING_COUNT) + { + languageIndex = stringDescriptor->stringIndex; + } + break; + } + } + + if (USB_DEVICE_STRING_COUNT == languageIndex) + { + return kStatus_USB_InvalidRequest; + } + stringDescriptor->buffer = (uint8_t *)g_UsbDeviceLanguageList.languageList[languageId].string[languageIndex]; + stringDescriptor->length = g_UsbDeviceLanguageList.languageList[languageId].length[languageIndex]; + } + return kStatus_USB_Success; +} + +/*! + * @brief USB device set speed function. + * + * This function sets the speed of the USB device. + * + * Due to the difference of HS and FS descriptors, the device descriptors and configurations need to be updated to match + * current speed. + * As the default, the device descriptors and configurations are configured by using FS parameters for both EHCI and + * KHCI. + * When the EHCI is enabled, the application needs to call this fucntion to update device by using current speed. + * The updated information includes endpoint max packet size, endpoint interval, etc. + * + * @param handle The USB device handle. + * @param speed Speed type. USB_SPEED_HIGH/USB_SPEED_FULL/USB_SPEED_LOW. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceSetSpeed(usb_device_handle handle, uint8_t speed) +{ + usb_descriptor_union_t *ptr1; + usb_descriptor_union_t *ptr2; + + ptr1 = (usb_descriptor_union_t *)(&g_UsbDeviceConfigurationDescriptor[0]); + ptr2 = (usb_descriptor_union_t *)(&g_UsbDeviceConfigurationDescriptor[USB_DESCRIPTOR_LENGTH_CONFIGURATION_ALL - 1]); + + while (ptr1 < ptr2) + { + if (ptr1->common.bDescriptorType == USB_DESCRIPTOR_TYPE_ENDPOINT) + { + if (USB_SPEED_HIGH == speed) + { + if (USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT == (ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) + { + ptr1->endpoint.bInterval = HS_CDC_VCOM_INTERRUPT_IN_INTERVAL; + USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE, + ptr1->endpoint.wMaxPacketSize); + } + else if (USB_CDC_VCOM_BULK_IN_ENDPOINT == (ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) + { + USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_BULK_IN_PACKET_SIZE, ptr1->endpoint.wMaxPacketSize); + } + else if (USB_CDC_VCOM_BULK_OUT_ENDPOINT == (ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) + { + USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(HS_CDC_VCOM_BULK_OUT_PACKET_SIZE, ptr1->endpoint.wMaxPacketSize); + } + else + { + } + } + else + { + if (USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT == (ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) + { + ptr1->endpoint.bInterval = FS_CDC_VCOM_INTERRUPT_IN_INTERVAL; + USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE, + ptr1->endpoint.wMaxPacketSize); + } + else if (USB_CDC_VCOM_BULK_IN_ENDPOINT == (ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) + { + USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_BULK_IN_PACKET_SIZE, ptr1->endpoint.wMaxPacketSize); + } + else if (USB_CDC_VCOM_BULK_OUT_ENDPOINT == (ptr1->endpoint.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)) + { + USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(FS_CDC_VCOM_BULK_OUT_PACKET_SIZE, ptr1->endpoint.wMaxPacketSize); + } + else + { + } + } + } + ptr1 = (usb_descriptor_union_t *)((uint8_t *)ptr1 + ptr1->common.bLength); + } + + for (int i = 0; i < USB_CDC_VCOM_ENDPOINT_CIC_COUNT; i++) + { + if (USB_SPEED_HIGH == speed) + { + g_UsbDeviceCdcVcomCicEndpoints[i].maxPacketSize = HS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE; + } + else + { + g_UsbDeviceCdcVcomCicEndpoints[i].maxPacketSize = FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE; + } + } + for (int i = 0; i < USB_CDC_VCOM_ENDPOINT_DIC_COUNT; i++) + { + if (USB_SPEED_HIGH == speed) + { + g_UsbDeviceCdcVcomDicEndpoints[i].maxPacketSize = HS_CDC_VCOM_BULK_OUT_PACKET_SIZE; + } + else + { + g_UsbDeviceCdcVcomDicEndpoints[i].maxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE; + } + } + + return kStatus_USB_Success; +} diff --git a/source/MK64FX512xxx12_Project.c b/source/MK64FX512xxx12_Project.c new file mode 100644 index 0000000..8214eba --- /dev/null +++ b/source/MK64FX512xxx12_Project.c @@ -0,0 +1,63 @@ +/* + * Copyright 2016-2018 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file MK64FX512xxx12_Project.c + * @brief Application entry point. + */ +#include +#include "board.h" +#include "peripherals.h" +#include "pin_mux.h" +#include "clock_config.h" +#include "MK64F12.h" +/* TODO: insert other include files here. */ + +/* TODO: insert other definitions and declarations here. */ +extern int ECUHostMain(void); + + +/* + * @brief Application entry point. + */ +int main(void) { + /* Init board hardware. */ + + BOARD_InitBootPins(); + BOARD_InitBootPeripherals(); + + /* Enter an infinite loop */ + while(1) + { + ECUHostMain(); + } + + return 0 ; +} diff --git a/source/OS/CLIENT.c b/source/OS/CLIENT.c new file mode 100644 index 0000000..d231d77 --- /dev/null +++ b/source/OS/CLIENT.c @@ -0,0 +1,162 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: CLIENT */ +/* DESCRIPTION: This code provides functions for adding client tasks */ +/* and running the client callback queue */ +/* FILE NAME: CLIENT.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include "CPUAbstract.h" +#include "TASKAPI.h" +#include "SYSAPI.h" +#include "IOAPI.h" +#include "ADCAPI.h" +#include "TEPMAPI.h" +#include "USER.h" +#include "MSG.h" +#include "PERADC.h" +#include "TEPM.h" +#include "CQUEUE.h" + + +uint32 u32Temp; +uint32 CLIENT_u32TaskStartCount = 0; +uint32 CLIENT_u32RunTaskCount = 0; +CLIENT_tstCBInfo astCBInfo[CLIENT_nUserCBMax]; +CQUEUE_tstQueue stCBQueue; + +TASK_tstTask CLIENT_rastTaskCyclic[SYS_CLIENT_MODULES_MAX]; + +void CLIENT_vStart(uint32 * const pu32Arg) +{ + CQUEUE_xInit(&stCBQueue, CLIENT_nUserCBMax, astCBInfo); + +#ifdef BUILD_KERNEL + puint32 pu32UserEntry = (puint32)CLIENT_nUserAppImageBase; + uint32 u32UserAppImageEntry= *pu32UserEntry; + + if ((CLIENT_nUserAppImageBase & 0xffff0000) == (0xffff0000 & u32UserAppImageEntry)) + { + pfUserStart = (tpfUserStart)u32UserAppImageEntry; + iRetCode = pfUserStart(&OS_stSVCDataStruct); + } +#endif + +#ifdef BUILD_KERNEL_APP + (void)USER_vStart(&OS_stSVCDataStruct); +#endif + +} + +void CLIENT_vRunUserCBQueue(void) +{ + ADC_tstADCResult* pstADCResult; + TEPM_tstTEPMResult* pstTEPMEvent; + DIAGAPI_tstDataTransferCB* pstDataTransferCB; + ADCAPI_tpfResultCB pfADCResultCB; + TEPMAPI_tpfEventCB pfTEPMEventCB = NULL; + DIAGAPI_tDataWriteCB pfDataWriteCB; + + CPU_vEnterCritical(); + + if (!CQUEUE_xIsEmpty(&stCBQueue)) + { + switch (astCBInfo[stCBQueue.u32Head].pstMBX->enMSGType) + { + case MSG_enADCResult: + { + /* Run the callback if not NULL */ + pstADCResult = (ADC_tstADCResult*)astCBInfo[stCBQueue.u32Head].pstMBX->pstMSG; + pfADCResultCB = (ADCAPI_tpfResultCB)astCBInfo[stCBQueue.u32Head].pfCB; + + if (NULL != pfADCResultCB) + { + pfADCResultCB(pstADCResult->enEHIOResource, pstADCResult->u32Result); + } + + break; + } + case MSG_enTEPMEvent: + { + /* Run the callback if not NULL */ + pstTEPMEvent = (TEPM_tstTEPMResult*)astCBInfo[stCBQueue.u32Head].pstMBX->pstMSG; + pfTEPMEventCB = (TEPMAPI_tpfEventCB)astCBInfo[stCBQueue.u32Head].pfCB; + + if (NULL != pfTEPMEventCB) + { + pfTEPMEventCB(pstTEPMEvent->enEHIOResource, pstTEPMEvent->tEventTime); + } + break; + } + case MSG_enDiagDataWrite: + { + /* Run the callback if not NULL */ + pstDataTransferCB = (DIAGAPI_tstDataTransferCB*)astCBInfo[stCBQueue.u32Head].pstMBX->pstMSG; + pfDataWriteCB = (DIAGAPI_tDataWriteCB)astCBInfo[stCBQueue.u32Head].pfCB; + + if (NULL != pfTEPMEventCB) + { + (void)pfDataWriteCB(pstDataTransferCB->u16CID, pstDataTransferCB->pu8Data, pstDataTransferCB->u8DataCount); + pstDataTransferCB->boTransferComplete = TRUE; + } + break; + } + default: + { + break; + } + } + CQUEUE_xRemoveItemUnsafe(&stCBQueue); + } + + CPU_vExitCritical(); +} + +/* Caveat only call this function with interrupts enabled! Not from a thread critical section! */ +CLIENT_tenErr CLIENT_enEnqueueCB(MSG_tstMBX* pstMBX, tpfClientCB pfCB) +{ + CLIENT_tenErr enErr = CLIENT_enFailQueueFull; + + CPU_xEnterCritical(); + + if (!CQUEUE_xIsFull(&stCBQueue)) + { + astCBInfo[stCBQueue.u32Tail].pfCB = pfCB; + astCBInfo[stCBQueue.u32Tail].pstMBX = pstMBX; + CQUEUE_xAddItemUnsafe(&stCBQueue); + enErr = CLIENT_enOK; + } + + CPU_xExitCritical(); + + return enErr; +} + + +SYSAPI_tenSVCResult CLIENT_vAddTask(OS_tenQueueType enQueueType, SYSAPI_tpfUserTaskFunction pfUserTask, TASKAPI_tenPriority enPriority, TASKAPI_tenRateMs enRateMs) +{ + TASK_tstTask stTask; + SYSAPI_tenSVCResult enSVCResult; + + stTask.tTaskID = 0x2000; + stTask.enTaskType = enTaskFunction; + stTask.enTaskPriority = enPriority; + stTask.enTaskRateMS = enRateMs; + stTask.enTaskState = enTaskReady; + stTask.pfTaskFunction = pfUserTask; + stTask.enPrivilege = enTaskUnprivileged; + + enSVCResult = OS_enAddTaskToQueue(enQueueType, &stTask); + + return enSVCResult; +} diff --git a/source/OS/CLIENT.h b/source/OS/CLIENT.h new file mode 100644 index 0000000..b5e9a89 --- /dev/null +++ b/source/OS/CLIENT.h @@ -0,0 +1,57 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: CLIENT Header File */ +/* DESCRIPTION: This code provides struct and enum definitions for */ +/* client queues and callbacks */ +/* FILE NAME: CLIENT.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef CLIENT_H +#define CLIENT_H + +#include +#include +#include +#include "TASKAPI.h" +#include "SYSAPI.h" +#include "OS.h" +#include "MSG.h" + +#define CLIENT_nUserCBMax 20u +#define CLIENT_nUserAppImageBase 0x00050000u +/*CR1_90*/ + +typedef void (*tpfClientCB)(void*); +typedef int (*tpfUserStart)(SYSAPI_tstSVCDataStruct*); + +typedef enum +{ + TaskQueue_Start, + TaskQueue_Run, + TaskQueue_Terminate, +} CLIENT_tenTaskQueue; + +typedef enum +{ + CLIENT_enOK, + CLIENT_enFailQueueFull, + CLIENT_enErrUNK +} CLIENT_tenErr; + +typedef struct +{ + tpfClientCB pfCB; + MSG_tstMBX* pstMBX; +} CLIENT_tstCBInfo; + \ +void CLIENT_vStart(uint32* const); +CLIENT_tenErr CLIENT_enEnqueueCB(MSG_tstMBX*, tpfClientCB); +SYSAPI_tenSVCResult CLIENT_vAddTask(OS_tenQueueType, SYSAPI_tpfUserTaskFunction, TASKAPI_tenPriority, TASKAPI_tenRateMs); +void CLIENT_vRunUserCBQueue(void); + +#endif // CLIENT_H + diff --git a/source/OS/MSG.c b/source/OS/MSG.c new file mode 100644 index 0000000..7cf356e --- /dev/null +++ b/source/OS/MSG.c @@ -0,0 +1,174 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: MSG */ +/* DESCRIPTION: This code provides functions for OS messaging */ +/* */ +/* FILE NAME: MSG.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define __MSG_C + +#include "mk64f12.h" +#include +#include +#include "MSG.h" + +MSG_tstMBX MSG_astMBX[MSG_nMBXCount]; +static sint32 MSG_u32GetFreeMBX(void); + +void MSG_vStart(uint32* const pu32Stat) +{ + uint32 u32MBXIDX; + + for (u32MBXIDX = 0; u32MBXIDX < MSG_nMBXCount; u32MBXIDX++) + { + MSG_astMBX[u32MBXIDX].enMSGType = MSG_enNone; + MSG_astMBX[u32MBXIDX].pstMSG = NULL; + } +} + +void MSG_vRun(uint32* const pu32Stat) +{ + +} + +void MSG_vTerminate(uint32* const pu32Stat) +{ + +} + +MSG_tenMBXErr MSG_enMBXNew(MSG_tstMBX** ppstMBX, MSG_tenMSGType enMSGType) +{ + MSG_tenMBXErr enMBXErr = MSG_enBadMSGType; + sint32 i32MBXIDX = -1; + + if ((MSG_enNone < enMSGType) && (MSG_enMSGTypeCount > enMSGType)) + { + i32MBXIDX = MSG_u32GetFreeMBX(); + enMBXErr = MSG_enMBXQueueFull; + + if (-1 != i32MBXIDX) + { + MSG_astMBX[i32MBXIDX].enMSGType = enMSGType; + *ppstMBX = &MSG_astMBX[i32MBXIDX]; + enMBXErr = MSG_enOK; + } + } + return enMBXErr; +} + +void MSG_vMBXFree(MSG_tstMBX* const pstMBX) +{ + pstMBX->enMSGType = MSG_enNone; + pstMBX->pstMSG = NULL; +} + +void MSG_vMBXPost(MSG_tstMBX* const pstMBX, void* const pstMSG) +{ + if ((MSG_enNone != pstMBX->enMSGType) && (NULL == pstMBX->pstMSG) && (NULL != pstMBX)) + { + pstMBX->pstMSG = pstMSG; + } +} + +MSG_tenMBXErr MSG_vMBXTryPost(MSG_tstMBX* const pstMBX, void* const pstMSG) +{ + MSG_tenMBXErr enMBXErr = MSG_enBadMBX; + //todo wait + if(MSG_enNone != pstMBX->enMSGType) + { + enMBXErr = MSG_enMBXFull; + + if (NULL == pstMBX->pstMSG) + { + pstMBX->pstMSG = pstMSG; + enMBXErr = MSG_enOK; + } + } + + return enMBXErr; +} + +MSG_tenMBXErr MSG_enMBXTryFetchWait(MSG_tstMBX* const pstMBX, void* pstMSG) +{ + MSG_tenMBXErr enMBXErr = MSG_enBadMBX; + //todo wait + if(MSG_enNone != pstMBX->enMSGType) + { + enMBXErr = MSG_enNoMSG; + + if (NULL != pstMBX->pstMSG) + { + pstMSG = pstMBX->pstMSG; + enMBXErr = MSG_enOK; + } + } + + /* TODO suppress warning */ + (void)pstMSG; + + return enMBXErr; +} + +MSG_tenMBXErr MSG_enMBXTryFetch(MSG_tstMBX* const pstMBX, void* pstMSG) +{ + MSG_tenMBXErr enMBXErr = MSG_enBadMBX; + + if(MSG_enNone != pstMBX->enMSGType) + { + enMBXErr = MSG_enNoMSG; + + if (NULL != pstMBX->pstMSG) + { + pstMSG = pstMBX->pstMSG; + enMBXErr = MSG_enOK; + } + } + return enMBXErr; +} + +bool MSG_boMBXValid(MSG_tstMBX* const pstMBX) +{ + bool boValid = false; + + if (NULL != pstMBX) + { + boValid = MSG_enNone != pstMBX->enMSGType; + } + else + { +#ifdef BUILD_ERR_PRINTF + printf("Invalid mailbox\n"); + + while (1){} +#endif + } + + return boValid; +} + +void MSG_boMBXInvalidate(MSG_tstMBX* const pstMBX) +{ + pstMBX->enMSGType = MSG_enNone; +} + +static sint32 MSG_u32GetFreeMBX(void) +{ + uint32 u32MBXIDX; + sint32 i32RetIDX; + + for (u32MBXIDX = 0; u32MBXIDX < MSG_nMBXCount; u32MBXIDX++) + { + if (MSG_enNone == MSG_astMBX[u32MBXIDX].enMSGType) + { + i32RetIDX = u32MBXIDX; + break; + } + } + return i32RetIDX; +} + diff --git a/source/OS/MSG.h b/source/OS/MSG.h new file mode 100644 index 0000000..50960cf --- /dev/null +++ b/source/OS/MSG.h @@ -0,0 +1,62 @@ +/******************************************************************************/ +/* MSG header file */ +/******************************************************************************/ +/* */ +/* Copyright (c) 2013 MD Automotive Controls. All rights reserved. */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#ifndef MSG_H +#define MSG_H + +#include + +typedef enum +{ + MSG_enNone, + MSG_enADCResult, + MSG_enUSERCB, + MSG_enLWIP, + MSG_enTEPMEvent, + MSG_enDiagDataRead, + MSG_enDiagDataWrite, + MSG_enDiagFunctionReq, + MSG_enMSGTypeCount +} MSG_tenMSGType; + +typedef enum +{ + MSG_enOK, + MSG_enMBXQueueFull, + MSG_enMBXFull, + MSG_enMBXTimeout, + MSG_enNoMSG, + MSG_enBadMBX, + MSG_enBadMSGType +} MSG_tenMBXErr; + +typedef struct +{ + MSG_tenMSGType enMSGType; + void* pstMSG; +} MSG_tstMBX; + +#define MSG_nMBXCount 128u + + +/* Public function definitions */ +void MSG_vStart(uint32* const); +void MSG_vRun(uint32* const); +void MSG_vTerminate(uint32* const); +MSG_tenMBXErr MSG_enMBXNew(MSG_tstMBX**, MSG_tenMSGType); +void MSG_vMBXFree(MSG_tstMBX* const); +void MSG_vMBXPost(MSG_tstMBX* const, void* const); +MSG_tenMBXErr MSG_vMBXTryPost(MSG_tstMBX* const, void* const); +MSG_tenMBXErr MSG_enMBXTryFetchWait(MSG_tstMBX* const, void*); +MSG_tenMBXErr MSG_enMBXTryFetch(MSG_tstMBX* const, void*); +bool MSG_boMBXValid(MSG_tstMBX* const); +void MSG_boMBXInvalidate(MSG_tstMBX* const); + +#endif // MSG_H + diff --git a/source/OS/OS.c b/source/OS/OS.c new file mode 100644 index 0000000..762b402 --- /dev/null +++ b/source/OS/OS.c @@ -0,0 +1,587 @@ + +/******************************************************************************/ +/* OS c file */ +/******************************************************************************/ +/* */ +/* Copyright (c) 2013 MD Automotive Controls. All rights reserved. */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#define _OS_C +#include +#include +#include "mk64f12.h" + +#include "PROTAPI.h" +#include "IOAPI.h" +#include "DLL.h" +#include "peruart.h" +#include "PIM.h" +#include "PERADC.h" +#include "DAC.h" +#include "PIT.h" +#include "FEE.h" +#include "perCAN.h" +#include "DSCRIO.h" +#include "CQUEUE.h" +#include "SRLTFR.h" +#include "SDHC.h" +#include "DISK.h" +#include "TIME.h" +#include "TIMER.h" +#include "TEPM.h" +#include "RESM.h" +#include "CTRL.h" +#include "MSG.h" +#include "UDSAL.h" +#include "CRC16.h" +#include +#include "TASKAPI.h" +#include +#include "IRQ.h" +#include +#include "CPUAbstract.h" +#include "tqueue.h" +#include +#include +#include +#include "OS.h" +#include "tqueueHA.h" + +extern void VCOM_vStart(uint32* const u32Stat); +extern void VCOM_vRun(uint32* const u32Stat); +extern void VCOM_vTerminate(uint32* const u32Stat); + + +/* Declare constant task arrays */ +const TASK_tstTask OS_rastTaskStart[] = OS_nTaskStart; +const TASK_tstTask OS_rastTaskCyclic[] = OS_nTaskCyclic; +const TASK_tstTask OS_rastTaskTerminate[] = OS_nTaskTerminate; +#define OS_nKERNELTaskStartCount sizeof(OS_rastTaskStart) / sizeof(TASK_tstTask) +#define OS_nKERNELTaskCyclicCount sizeof(OS_rastTaskCyclic) / sizeof(TASK_tstTask) +#define OS_nKERNELTaskTerminateCount sizeof(OS_rastTaskTerminate) / sizeof(TASK_tstTask) +#define OS_nTaskCount (OS_nKERNELTaskStartCount + OS_nKERNELTaskCyclicCount + OS_nKERNELTaskTerminateCount + SYS_THREAD_MAX + 1) /* + 1 for system idle thread */ + +task_queue OS_apstTaskQueue[OS_enTaskQueueCount]; +tq_struct* OS_pstBackgroundDispatcherTask; + +typedef struct +{ + uint32 u32StartCount; + uint32 u32CyclicCount; + uint32 u32TerminateCount; + uint32 u32TotalCount; + tq_struct stqTask[OS_nTaskCount]; +} OS_tstKERNELTaskNodePool; + +typedef struct +{ + uint32 u32StartCount; + uint32 u32CyclicCount; + uint32 u32TerminateCount; + uint32 u32TotalCount; + tq_struct stqTask[OS_nClientTasksMax]; +} OS_tstCLIENTTaskNodePool; + +/* local functions */ +void OS_vBackgroundDispatcher(void); +bool OS_boCreateThread(OS_tenQueueType, TASK_tProgramCounter); +bool OS_boCreateDispatcherTask(OS_tenQueueType, TASK_tProgramCounter); +void OS_vSystemDummyThread(uint32* const); +static void OSHA_vLoadProcessStackASM(struct tq_struct*); +static void OS_vRunQueues(void); + +/* module data */ +OS_tstKERNELTaskNodePool OS_stKERNELTaskNodePool; +OS_tstCLIENTTaskNodePool OS_stCLIENTTaskNodePool; + +uint32 OS_u32CLIENTStartTaskCount; +uint32 OS_u32CLIENTCyclicTaskCount; +uint32 OS_u32CLIENTTerminateTaskCount; + +OS_tenOSState OS_enOSState; +OS_tenOSKernelMode enOSKernelMode; +bool OS_bModuleActive[OS_nKERNELTaskStartCount]; +uint32 OS_u32StartTaskStatus; +uint32 OS_u32RunTaskStatus; +uint32 OS_u32TerminateTaskStatus; +uint8 OS_u8SchedulerIDX; +uint32 OS_u32SchedulerRunStatus; +uint32 OS_u32SysTickInterval; +uint32 OS_u32SysRunTimeHigh; +uint32 OS_u32SysRunTimeLow; + + +void OS_vStart(uint32* const u32Stat) +{ + uint32 u32ModuleStartStatus; + uint8 u8IDX; + + OS_enOSState = OS_enOSStatePreOS; + enOSKernelMode = enOSKernelMode; + OS_u32TickCounter = 0; + CPU_vStart(); + THREAD_vStart(NULL); + + memset((void*)&OS_stKERNELTaskNodePool, 0, sizeof(OS_tstKERNELTaskNodePool)); + memset((void*)&OS_stCLIENTTaskNodePool, 0, sizeof(OS_tstCLIENTTaskNodePool)); + memset((void*)OS_apstTaskQueue, 0, sizeof(task_queue) * OS_enTaskQueueCount); + + OS_u32CLIENTStartTaskCount = 0; + OS_u32CLIENTCyclicTaskCount = 0; + OS_u32CLIENTTerminateTaskCount = 0; + + OS_stKERNELTaskNodePool.u32StartCount = OS_nKERNELTaskStartCount; + OS_stKERNELTaskNodePool.u32CyclicCount = OS_nKERNELTaskCyclicCount; + OS_stKERNELTaskNodePool.u32TerminateCount = OS_nKERNELTaskTerminateCount; + OS_stKERNELTaskNodePool.u32TotalCount = 0; + + OS_stCLIENTTaskNodePool.u32StartCount = 0; + OS_stCLIENTTaskNodePool.u32CyclicCount = 0; + OS_stCLIENTTaskNodePool.u32TerminateCount = 0; + OS_stCLIENTTaskNodePool.u32TotalCount = 0; + + OS_stSVCDataStruct.pvData = (void*)&au32SVCResult; + + /* add to static node pool, queue and run the start task list */ + for(u8IDX = 0; u8IDX < OS_nKERNELTaskStartCount; u8IDX++) + { + memcpy((void*)&OS_stKERNELTaskNodePool.stqTask[u8IDX].stTask, + (void*)&OS_rastTaskStart[u8IDX], sizeof(TASK_tstTask)); + + OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount++].stTask.tsTaskQueued = CPUA_OS_u32GetSysTimeStamp(); + queue_task(&OS_stKERNELTaskNodePool.stqTask[u8IDX], &OS_apstTaskQueue[OS_enKERNELQueueStart]); + } + + OS_xPrioritiseQueue(&OS_apstTaskQueue[OS_enKERNELQueueStart]); + + /* Run the KERNEL start task queue */ + run_cooperative_task_queue(&OS_apstTaskQueue[OS_enKERNELQueueStart], NULL, &u32ModuleStartStatus); + + /* Run the CLIENT start task queue */ + run_cooperative_task_queue(&OS_apstTaskQueue[OS_enCLIENTQueueStart], NULL, &u32ModuleStartStatus); + + + + /* add to static node pool the cyclic task list */ + for(u8IDX = OS_nKERNELTaskStartCount; u8IDX < (OS_nKERNELTaskStartCount + OS_nKERNELTaskCyclicCount); u8IDX++) + { + memcpy((void*)&OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount++].stTask, + (void*)&OS_rastTaskCyclic[u8IDX - OS_nKERNELTaskStartCount], sizeof(TASK_tstTask)); + } + + + /* create the kernel idle thread */ + (void)OS_boCreateThread(OS_enKERNELQueueThread, &OS_vSystemIdleThread); + +#ifdef OS_MULTI_THREAD_ + /* create a dummy thread */ + (void)OS_boCreateThread(OS_enKERNELQueueThread, &OS_vSystemDummyThread); +#endif //OS_MULTI_THREAD + + /* create the background dispatcher task */ + (void)OS_boCreateDispatcherTask(OS_enKERNELQueueCyclic, &OS_vBackgroundDispatcher); + + OS_xModuleStartOK(*u32Stat); + OS_enOSState = OS_enOSStartRequest; +} + +void OS_vRun(uint32* const u32Stat) +{ + OSHA_vLoadProcessStackASM(OS_pstBackgroundDispatcherTask); + OS_vBackgroundDispatcher(); +} + +void OS_vSchedule(OS_tenOSScheduleCallContext enOSScheduleCallContext) +{ + + for(OS_u8SchedulerIDX = OS_stKERNELTaskNodePool.u32StartCount; OS_u8SchedulerIDX < (OS_stKERNELTaskNodePool.u32StartCount + OS_stKERNELTaskNodePool.u32CyclicCount); OS_u8SchedulerIDX++) + { + if((OS_u32TickCounter % OS_stKERNELTaskNodePool.stqTask[OS_u8SchedulerIDX].stTask.enTaskRateMS) == 0) + { + /* only call module run task if module was activated successfully at start */ + //if(OS_bModuleActive[u8IDX] == true) + //{ + /* queue then run the KERNEL cyclic task list */ + OS_stKERNELTaskNodePool.stqTask[OS_u8SchedulerIDX].stTask.tsTaskQueued = CPUA_OS_u32GetSysTimeStamp(); + queue_task(&OS_stKERNELTaskNodePool.stqTask[OS_u8SchedulerIDX], &OS_apstTaskQueue[OS_enKERNELQueueCyclic]); + //OS_xPrioritiseQueue(&OS_apstTaskQueue[OS_enKERNELQueueCyclic]); + //} + } + } + + for(OS_u8SchedulerIDX = OS_stCLIENTTaskNodePool.u32StartCount; OS_u8SchedulerIDX < (OS_stCLIENTTaskNodePool.u32StartCount + OS_stCLIENTTaskNodePool.u32CyclicCount); OS_u8SchedulerIDX++) + { + if((OS_u32TickCounter % OS_stCLIENTTaskNodePool.stqTask[OS_u8SchedulerIDX].stTask.enTaskRateMS) == 0) + { + /* only call module run task if module was activated successfully at start */ + //if(OS_bModuleActive[u8IDX] == true) + //{ + /* queue then run the KERNEL cyclic task list */ + OS_stCLIENTTaskNodePool.stqTask[OS_u8SchedulerIDX].stTask.tsTaskQueued = CPUA_OS_u32GetSysTimeStamp(); + queue_task(&OS_stCLIENTTaskNodePool.stqTask[OS_u8SchedulerIDX], &OS_apstTaskQueue[OS_enCLIENTQueueCyclic]); + //} + } + } +} + +void OS_vBackgroundDispatcher() +{ + /* run the Kernel cyclic task queue */ + run_cooperative_task_queue(&OS_apstTaskQueue[OS_enKERNELQueueCyclic], OS_vInterCoopTasks, &OS_u32SchedulerRunStatus); + + /* run the Client cyclic task queue */ + run_cooperative_task_queue(&OS_apstTaskQueue[OS_enCLIENTQueueCyclic], OS_vInterCoopTasks, &OS_u32SchedulerRunStatus); +#ifndef OS_MULTI_THREAD + while (1) + { + OS_vRunQueues(); + } +#endif //OS_MULTI_THREAD + /* invoke the Kernel next thread to run round robin */ + TQUEUEHA_vRunThreadTaskQueue(&OS_apstTaskQueue[OS_enKERNELQueueThread], OS_vInterCoopTasks); +} + +void OS_vTerminate(uint32* const u32Stat) +{ + +} + +void OS_vInterCoopTasks(void) +{ + OS_vRunQueues(); +} + +static void OS_vRunQueues(void) +{ + CLIENT_vRunUserCBQueue(); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); +} + +void OS_vSetCyclicTaskList(TASK_tstTask* pstTask) +{ + uint16 u16TaskID = 1000u; + while((pstTask->pfTaskFunction != NULL) && + (pstTask->tTaskID == u16TaskID) && + (u16TaskID++ < (1000u + OS_nClientTasksMax))) + { + memcpy((void*)&OS_stCLIENTTaskNodePool.stqTask[OS_stCLIENTTaskNodePool.u32TotalCount++].stTask, + (void*)pstTask++, sizeof(TASK_tstTask)); + } +} + +void OS_vPrioritiseQueue(task_queue* list) +{ + tq_struct* pstNode1; + tq_struct* pstNode2; + tq_struct* pstNode3; + uint16 u16I; + uint16 u16J; + uint16 u16NodeCount = 1; + + + pstNode1 = (tq_struct*)*list; + + while(pstNode1 -> next != NULL) + { + u16NodeCount++; + pstNode1 = (tq_struct*)pstNode1 -> next; + } + + for(u16I = 0; u16I < u16NodeCount - 1; u16I++) + { + pstNode1 = (tq_struct*)list; + pstNode2 = (tq_struct*)(pstNode1 -> next); + pstNode3 = (tq_struct*)(pstNode2 -> next); + + for(u16J = 0; u16J < u16NodeCount - u16I - 1; u16J++) + { + if(pstNode2 -> stTask.enTaskPriority > pstNode3 -> stTask.enTaskPriority) + { + pstNode2 -> next = (struct tq_struct*)(pstNode3 -> next); + pstNode3 -> next = (struct tq_struct*)pstNode2; + + if(u16J == 0) + { + *list = (struct tq_struct*)pstNode3; + } + else + { + pstNode1 -> next = (struct tq_struct*)pstNode3; + } + + pstNode1 = pstNode3; + pstNode3 = (tq_struct*)(pstNode2 -> next); + } + else + { + pstNode1 = pstNode2; + pstNode2 = pstNode3; + pstNode3 = (tq_struct*)(pstNode3 -> next); + } + } + } +} + +OS_tenOSState OS_enGetState(void) +{ + return OS_enOSState; +} + +void OS_vSetState(OS_tenOSState enOSState) +{ + OS_enOSState = enOSState; +} + +task_queue* OS_stGetOSQueue(OS_tenQueueType enQueueType) +{ + return &OS_apstTaskQueue[enQueueType]; +} + +OS_tenOSKernelMode OS_enGetOSKernelMode(void) +{ + return enOSKernelMode; +} + +void OS_vOverrunTaskReport(OS_tenQueueType enQueueType) +{ + static uint32 u32OverrunCount = 0; + + u32OverrunCount++; +} + +void OS_vSuspendThread(OS_tenQueueType enQueueType) +{ + /* TODO */ +} + +bool OS_boCreateThread(OS_tenQueueType enQueueType, TASK_tProgramCounter pEntryPoint) +{ + /* add the thread to system node pool */ + OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount].stTask.tTaskID = 1000; + OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount].stTask.enTaskType = enTaskThread; + OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount].stTask.enTaskState = TASKAPI_enTaskPrMaxAll; + OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount].stTask.pfTaskFunction = (void*)pEntryPoint; + OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount].stTask.tTaskProgramCounter = pEntryPoint; + OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount].stTask.tTaskStackPointer = + THREAD_pu32GetThreadStack(&OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount]); + OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount].stTask.enPrivilege = + (OS_enKERNELQueueThread == enQueueType) ? enTaskPrivileged : enTaskUnprivileged; + + queue_task(&OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount], &OS_apstTaskQueue[enQueueType]); + OS_stKERNELTaskNodePool.u32TotalCount++; + + return true; +} + +bool OS_boCreateDispatcherTask(OS_tenQueueType enQueueType, TASK_tProgramCounter pEntryPoint) +{ + /* add the task to system node pool */ + OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount].stTask.tTaskID = 1000; + OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount].stTask.enTaskType = enTaskFunction; + OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount].stTask.enTaskState = TASKAPI_enTaskPrMaxAll; + OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount].stTask.pfTaskFunction = (void (*)(uint32 *const))pEntryPoint; + OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount].stTask.tTaskStackPointer = + THREAD_pu32GetThreadStack(&OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount]); + OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount].stTask.enPrivilege = enTaskPrivileged; + OS_pstBackgroundDispatcherTask = &OS_stKERNELTaskNodePool.stqTask[OS_stKERNELTaskNodePool.u32TotalCount]; + OS_stKERNELTaskNodePool.u32TotalCount++; + + return true; +} + +SYSAPI_tenSVCResult OS_enAddTaskToQueue(OS_tenQueueType enQueueType, TASK_tstTask* pstTask) +{ + memcpy((void*)&OS_stCLIENTTaskNodePool.stqTask[OS_stCLIENTTaskNodePool.u32TotalCount].stTask, + (void*)pstTask, sizeof(TASK_tstTask)); + + OS_stCLIENTTaskNodePool.stqTask[OS_stCLIENTTaskNodePool.u32TotalCount].stTask.tsTaskQueued = CPUA_OS_u32GetSysTimeStamp(); + + switch (enQueueType) + { + case OS_enCLIENTQueueStart: + { + queue_task(&OS_stCLIENTTaskNodePool.stqTask[OS_stCLIENTTaskNodePool.u32TotalCount++], &OS_apstTaskQueue[OS_enCLIENTQueueStart]); + OS_stCLIENTTaskNodePool.u32StartCount++; + break; + } + case OS_enCLIENTQueueCyclic: + { + queue_task(&OS_stCLIENTTaskNodePool.stqTask[OS_stCLIENTTaskNodePool.u32TotalCount++], &OS_apstTaskQueue[OS_enCLIENTQueueCyclic]); + OS_stCLIENTTaskNodePool.u32CyclicCount++; + break; + } + case OS_enCLIENTQueueTerminate: + { + queue_task(&OS_stCLIENTTaskNodePool.stqTask[OS_stCLIENTTaskNodePool.u32TotalCount++], &OS_apstTaskQueue[OS_enCLIENTQueueTerminate]); + OS_stCLIENTTaskNodePool.u32TerminateCount++; + break; + } + default: + { + break; + } + } + + return SYSAPI_enOK; +} + + +void OS_vSystemIdleThread(uint32* const u32Stat) +{ + uint32 u32A; + uint32 u32B; + + while(1) + { + u32A++; + u32B++; + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + //DSCRIO_vSetDiscrete(enSYSTELLTALE, enToggle); + } +} + +#ifdef OS_MULTI_THREAD +void OS_vSystemDummyThread(uint32* const u32Stat) +{ + uint32 u32A; + uint32 u32B; + + while(1) + { + u32A++; + u32B++; + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + __asm("nop"); + //DSCRIO_vSetDiscrete(enSYSTELLTALE, enToggle); + } +} +#endif //OS_MULTI_THREAD + +static void OSHA_vLoadProcessStackASM(struct tq_struct* pstDispatcherTask) +{ + /* load PSP with dispatcher task stack pointer */ + //__asm("LDR R1, [R0, #18]"); //18 is TASK_SP_OFFSET + __asm("LDR R1, [R0, #18]"); //18 is TASK_SP_OFFSET UNPACKED TQSTRUCT + __asm("MSR PSP, R1"); + __asm("MRS R0, CONTROL"); + __asm("ORR R0, #2"); //2 is MASK_CONTROL_SPSEL_PSP + __asm("MSR CONTROL, R0"); + __asm("ISB"); + __asm("BX LR"); +} + + + + + + diff --git a/source/OS/OS.h b/source/OS/OS.h new file mode 100644 index 0000000..3331d9e --- /dev/null +++ b/source/OS/OS.h @@ -0,0 +1,217 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: OS Header File */ +/* DESCRIPTION: This code provides macros that describe the OS task */ +/* schedule and OS enums */ +/* FILE NAME: OS.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef OS_H +#define OS_H + +#include +#include +#include +#include "SYSAPI.h" +#include "tqueue.h" +#include "TASKAPI.h" + +#define OS_MULTI_THREAD_off + +/**/ +#define OS_nTaskStart \ +/* enTaskID, enType, enPriority, enState, enRateMS, pfFunction, tSP, tPC, tsCreated, tsStarted, tsFinished, tsAccumulated, tsPrivilege */\ +{ \ + { 1u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &CLIENT_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 2u , enTaskFunction , 5u , enTaskReady, TASKAPI_enTaskCycNot , &RESM_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 3u , enTaskFunction , 5u , enTaskReady, TASKAPI_enTaskCycNot , &SPREADS_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 4u , enTaskFunction , 5u , enTaskReady, TASKAPI_enTaskCycNot , &TABLES_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 5u , enTaskFunction , 5u , enTaskReady, TASKAPI_enTaskCycNot , &UART_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 6u , enTaskFunction , 15u , enTaskReady, TASKAPI_enTaskCycNot , &UDSAL_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 7u , enTaskFunction , 3u , enTaskReady, TASKAPI_enTaskCycNot , &PIM_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 8u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &FEE_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 9u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &CRC16_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 10u, enTaskFunction , 200u , enTaskReady, TASKAPI_enTaskCycNot , &ADC_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 11u, enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &DAC_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 12u, enTaskFunction , 100u , enTaskReady, TASKAPI_enTaskCycNot , &PIT_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 13u, enTaskFunction , 66u , enTaskReady, TASKAPI_enTaskCycNot , &DLL_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 14u, enTaskFunction , 77u , enTaskReady, TASKAPI_enTaskCycNot , &DSCRIO_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 15u, enTaskFunction , 77u , enTaskReady, TASKAPI_enTaskCycNot , &TIMER_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 16u, enTaskFunction , 77u , enTaskReady, TASKAPI_enTaskCycNot , &SDHC_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 17u, enTaskFunction , 77u , enTaskReady, TASKAPI_enTaskCycNot , &DISK_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 18u, enTaskFunction , 77u , enTaskReady, TASKAPI_enTaskCycNot , &TIME_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 19u, enTaskFunction , 78u , enTaskReady, TASKAPI_enTaskCycNot , &CAN_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 20u, enTaskFunction , 78u , enTaskReady, TASKAPI_enTaskCycNot , &CTRL_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 21u, enTaskFunction , 78u , enTaskReady, TASKAPI_enTaskCycNot , &TEPM_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 22u, enTaskFunction , 78u , enTaskReady, TASKAPI_enTaskCycNot , &VCOM_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 23u, enTaskFunction , 78u , enTaskReady, TASKAPI_enTaskCycNot , &SRLTFR_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged } \ +} + +#define OS_nTaskCyclic \ +/* enTaskID, enType, enPriority, enState, enRateMS, pfFunction, tSP, tPC, tsCreated, tsStarted, tsFinished, tsAccumulated, tsPrivilege */\ +{ \ + { 24u , enTaskCyclic , TASKAPI_enTaskPrMaxCyc, enTaskReady, 100u , &UART_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 25u , enTaskCyclic , 101u , enTaskReady, 10u , &UDSAL_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 26u , enTaskCyclic , 180u , enTaskReady, 20u , &PIM_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 27u , enTaskCyclic , 115u , enTaskReady, 20u , &ADC_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 28u , enTaskCyclic , 115u , enTaskReady, 20u , &DAC_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 29u , enTaskCyclic , 110u , enTaskReady, 20u , &PIT_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 30u , enTaskCyclic , 200u , enTaskReady, 1u , &DLL_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 31u , enTaskCyclic , 166u , enTaskReady, 1u , &FEE_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 32u , enTaskCyclic , 166u , enTaskReady, 250u , &DSCRIO_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 33u , enTaskCyclic , 166u , enTaskReady, 250u , &SDHC_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 34u , enTaskCyclic , 166u , enTaskReady, 250u , &DISK_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 35u , enTaskCyclic , 166u , enTaskReady, 250u , &TIME_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 36u , enTaskCyclic , 19u , enTaskReady, 1u , &CAN_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 37u , enTaskCyclic , 19u , enTaskReady, 1u , &CTRL_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 38u , enTaskCyclic , 19u , enTaskReady, 1u , &TEPM_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 39u , enTaskCyclic , 19u , enTaskReady, 1u , &CRC16_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 40u , enTaskCyclic , 19u , enTaskReady, 1u , &VCOM_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 41u , enTaskCyclic , 19u , enTaskReady, 5u , &SRLTFR_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged } \ +} + +#define OS_nTaskTerminate \ +/* enTaskID, enType, enPriority, enState, enRateMS, pfFunction, tSP, tPC, tsCreated, tsStarted, tsFinished, tsAccumulated, tsPrivilege */\ +{ \ + { 42u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &UART_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 43u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &UDSAL_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 44u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &PIM_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 45u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &ADC_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 46u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &DAC_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 47u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &PIT_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 48u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &DLL_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 49u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &FEE_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 50u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &DSCRIO_vTerminate, NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 51u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &SDHC_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 52u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &DISK_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 53u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &TIME_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 54u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &TIMER_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 55u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &CAN_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 56u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &CRC16_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 57u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &VCOM_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 58u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &SRLTFR_vTerminate, NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged } \ +} +/**/ + + +/**/ + + + +typedef enum +{ + OS_enOSStateReset, + OS_enOSStatePreBootloader, + OS_enOSStatePreOS, + OS_enOSStartRequest, + OS_enOSStateOSStarted, + OS_enOSStateAppStarted, + OS_enOSStateCount +} OS_tenOSState; +/**/ + +/**/ +typedef enum +{ + OS_enOSIDXCLIENT, + OS_enOSIDXUART, + OS_enOSIDXDIAG, + OS_enOSIDXPIM, + OS_enOSIDXADC, + OS_enOSIDXPIT, + OS_enOSIDXDLL, + OS_enOSIDXFEE, + OS_enOSIDXENE, + OS_enOSIDXBMX, + OS_enOSIDXWIFI, + OS_enOSIDXCAN, + OS_enOSIDXCount +} OS_tenOSModuleIDX; + +typedef enum +{ + OS_enOSModeKernel, + OS_enOSModeClient +} OS_tenOSKernelMode; + +typedef enum +{ + OS_enOSSchedulerTick, + OS_enOSSchedulerSWI, + OS_enOSSchedulerBHRequest +} OS_tenOSScheduleCallContext; + +typedef enum +{ + OS_enKERNELQueueStart, + OS_enKERNELQueueCyclic, + OS_enKERNELQueueThread, + OS_enKERNELQueueTerminate, + OS_enCLIENTQueueStart, + OS_enCLIENTQueueCyclic, + OS_enCLIENTQueueThread, + OS_enCLIENTQueueTerminate, + OS_enTaskQueueCount +} OS_tenQueueType; + + +#define OS_xModuleStartOK( x ) ( (x) = ( (x) << 1 ) | 1 ) +#define OS_xModuleStartFAIL( x ) ( (x) = (x) << 1 ) +#define OS_xModuleRunOK( x ) ( (x) = ( (x) << 1 ) | 1 ) +#define OS_xModuleRunEnd( x ) ( (x) = ( (x) << 1 )) +#define OS_xModuleRunFAIL( x ) ( (x) = ( (x) = 0 ) +#define OS_xAddTaskToRunQueue( x ) ( +#define OS_nTickCounterTerminal 4000000000u +#define OS_MODULE_START( x ) x ( &OS_ucModuleStartStatus ); +#define OS_nKernelHandle 0xF0001000 + + +/* macro to add any task to the static task queue */ +#define OS_xAddTaskToList( x, y ) memcpy( (OS_tstSYSTaskNodePool*)x->stTask[ (OS_tstSYSTaskNodePool*)x->u16Count++ ], \ + (TASK_tstTask*)y, sizeof( TASK_tstTask ) ) + +#ifdef SYS_TASK_PRIORITISE + #define OS_xPrioritiseQueue( x ) OS_vPrioritiseQueue( x ); +#else + #define OS_xPrioritiseQueue( x ) OS_vPrioritiseQueue( NULL ); +#endif + +#define OS_nClientTasksMax 35u + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _OS_C + #define EXTERN +#else + #define EXTERN extern +#endif + +EXTERN SYSAPI_tstSVCDataStruct OS_stSVCDataStruct; +EXTERN uint32 au32SVCResult[10]; +EXTERN uint32 OS_u32TickCounter; + +void OS_vStart( uint32* const ); +void OS_vRun( uint32* const ); +void OS_vSchedule( OS_tenOSScheduleCallContext ); +void OS_vTerminate( uint32* const ); +void OS_vSetCyclicTaskList (TASK_tstTask*); +void OS_vPrioritiseQueue( task_queue* ); +void OS_vBackgroundDispatcher( void ); +OS_tenOSState OS_enGetState( void ); +void OS_vSetState(OS_tenOSState); +task_queue* OS_stGetOSQueue( OS_tenQueueType); +OS_tenOSKernelMode OS_enGetOSKernelMode( void ); +void OS_vOverrunTaskReport( OS_tenQueueType ); +void OS_vSuspendThread( OS_tenQueueType ); +void OS_vSystemIdleThread( uint32* const ); +void OS_vInterCoopTasks(void); +SYSAPI_tenSVCResult OS_enAddTaskToQueue(OS_tenQueueType, TASK_tstTask*); + +#endif // OS_H + + diff --git a/source/OS/OSHA.h b/source/OS/OSHA.h new file mode 100644 index 0000000..a715b75 --- /dev/null +++ b/source/OS/OSHA.h @@ -0,0 +1,23 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: OS Header File */ +/* DESCRIPTION: This code provides macros that describe the OS task */ +/* schedule and OS enums */ +/* FILE NAME: OS.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef OSHA_H +#define OSHA_H + +#include "tqueue.h" + +void OSHA_vLoadProcessStack(struct tq_struct*); + + +#endif //OSHA_H + + diff --git a/source/OS/OSTASKS.h b/source/OS/OSTASKS.h new file mode 100644 index 0000000..e1dd984 --- /dev/null +++ b/source/OS/OSTASKS.h @@ -0,0 +1,130 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: OS Header File */ +/* DESCRIPTION: This code provides macros that describe the OS task */ +/* schedule and OS enums */ +/* FILE NAME: OS.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#ifndef OSTASKS_H +#define OSTASKS_H + +extern void UDSAL_vStart(puint32); +extern void UDSAL_vRun(puint32); +extern void UDSAL_vTerminate(puint32); + +#include "PERADC.h" +#include "PERCAN.h" +#include "CEM.h" +#include "CRC16.h" +#include "CLIENT.h" +#include "CTRL.h" +#include "DAC.h" +#include "DISK.h" +#include "DLL.h" +#include "DSCRIO.h" +#include "ENE.h" +#include "FEE.h" +#include "maps.h" +#include "PIM.h" +#include "PIT.h" +#include "RESM.h" +#include +#include "spreads.h" +#include "SRLTFR.h" +#include "tables.h" +#include "TASKAPI.h" +#include "TEPM.h" +#include "time.h" +#include "TIMER.h" +#include "PERUART.h" +#include "WIFI.h" +#include "task.h" + +#define OSTASKS_nTaskStart \ +/* enTaskID, enType, enPriority, enState, enRateMS, pfFunction, tSP, tPC, tsCreated, tsStarted, tsFinished, tsAccumulated, tsPrivilege */\ +{ \ + { 1u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &CLIENT_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 2u , enTaskFunction , (TASKAPI_tenPriority)5u , enTaskReady, TASKAPI_enTaskCycNot , &RESM_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 3u , enTaskFunction , (TASKAPI_tenPriority)5u , enTaskReady, TASKAPI_enTaskCycNot , &SPREADS_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 4u , enTaskFunction , (TASKAPI_tenPriority)5u , enTaskReady, TASKAPI_enTaskCycNot , &TABLES_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 5u , enTaskFunction , (TASKAPI_tenPriority)5u , enTaskReady, TASKAPI_enTaskCycNot , &MAPS_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 6u , enTaskFunction , (TASKAPI_tenPriority)5u , enTaskReady, TASKAPI_enTaskCycNot , &UART_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 7u , enTaskFunction , (TASKAPI_tenPriority)15u , enTaskReady, TASKAPI_enTaskCycNot , &UDSAL_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 8u , enTaskFunction , (TASKAPI_tenPriority)3u , enTaskReady, TASKAPI_enTaskCycNot , &PIM_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 9u , enTaskFunction , TASKAPI_enTaskPrMaxAll , enTaskReady, TASKAPI_enTaskCycNot , &FEE_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 10u , enTaskFunction , TASKAPI_enTaskPrMaxAll , enTaskReady, TASKAPI_enTaskCycNot , &CRC16_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 11u , enTaskFunction , (TASKAPI_tenPriority)200u, enTaskReady, TASKAPI_enTaskCycNot , &ADC_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 12u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &DAC_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 13u , enTaskFunction , (TASKAPI_tenPriority)100u , enTaskReady, TASKAPI_enTaskCycNot , &PIT_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 14u , enTaskFunction , (TASKAPI_tenPriority)66u , enTaskReady, TASKAPI_enTaskCycNot , &DLL_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 15u , enTaskFunction , (TASKAPI_tenPriority)77u , enTaskReady, TASKAPI_enTaskCycNot , &ENE_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 16u , enTaskFunction , (TASKAPI_tenPriority)77u , enTaskReady, TASKAPI_enTaskCycNot , &WIFI_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 17u , enTaskFunction , (TASKAPI_tenPriority)77u , enTaskReady, TASKAPI_enTaskCycNot , &DSCRIO_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 18u , enTaskFunction , (TASKAPI_tenPriority)77u , enTaskReady, TASKAPI_enTaskCycNot , &TIMER_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 19u , enTaskFunction , (TASKAPI_tenPriority)77u , enTaskReady, TASKAPI_enTaskCycNot , &SDHC_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 20u , enTaskFunction , (TASKAPI_tenPriority)77u , enTaskReady, TASKAPI_enTaskCycNot , &DISK_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 21u , enTaskFunction , (TASKAPI_tenPriority)77u , enTaskReady, TASKAPI_enTaskCycNot , &TIME_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 22u , enTaskFunction , (TASKAPI_tenPriority)78u , enTaskReady, TASKAPI_enTaskCycNot , &CAN_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 23u , enTaskFunction , (TASKAPI_tenPriority)78u , enTaskReady, TASKAPI_enTaskCycNot , &CTRL_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 24u , enTaskFunction , (TASKAPI_tenPriority)78u , enTaskReady, TASKAPI_enTaskCycNot , &TEPM_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 25u , enTaskFunction , (TASKAPI_tenPriority)78u , enTaskReady, TASKAPI_enTaskCycNot , &CEM_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 26u , enTaskFunction , (TASKAPI_tenPriority)78u , enTaskReady, TASKAPI_enTaskCycNot , &SRLTFR_vStart , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged } \ +} + +#define OSTASKS_nTaskCyclic \ +/* enTaskID, enType, enPriority, enState, enRateMS, pfFunction, tSP, tPC, tsCreated, tsStarted, tsFinished, tsAccumulated, tsPrivilege */\ +{ \ + { 27u , enTaskCyclic , TASKAPI_enTaskPrMaxCyc, enTaskReady, TASKAPI_enTask100ms , &UART_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 28u , enTaskCyclic , (TASKAPI_tenPriority)101u , enTaskReady, TASKAPI_enTask10ms , &UDSAL_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 29u , enTaskCyclic , (TASKAPI_tenPriority)180u , enTaskReady, TASKAPI_enTask20ms , &PIM_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 30u , enTaskCyclic , (TASKAPI_tenPriority)115u , enTaskReady, TASKAPI_enTask20ms , &ADC_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 31u , enTaskCyclic , (TASKAPI_tenPriority)115u , enTaskReady, TASKAPI_enTask20ms , &DAC_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 32u , enTaskCyclic , (TASKAPI_tenPriority)110u , enTaskReady, TASKAPI_enTask20ms , &PIT_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 33u , enTaskCyclic , (TASKAPI_tenPriority)200u , enTaskReady, TASKAPI_enTask1ms , &DLL_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 34u , enTaskCyclic , (TASKAPI_tenPriority)166u , enTaskReady, TASKAPI_enTask1ms , &FEE_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 35u , enTaskCyclic , (TASKAPI_tenPriority)166u , enTaskReady, TASKAPI_enTask1ms , &ENE_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 36u , enTaskCyclic , (TASKAPI_tenPriority)166u , enTaskReady, TASKAPI_enTask250ms , &WIFI_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 37u , enTaskCyclic , (TASKAPI_tenPriority)166u , enTaskReady, TASKAPI_enTask250ms , &DSCRIO_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 38u , enTaskCyclic , (TASKAPI_tenPriority)166u , enTaskReady, TASKAPI_enTask250ms , &SDHC_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 39u , enTaskCyclic , (TASKAPI_tenPriority)166u , enTaskReady, TASKAPI_enTask250ms , &DISK_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 40u , enTaskCyclic , (TASKAPI_tenPriority)166u , enTaskReady, TASKAPI_enTask250ms , &TIME_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 41u , enTaskCyclic , (TASKAPI_tenPriority)19u , enTaskReady, TASKAPI_enTask1ms , &CAN_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 42u , enTaskCyclic , (TASKAPI_tenPriority)19u , enTaskReady, TASKAPI_enTask1ms , &CTRL_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 43u , enTaskCyclic , (TASKAPI_tenPriority)19u , enTaskReady, TASKAPI_enTask1ms , &CRC16_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 44u , enTaskCyclic , (TASKAPI_tenPriority)19u , enTaskReady, TASKAPI_enTask20ms , &CEM_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 45u , enTaskCyclic , (TASKAPI_tenPriority)19u , enTaskReady, TASKAPI_enTask1ms , &SRLTFR_vRun , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged } \ +} + +#define OSTASKS_nTaskTerminate \ +/* enTaskID, enType, enPriority, enState, enRateMS, pfFunction, tSP, tPC, tsCreated, tsStarted, tsFinished, tsAccumulated, tsPrivilege */\ +{ \ + { 46u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &UART_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 47u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &UDSAL_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 48u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &PIM_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 49u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &ADC_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 50u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &DAC_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 51u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &PIT_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 52u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &DLL_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 53u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &FEE_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 54u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &ENE_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 55u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &WIFI_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 56u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &DSCRIO_vTerminate, NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 57u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &SDHC_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 58u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &DISK_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 59u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &TIME_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 60u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &TIMER_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 61u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &CAN_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 62u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &CRC16_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 63u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &CEM_vTerminate , NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged },\ + { 64u , enTaskFunction , TASKAPI_enTaskPrMaxAll, enTaskReady, TASKAPI_enTaskCycNot , &SRLTFR_vTerminate, NULL, NULL, 0u , 0u , 0u , 0u , enTaskPrivileged } \ +} + +#endif //OSTASKS_H + + diff --git a/source/OS/STACK.c b/source/OS/STACK.c new file mode 100644 index 0000000..de9a35d --- /dev/null +++ b/source/OS/STACK.c @@ -0,0 +1,18 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: STACK */ +/* DESCRIPTION: This code is a dummy for future stack functions */ +/* */ +/* FILE NAME: STACK.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include "stack.h" + + + + diff --git a/source/OS/STACK.h b/source/OS/STACK.h new file mode 100644 index 0000000..1e088d7 --- /dev/null +++ b/source/OS/STACK.h @@ -0,0 +1,32 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: STACK Header File */ +/* DESCRIPTION: This code provides struct definition for thread stack */ +/* */ +/* FILE NAME: STACK.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef STACK_H +#define STACK_H + +#include +#include + +typedef struct BUILD_PACKING +{ + uint32 u32R0; + uint32 u32R1; + uint32 u32R2; + uint32 u32R3; + uint32 u32R12; + uint32 u32LR; + uint32 u32PC; + uint32 u32xPSR; +} STACK_tstStackFrame; + +#endif // STACK_H + diff --git a/source/OS/TASK.c b/source/OS/TASK.c new file mode 100644 index 0000000..2984875 --- /dev/null +++ b/source/OS/TASK.c @@ -0,0 +1,27 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: TASK */ +/* DESCRIPTION: This code provides functions for reporting of tasks */ +/* */ +/* FILE NAME: TASK.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include +#include "TASKAPI.h" + +TASK_tstTime TASK_vReportRunTime(TASK_tstTask* const pstTask) +{ + return pstTask->tsTaskFinished - pstTask->tsTaskStarted; +} + + + + + + + diff --git a/source/OS/TASK.h b/source/OS/TASK.h new file mode 100644 index 0000000..ba9b2b4 --- /dev/null +++ b/source/OS/TASK.h @@ -0,0 +1,82 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: TASK Header File */ +/* DESCRIPTION: This code provides definitions of task structs and */ +/* enums */ +/* FILE NAME: TASK.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef TASK_H +#define TASK_H + +#include +#include +#include "TASKAPI.h" + +// typedef enum +// { +// enTaskPrMaxAll = 0u, +// enTaskPrMaxCyc = 128u, +// enTaskPrLowest = 255u, +// } TASK_tenPriority; + +// typedef enum +// { +// enTaskCycBad = 0u, +// enTask1ms = 1u, +// enTask2ms = 2u, +// enTask5ms = 5u, +// enTask10ms = 10u, +// enTask25ms = 25u, +// enTask100ms = 100u, +// enTask200ms = 200u, +// enTaskCycNot = 255u +// } TASK_tenRateMs; + +typedef enum { + enTaskNew, enTaskRunning, enTaskReady, enTaskFinished, enTaskBlocked +} TASK_tenState; + +typedef enum { + enTaskFunction, enTaskCyclic, enTaskThread +} TASK_tenType; + +typedef enum { + enTaskPrivileged = 0, enTaskUnprivileged = 1 +} TASK_tenPrivilege; + +typedef uint16 TASK_tID; +typedef uint32 TASK_tstTime; +typedef void* TASK_tProgramCounter; +typedef void* TASK_tStackPointer; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wattributes" + +typedef struct +{ + TASK_tID tTaskID; //0 + TASK_tenType enTaskType; //2 + TASKAPI_tenPriority enTaskPriority; //3 + TASK_tenState enTaskState; //4 + TASKAPI_tenRateMs enTaskRateMS; //5 + void (*pfTaskFunction)(uint32* const); //6 + TASK_tStackPointer tTaskStackPointer; //10 + TASK_tProgramCounter tTaskProgramCounter; //14 + TASK_tstTime tsTaskQueued; //18 + TASK_tstTime tsTaskStarted; //22 + TASK_tstTime tsTaskFinished; //26 + TASK_tstTime tsTaskAccumulated; //30 + TASK_tenPrivilege enPrivilege; //34 +} BUILD_PACKING TASK_tstTask; + +#pragma GCC diagnostic pop + +TASK_tstTime TASK_vReportRunTime(TASK_tstTask* const); + + +#endif // TASK_H + diff --git a/source/OS/THREAD.c b/source/OS/THREAD.c new file mode 100644 index 0000000..06cd012 --- /dev/null +++ b/source/OS/THREAD.c @@ -0,0 +1,70 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: THREAD */ +/* DESCRIPTION: This code provides thread stack functions */ +/* */ +/* FILE NAME: THREAD.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include +#include +#include + +typedef struct +{ + uint32 u32ThreadStack[ SYS_THREAD_STACK_SIZE ]; +} THREAD_tastThreadStack; + +THREAD_tastThreadStack THREAD_astThreadStack[SYS_THREAD_MAX]; +tq_struct* THREAD_pstStackOwner[SYS_THREAD_MAX] = { NULL }; + + +void THREAD_vStart(uint32* const pu32Stat) +{ + uint32 u32StackIDX; + + for (u32StackIDX = 0; u32StackIDX < SYS_THREAD_MAX; u32StackIDX++) + { + THREAD_pstStackOwner[u32StackIDX] = NULL; + } +} + + +uint32* THREAD_pu32GetThreadStack( tq_struct* pstStackOwnerTask ) +{ + uint32 u32StackIDX; + uint32* pu32StackPointer = NULL; + STACK_tstStackFrame* pstStackFrame; + + for(u32StackIDX = 0; u32StackIDX < SYS_THREAD_MAX; u32StackIDX++) + { + if( NULL == THREAD_pstStackOwner[ u32StackIDX ] ) + { + THREAD_pstStackOwner[ u32StackIDX ] = pstStackOwnerTask; + pu32StackPointer = (uint32*)( (uint32)&THREAD_astThreadStack[ u32StackIDX ] + + (uint32)SYS_THREAD_STACK_SIZE * sizeof(uint32) ); + break; + } + } + + /* set the thread entry point at the stack frame program counter + ready for the initial thread context restore */ + pu32StackPointer -= ( sizeof(STACK_tstStackFrame) / sizeof(uint32) ); + pstStackFrame = (STACK_tstStackFrame*)pu32StackPointer; + pstStackFrame->u32PC = (uint32)pstStackOwnerTask->stTask.tTaskProgramCounter; + + return pu32StackPointer; +} + + + + + + + + diff --git a/source/OS/THREAD.h b/source/OS/THREAD.h new file mode 100644 index 0000000..a99e904 --- /dev/null +++ b/source/OS/THREAD.h @@ -0,0 +1,27 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: THREAD Header File */ +/* DESCRIPTION: This code provides thread stack function declarations */ +/* */ +/* FILE NAME: THREAD.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef THREAD_H +#define THREAD_H + +#include +#include +#include +#include "TASKAPI.h" +#include "tqueue.h" + +uint32* THREAD_pu32GetThreadStack(tq_struct*); +void THREAD_vStart(uint32* const pu32Stat); + +#endif // THREAD_H + + diff --git a/source/OS/tqueue.c b/source/OS/tqueue.c new file mode 100644 index 0000000..f77c55d --- /dev/null +++ b/source/OS/tqueue.c @@ -0,0 +1,53 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: TQUEUE */ +/* DESCRIPTION: This code provides functions for running task queues */ +/* */ +/* FILE NAME: TQUEUE.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#include "tqueue.h" +#include "tqueueHA.h" +#include "types.h" +#include "task.h" +#include "CPUAbstract.h" + +void queue_task(tq_struct* task_pointer, task_queue* task_list) +{ + task_pointer->next = *task_list; + *task_list = (task_queue)task_pointer; +} + +/* + * Call all tasks in a given list. + */ +void run_cooperative_task_queue(task_queue* list, pfInterTaskFunction pfInterTask, uint32* pu32Stat) +{ + tq_struct* p; + tq_struct* save_p; + void (*f)(uint32*); + + p = (struct tq_struct*)*list; + while (p != NULL) + { + f = p -> stTask.pfTaskFunction; // copy the task function pointer + p -> stTask.tsTaskStarted = CPUA_OS_u32GetSysTimeStamp(); + save_p = p; // save the tq_struct + p = (tq_struct*)p -> next; // point to next node + (*f)(pu32Stat); // run the task function + save_p -> stTask.tsTaskFinished = CPUA_OS_u32GetSysTimeStamp(); + *list = (task_queue)p; // update the list + save_p -> next = NULL; // set the old tq_struct->next to NULL + if (NULL != pfInterTask) pfInterTask(); // run the intertask function + } +} + +void TQUEUE_vRunThreadTaskQueue(task_queue* list, pfInterTaskFunction pfInterThread) +{ + TQUEUEHA_vRunThreadTaskQueue(list, pfInterThread); +} \ No newline at end of file diff --git a/source/OS/tqueue.h b/source/OS/tqueue.h new file mode 100644 index 0000000..4ef447c --- /dev/null +++ b/source/OS/tqueue.h @@ -0,0 +1,42 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: TQUEUE Header File */ +/* DESCRIPTION: This code provides definitions of task queue structs */ +/* */ +/* FILE NAME: TQUEUE.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef _TQUEUE_H +#define _TQUEUE_H + +#include "types.h" +#include "task.h" +#include "TASKAPI.h" + +/* modified linux task queue header */ +typedef void (*pfInterTaskFunction)(void); + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wattributes" + +typedef struct tq_struct +{ + struct tq_struct* next; /* linked list of queued tasks */ + struct tq_struct* prev; /* doubly linked list for removal and insertion */ + TASK_tstTask stTask; /* the task */ +} BUILD_PACKING tq_struct; + +#pragma GCC diagnostic pop + +typedef struct tq_struct* task_queue; + + +void queue_task(struct tq_struct* task_pointer, task_queue* task_list); +void run_cooperative_task_queue(task_queue* list, pfInterTaskFunction, uint32* pu32Stat); +void TQUEUE_vRunThreadTaskQueue(task_queue* list, pfInterTaskFunction); + +#endif /* _TQUEUE_H */ diff --git a/source/OS/tqueueHA.c b/source/OS/tqueueHA.c new file mode 100644 index 0000000..5595eef --- /dev/null +++ b/source/OS/tqueueHA.c @@ -0,0 +1,77 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: TQUEUE Hardware Adaption */ +/* DESCRIPTION: This code provides functions for running task queues */ +/* */ +/* FILE NAME: TQUEUEHA.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#include "CPUAbstract.h" +#include "tqueue.h" +#include "types.h" +#include "task.h" + + +static void run_thread_task_queue(task_queue* list, pfInterTaskFunction pfInterThread); + +void TQUEUEHA_vRunThreadTaskQueue(task_queue* list, pfInterTaskFunction pfInterThread) +{ + run_thread_task_queue(list, pfInterThread); +} + +static void run_thread_task_queue(task_queue* list, pfInterTaskFunction pfInterThread) +{ + __asm(".EQU TASK_PC_OFFSET, 22"); + __asm(".EQU TASK_SP_OFFSET, 18"); + __asm(".EQU FRAME_R0_OFFSET, 0"); + __asm(".EQU FRAME_R1_OFFSET, 4"); + __asm(".EQU FRAME_R2_OFFSET, 8"); + __asm(".EQU FRAME_R3_OFFSET, 12"); + __asm(".EQU FRAME_R12_OFFSET, 16"); + __asm(".EQU FRAME_LR_OFFSET, 20"); + __asm(".EQU FRAME_PC_OFFSET, 24"); + __asm(".EQU FRAME_XPSR_OFFSET, 28"); + __asm(".EQU TASK_PRIVILEGE_OFFSET, 42"); + __asm(".EQU MASK_XPSR_THUMB, 16777216"); + +/* get current task in R1 */ + __asm("LDR R1, [R0]"); + +/* change the control register stack select to Process Stack Pointer and */ +/* set the privilege from the task privilege enum */ + __asm("MOV R2, #2"); + __asm("LDR R3, [R1, #TASK_PRIVILEGE_OFFSET]"); + __asm("AND R3, #1"); + __asm("ORR R3, R2"); + __asm("MSR CONTROL, R3"); + __asm("ISB"); + +/* restore the current task stack pointer from task structure stack pointer */ + __asm("LDR SP, [R1, #TASK_SP_OFFSET]"); + +/* restore the XPSR, setting thumb bit always */ + __asm("LDR R0, [SP, #FRAME_XPSR_OFFSET]"); + __asm("ORR R0, #MASK_XPSR_THUMB"); +/* __asm("MSR XPSR, R0"); matthew*/ + +/* set the thumb bit of the return vector */ + __asm("LDR R0, [SP, #FRAME_PC_OFFSET]"); + __asm("ORR R0, #1"); + __asm("STR R0, [SP, #FRAME_XPSR_OFFSET]"); + +/* restore stack frame remaining registers then return */ + __asm("POP {R0, R1, R2, R3, R12, LR}"); + __asm("ADD SP, #4"); + __asm("POP {PC}"); + +/* restore current task program counter from task structure program counter */ +/* LDR PC, [R1, #TASK_PC_OFFSET] */ +} + + + diff --git a/source/OS/tqueueHA.h b/source/OS/tqueueHA.h new file mode 100644 index 0000000..508cfaf --- /dev/null +++ b/source/OS/tqueueHA.h @@ -0,0 +1,20 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: TQUEUE Header File */ +/* DESCRIPTION: This code provides definitions of task queue structs */ +/* */ +/* FILE NAME: TQUEUEHA.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef _TQUEUEHA_H +#define _TQUEUEHA_H + +#include "tqueue.h" + +void TQUEUEHA_vRunThreadTaskQueue(task_queue* list, pfInterTaskFunction pfInterThread); + +#endif /* _TQUEUEHA_H */ diff --git a/source/Peripherals/ADCHA.c b/source/Peripherals/ADCHA.c new file mode 100644 index 0000000..5792a3e --- /dev/null +++ b/source/Peripherals/ADCHA.c @@ -0,0 +1,431 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include +#include +#include +#include +#include "mk64f12.h" +#include "CRC16.h" +#include "CPUAbstract.h" +#include "regset.h" +#include "os.h" +#include "MSG.h" +#include "PERADC.h" +#include "CQUEUE.h" +#include "ADCAPI.h" +#include "SIM.h" +#include "IRQ.h" +#include "dscrio.h" +#include "adcha.h" + +const REGSET_tstReg32Val ADCHA_rastADCReg32Val[] = ADCHA_nReg32Set; +const ADCHA_tstADCChannel ADCHA_rastADCChannel[] = ADCHA_nChannelInfo; +const IOAPI_tenEHIOResource ADCHA_raenIOResource[] = ADCHA_nIOResourceMap; +uint32 ADCHA_u32PortClockRequested; +uint32 ADCHA_u32Calibrated; +bool ADCHA_aboModuleBusy[ADCHA_enChannelCount]; + +#ifdef ADC_CALIBRATE +static void ADCHA_vBackupCalibration(tstADCModule* pstADC, ADCHA_tstADCCalStruct* pstADCCalStruct); +#endif //ADC_CALIBRATE + +static void ADCHA_vInitInterrupts(IRQn_Type enIrq); + +void ADCHA_vStart(uint32* const pu32Stat) +{ + uint32 u32IDX; + + for (u32IDX = 0; u32IDX < ADCHA_enChannelCount; u32IDX++) + { + ADCHA_aboModuleBusy[u32IDX] = false; + } + +#if defined(BUILD_MK60) + ADC_xInitialise(ADC3, ADC3_IRQn); + ADC_xInitialise(ADC2, ADC2_IRQn); + ADC_xInitialise(ADC1, ADC1_IRQn); + ADC_xInitialise(ADC0, ADC0_IRQn); + REGSET_vInitReg32(&ADCHA_rastADCReg32Val[0]); +#endif //BUILD_MK60 + +#if defined(BUILD_MK64) + ADCHA_xInitialise(ADC1, ADC1_IRQn); + ADCHA_xInitialise(ADC0, ADC0_IRQn); + REGSET_vInitReg32(ADCHA_rastADCReg32Val); +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E + tstADCModule* pstADCModule = ADC; + (void)SIM_boEnablePeripheralClock(ADC_IRQn); + ADCHA_u32PortClockRequested = 1; + adc_init(pstADCModule, SYS_FREQ_BUS, ADCHA_nADCCLKFREQ, ADCHA_nADCTRSTTIME); + IRQ_vEnableIRQ(ADC_IRQn, IRQ_enPRIO_8, ADC_vInterruptHandler, NULL); +#endif +} + + +bool ADCHA_boBackupCalibrations(void) +{ + bool boRetCode = FALSE; + +/* TODO +#if defined(BUILD_MK60) || defined(BUILD_MK64) + ADCHA_tstADCCalStruct* pstADCCalStruct; + + if (TRUE == FEE_boCheckPartition()) + { + ADCHA_vBackupCalibration(ADC0, pstADCCalStruct++); + ADCHA_vBackupCalibration(ADC1, pstADCCalStruct++); + boRetCode = TRUE; + } +#endif +*/ + return boRetCode; +} + + +void ADCHA_vInitADCResourcePGA(ADCHA_tstADCConversion* pstADCConversion) +{ +#if defined(BUILD_MK60) + tstADCModule* pstADC; + /* Set the differential gain */ + pstADC = ADCHA_pstGetADCModule(pstADCConversion->stADCChannel.enADCModule); + pstADC->PGA = (ADC_PGA_PGAG(pstADCCB->enDiffGain) | ADC_PGA_PGAEN_MASK); +#endif //BUILD_MK6X +} + +void ADCHA_vInitChannel(IOAPI_tenEHIOResource enIOResource) +{ +#ifdef BUILD_SAM3X8E + tstADCModule* pstADC = ADCHA_pstGetADCModule(ADCHA_enADC0); + uint32 u32Channel = ADCHA_rastADCChannel[enIOResource].u32ADChannel; + adc_enable_channel(pstADC, u32Channel); + //adc_enable_interrupt(pstADC, 1 << u32Channel); +#endif //BUILD_SAM3X8E +} + +void ADCHA_vTerminate(uint32* const u32Stat) +{ + +} + +bool ADCHA_boInitiateConversion(ADCHA_tstADCConversion* pstADCConversion, ADCHA_tenQueue enQueue, uint32 u32QueueTail, bool boPreserveSeq) +{ + bool boADCInitPending = TRUE; + tstADCModule* pstADC; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + uint32 u32Conversion; + pstADC = ADCHA_pstGetADCModule(pstADCConversion->stADCChannel.enADCModule); + + if (ADC_SC1_ADCH_MASK == (ADC_SC1_ADCH_MASK & pstADC->SC1[0])) + { + boADCInitPending = FALSE; + + pstADC->CFG2 &= ~ADC_CFG2_MUXSEL_MASK; + pstADC->CFG2 |= (pstADCConversion->stADCChannel.enChannelAB << ADC_CFG2_MUXSEL_SHIFT) | + ADC_CFG2_ADHSC_MASK; + + pstADC->SC3 = (ADC_SC3_AVGS_MASK | ADC_SC3_AVGE_MASK | (pstADCConversion->stADCChannel.u32Samples)); + u32Conversion = ADC_SC1_ADCH_MASK & pstADCConversion->stADCChannel.u32ADChannel; + u32Conversion |= ADC_SC1_AIEN_MASK; + + if (TRUE == pstADCConversion->stADCChannel.boIsDiff) + { + u32Conversion |= ADC_SC1_DIFF_MASK; + } + + pstADC->SC1[0] = u32Conversion; + } +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + ADCHA_tstADCConversion* pstADCConversionQueue; + uint32 u32ConversionIDX; + enum adc_channel_num_t aenChannels[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + uint32 u32ChannelMask = 0; + uint32 u32Temp = 0; + uint32 u32TerminateInterrupt = 0; + + boADCInitPending = FALSE; + ADCHA_aboModuleBusy[0] = true; + + pstADC = ADC; + //adc_disable_all_channel(pstADC); + adc_disable_interrupt(pstADC, 0xffff); + + ///* Clear flags */ + //for (u32ConversionIDX = 0; u32ConversionIDX < 16; u32ConversionIDX++) + //{ + //u32ChannelMask = MATH_u32IDXToMask(u32ConversionIDX); +// + //if (u32ChannelMask == (pstADC->ADC_ISR & u32ChannelMask)) + //{ + ///* Dummy read the data register to clear the flag */ + //u32ChannelMask = pstADC->ADC_CDR[u32ConversionIDX]; + //} + //} + + /* Enable the required channels except the last */ + //pstADCConversionQueue = pstADCConversion; + //for (u32ConversionIDX = 0; u32ConversionIDX < u32QueueTail; u32ConversionIDX++) + //{ + //adc_enable_channel(pstADC, (enum adc_channel_num_t)pstADCConversionQueue->stADCChannel.u32ADChannel); + //pstADCConversionQueue++; + //} + + /* Configure the sequence */ + u32ChannelMask = 0; + pstADCConversionQueue = pstADCConversion; + for (u32ConversionIDX = 0; u32ConversionIDX < u32QueueTail; u32ConversionIDX++) + { + u32ChannelMask |= MATH_u32IDXToMask(pstADCConversionQueue->stADCChannel.u32ADChannel); + pstADCConversionQueue++; + } + + for (u32ConversionIDX = 0; u32ConversionIDX < 16; u32ConversionIDX++) + { + u32Temp = MATH_u32IDXToMask(u32ConversionIDX); + u32Temp &= u32ChannelMask; + + if (0 != u32Temp) + { + aenChannels[u32ConversionIDX] = (enum adc_channel_num_t)u32ConversionIDX; + u32TerminateInterrupt = u32Temp; + } + } + + adc_enable_interrupt(pstADC, u32TerminateInterrupt); + + //if (TRUE == boPreserveSeq) + { + adc_start_sequencer(pstADC); + adc_configure_sequence(pstADC, aenChannels, 16); + } + + adc_start(pstADC); + +#endif //BUILD_SAM3X8E + + return boADCInitPending; +} + +tstADCModule* ADCHA_pstGetADCModule(ADCHA_tenADCModule enADCModule) +{ + tstADCModule* pstADC = NULL; + +#if defined(BUILD_MK60) + switch(enADCModule) + { + case ADCHA_enADC0: pstADC = ADC0; break; + case ADCHA_enADC1: pstADC = ADC1; break; + case ADCHA_enADC2: pstADC = ADC2; break; + case ADCHA_enADC3: pstADC = ADC3; break; + default: pstADC = NULL; break; + } +#endif //BUILD_MK6X + +#if defined(BUILD_MK64) + switch(enADCModule) + { + case ADCHA_enADC0: pstADC = ADC0; break; + case ADCHA_enADC1: pstADC = ADC1; break; + default: pstADC = NULL; break; + } +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +switch(enADCModule) +{ + case ADCHA_enADC0: pstADC = ADC; break; + default: pstADC = NULL; break; +} +#endif //BUILD_SAM3X8E + + return pstADC; +} + +uint32 ADCHA_u32GetAvailableResultCount(tstADCModule* pstADC) +{ + uint32 u32RetVal = 1; + +#ifdef BUILD_SAM3X8E + u32RetVal = 0; + uint32 u32ChannelMask = 1; + + while (0x8000 > u32ChannelMask) + { + if (u32ChannelMask == (u32ChannelMask & pstADC->ADC_CHSR)) u32RetVal++; + u32ChannelMask *= 2; + } +#endif //BUILD_SAM3X8E + + return u32RetVal; +} + +void ADCHA_vCalibrate(tstADCModule* pstADC, uint32 u32ADCIDX, uint32 u32CalFlag) +{ +#ifdef ADC_CALIBRATE +#if defined(BUILD_MK60) || defined(BUILD_MK64) + uint16 u16Temp; + uint16 u16CRC; + ADCHA_tstADCCalStruct* pstADCCalStruct = (ADCHA_tstADCCalStruct*)FEEHA_ADCREC_ADDRESS + u32ADCIDX; + + //u16CRC = CRC16_u16CalcCRC(0xffff, (puint8)pstADCCalStruct, sizeof(ADCHA_tstADCCalStruct) - sizeof(uint32)); + +#if (ADC_nCalFromRecord) + if(true) + //if ((uint32)u16CRC != pstADCCalStruct->u32CRC) +#else + if (true) +#endif + { + pstADC->SC2 &= ~ ADC_SC2_ADTRG_MASK; + pstADC->SC3 |= ADC_SC3_CAL_MASK; + + while (0 != (pstADC->SC2 & ADC_SC2_ADACT_MASK)) {}; + + if (0 == (pstADC->SC3 & ADC_SC3_CALF_MASK)) + { + u16Temp = 0; + u16Temp += pstADC->CLP0; + u16Temp += pstADC->CLP1; + u16Temp += pstADC->CLP2; + u16Temp += pstADC->CLP3; + u16Temp += pstADC->CLP4; + u16Temp += pstADC->CLPS; + u16Temp /= 2; + u16Temp |= 0x8000; + pstADC->PG = u16Temp; + + u16Temp = 0; + u16Temp += pstADC->CLM0; + u16Temp += pstADC->CLM1; + u16Temp += pstADC->CLM2; + u16Temp += pstADC->CLM3; + u16Temp += pstADC->CLM4; + u16Temp += pstADC->CLMS; + u16Temp /= 2; + u16Temp |= 0x8000; + pstADC->MG = u16Temp; + + ADCHA_u32Calibrated |= u32CalFlag; + } + } + else + { + pstADC->OFS = pstADCCalStruct->u32OFS; + pstADC->PG = pstADCCalStruct->u32PG; + pstADC->MG = pstADCCalStruct->u32MG; + } +#endif //BUILD_MK60 +#endif //ADC_CALIBRATE +} + +#ifdef ADC_CALIBRATE +static void ADCHA_vBackupCalibration(tstADCModule* pstADC, ADCHA_tstADCCalStruct* pstADCCalStruct) +{ +#if defined(BUILD_MK60) || defined(BUILD_MK64) + puint8 pu8ADCCalStruct = (puint8)pstADCCalStruct; + ADCHA_tstADCCalStruct stADCCalStruct; + uint16 u16CRC; + + stADCCalStruct.u32OFS = pstADC->OFS; + stADCCalStruct.u32PG = pstADC->PG; + stADCCalStruct.u32MG = pstADC->MG; + u16CRC = CRC16_u16CalcCRC(0xffff, pu8ADCCalStruct, sizeof(ADCHA_tstADCCalStruct) - sizeof(uint32)); + stADCCalStruct.u32CRC = (uint32)(u16CRC); + + FEE_boWriteNVM((puint8)&stADCCalStruct, (puint8)pstADCCalStruct, sizeof(ADCHA_tstADCCalStruct)); +#endif //BUILD_MK60 +} +#endif //ADC_CALIBRATE + +IOAPI_tenEHIOResource ADCHA_enGetResourceAndResult(ADCHA_tenADCModule enADCModule, tstADCModule* pstADC, uint32 u32ADCChannel, puint32 pu32ADCResult) +{ + IOAPI_tenEHIOResource enEHIOResource; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + /* Get the queue, channel and resource */ + //u32ADCChannel = ADC_SC1_ADCH_MASK & pstADC->SC1[0];//matthew check here against channel + enEHIOResource = ADCHA_raenIOResource[32 * enADCModule + u32ADCChannel]; + + /* Deactivate the AD module */ + pstADC->SC1[0] |= ADC_SC1_ADCH_MASK; + *pu32ADCResult = pstADC->R[0]; +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + /* Get the queue, channel and resource */ + enEHIOResource = ADCHA_raenIOResource[u32ADCChannel]; + *pu32ADCResult = pstADC->ADC_CDR[u32ADCChannel]; +#endif //BUILD_MK60 + return enEHIOResource; +} + +void ADCHA_vInitConversion(IOAPI_tenEHIOResource enIOResource, ADCHA_tstADCConversion* pstADCConversion, ADCAPI_tstADCCB* pstADCCB, uint32 u32QueueIDX) +{ +#if defined(BUILD_MK60) || defined (BUILD_MK64) + pstADCConversion->stADCChannel.enEHIOResource = enIOResource; + pstADCConversion->stADCChannel.enADCModule = ADCHA_rastADCChannel[enIOResource].enADCModule; + pstADCConversion->stADCChannel.u32ADChannel = ADCHA_rastADCChannel[enIOResource].u32ADChannel; + pstADCConversion->stADCChannel.enChannelAB = ADCHA_rastADCChannel[enIOResource].enChannelAB; + pstADCConversion->stADCChannel.boIsDiff = ADCHA_rastADCChannel[enIOResource].boIsDiff; + pstADCConversion->stADCChannel.u32Samples = pstADCCB->enSamplesAv; + pstADCConversion->pfResultCB = pstADCCB->pfResultCB; + pstADCConversion->u32ControlCount = 0; +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + pstADCConversion->stADCChannel.enEHIOResource = enIOResource; + pstADCConversion->stADCChannel.enADCModule = ADCHA_rastADCChannel[enIOResource].enADCModule; + pstADCConversion->stADCChannel.u32ADChannel = ADCHA_rastADCChannel[enIOResource].u32ADChannel; + pstADCConversion->stADCChannel.boIsDiff = ADCHA_rastADCChannel[enIOResource].boIsDiff; + pstADCConversion->pfResultCB = pstADCCB->pfResultCB; + pstADCConversion->u32ControlCount = 0; +#endif //BUILD_SAM3X8E +} + +static void ADCHA_vInitInterrupts(IRQn_Type enIrq) +{ + IRQ_vEnableIRQ(enIrq, IRQ_enPRIO_8, ADC_vInterruptHandler, NULL); +} + +bool ADCHA_boGetModuleBusy(ADCHA_tenADCModule enADCModule) +{ + bool boModuleBusy; + tstADCModule* pstADC = ADCHA_pstGetADCModule(enADCModule); + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + pstADC = ADCHA_pstGetADCModule(enADCModule); + boModuleBusy = (ADC_SC1_ADCH_MASK == (ADC_SC1_ADCH_MASK & pstADC->SC1[0])) ? FALSE : TRUE; +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + pstADC = ADCHA_pstGetADCModule(enADCModule); + boModuleBusy = ADCHA_aboModuleBusy[0]; +#endif //BUILD_SAM3X8E + + return boModuleBusy; +} + +void ADCHA_vClearModuleBusy(ADCHA_tenADCModule enADCModule) +{ + ADCHA_aboModuleBusy[enADCModule] = false; +} + +void ADCHA_vReset(ADCHA_tenADCModule enADCModule) +{ + ADCHA_aboModuleBusy[enADCModule] = false; +} + diff --git a/source/Peripherals/ADCHA.h b/source/Peripherals/ADCHA.h new file mode 100644 index 0000000..d0452e1 --- /dev/null +++ b/source/Peripherals/ADCHA.h @@ -0,0 +1,624 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: ADCHA Header File */ +/* DESCRIPTION: ADC Hardware Adaption */ +/* FILE NAME: ADC.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef ADCHA_H +#define ADCHA_H + +#include +#include "build.h" +#include "peradc.h" +#include "CPUAbstract.h" +#include "declarations.h" +#include "feeha.h" +#include "IOAPI.h" +#include "IRQ.h" +#include "SIM.h" + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +typedef ADC_Type tstADCModule; +#endif + +#ifdef BUILD_SAM3X8E +#include "pmc.h" +typedef Adc tstADCModule; +#endif + +#ifdef BUILD_SAM3X8E +#define ADCHA_nADCCLKFREQ 5000000u +#define ADCHA_nADCTRSTTIME 8u +#endif //BUILD_SAM3X8E + +#ifdef BUILD_MK60 +#define ADCHA_nReg32Set \ +{ \ + {(volatile uint32*)(ADC0_BASE + offsetof(ADC_Type, CFG1)), (uint32)(ADC_CFG1_MODE(1) + ADC_CFG1_ADICLK(1)+ ADC_CFG1_ADIV(1) + ADC_CFG1_ADLSMP_MASK), REGSET_enOverwrite}, \ + {(volatile uint32*)(ADC1_BASE + offsetof(ADC_Type, CFG1)), (uint32)(ADC_CFG1_MODE(1) + ADC_CFG1_ADICLK(1)+ ADC_CFG1_ADIV(1) + ADC_CFG1_ADLSMP_MASK), REGSET_enOverwrite}, \ + {(volatile uint32*)(ADC2_BASE + offsetof(ADC_Type, CFG1)), (uint32)(ADC_CFG1_MODE(1) + ADC_CFG1_ADICLK(1)+ ADC_CFG1_ADIV(1) + ADC_CFG1_ADLSMP_MASK), REGSET_enOverwrite}, \ + {(volatile uint32*)(ADC3_BASE + offsetof(ADC_Type, CFG1)), (uint32)(ADC_CFG1_MODE(1) + ADC_CFG1_ADICLK(1)+ ADC_CFG1_ADIV(1) + ADC_CFG1_ADLSMP_MASK), REGSET_enOverwrite}, \ + { NULL, 0, REGSET_enOverwrite } \ +} +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +#define ADCHA_nReg32Set \ +{ \ + {(volatile uint32*)(ADC0_BASE + offsetof(ADC_Type, CFG1)), (uint32)(ADC_CFG1_MODE(1) + ADC_CFG1_ADICLK(1) + ADC_CFG1_ADIV(1) + ADC_CFG1_ADLSMP_MASK), REGSET_enOverwrite}, \ + {(volatile uint32*)(ADC1_BASE + offsetof(ADC_Type, CFG1)), (uint32)(ADC_CFG1_MODE(1) + ADC_CFG1_ADICLK(1) + ADC_CFG1_ADIV(1) + ADC_CFG1_ADLSMP_MASK), REGSET_enOverwrite}, \ + { NULL, 0, REGSET_enOverwrite } \ +} +#endif //BUILD_MK64 + + +#ifdef BUILD_SAM3X8E +#define ADCHA_nReg32Set \ +{ \ + { NULL, 0, REGSET_enOverwrite } \ +} +#endif //BUILD_SAM3X8E + +#ifdef BUILD_MK60 +#define ADCHA_nChannelInfo \ +{ \ + {EH_IO_ADSE1, ADCHA_enADC1, 13, 0, ADCHA_enChannelA, false}, \ + {EH_IO_ADSE2, ADCHA_enADC1, 12, 0, ADCHA_enChannelA, false}, \ + {EH_IO_ADSE3, ADCHA_enADC1, 11, 0, ADCHA_enChannelA, false}, \ + {EH_IO_ADSE4, ADCHA_enADC1, 10, 0, ADCHA_enChannelA, false}, \ + {EH_IO_ADSE5, ADCHA_enADC1, 15, 0, ADCHA_enChannelA, false}, \ + {EH_IO_ADSE6, ADCHA_enADC1, 14, 0, ADCHA_enChannelA, false}, \ + {EH_IO_ADSE7, ADCHA_enADC1, 4, 0, ADCHA_enChannelB, false}, \ + {EH_IO_ADSE8, ADCHA_enADC1, 5, 0, ADCHA_enChannelB, false}, \ + {EH_IO_ADSE9, ADCHA_enADC1, 6, 0, ADCHA_enChannelB, false}, \ + {EH_IO_ADSE10, ADCHA_enADC1, 7, 0, ADCHA_enChannelB, false}, \ + {EH_IO_ADSE11, ADCHA_enADC2, 14, 0, ADCHA_enChannelA, false}, \ + {EH_IO_ADSE12, ADCHA_enADC2, 15, 0, ADCHA_enChannelA, false}, \ + {EH_IO_GPSE1, ADCHA_enADC0, 13, 0, ADCHA_enChannelA, false}, \ + {EH_IO_GPSE2, ADCHA_enADC0, 12, 0, ADCHA_enChannelA, false}, \ + {EH_IO_GPSE5, ADCHA_enADC3, 4, 0, ADCHA_enChannelB, false}, \ + {EH_IO_GPSE6, ADCHA_enADC3, 7, 0, ADCHA_enChannelB, false}, \ + {EH_IO_GPSE7, ADCHA_enADC3, 4, 0, ADCHA_enChannelA, false}, \ + {EH_IO_GPSE8, ADCHA_enADC3, 5, 0, ADCHA_enChannelA, false}, \ + {EH_IO_GPSE9, ADCHA_enADC0, 11, 0, ADCHA_enChannelA, false}, \ + {EH_IO_GPSE10, ADCHA_enADC0, 10, 0, ADCHA_enChannelA, false}, \ + {EH_I_ADD1, ADCHA_enADC2, 2, 0, ADCHA_enChannelA, true}, \ + {EH_I_ADD2, ADCHA_enADC2, 2, 0, ADCHA_enChannelA, true}, \ + {EH_I_ADD3, ADCHA_enADC3, 2, 0, ADCHA_enChannelA, true}, \ + {EH_I_ADD4, ADCHA_enADC3, 2, 0, ADCHA_enChannelA, true}, \ + {EH_I_ADD5, ADCHA_enADC0, 2, 0, ADCHA_enChannelA, true}, \ + {EH_I_ADD6, ADCHA_enADC0, 2, 0, ADCHA_enChannelA, true}, \ + {EH_I_ADD7, ADCHA_enADC1, 2, 0, ADCHA_enChannelA, true}, \ + {EH_I_ADD8, ADCHA_enADC1, 2, 0, ADCHA_enChannelA, true}, \ + {EH_IO_CAN2T, ADCHA_enADC0, 17, 0, ADCHA_enChannelA, false}, \ + {EH_IO_CAN2R, ADCHA_enADC0, 18, 0, ADCHA_enChannelA, false}, \ + {EH_I_CMP1, ADCHA_enADC1, 16, 0, ADCHA_enChannelA, false}, \ + {EH_I_CMP2, ADCHA_enADC0, 16, 0, ADCHA_enChannelA, false}, \ + {EH_I_CMP3, ADCHA_enADC1, 18, 0, ADCHA_enChannelA, false} \ +} +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +#define ADCHA_nChannelInfo \ +{ \ + {EH_IO_GPSE1, ADCHA_enADC1, 17, 0, ADCHA_enChannelA, false}, \ + {EH_IO_GPSE2, ADCHA_enADC0, 14, 0, ADCHA_enChannelA, false}, \ + {EH_IO_GPSE3, ADCHA_enADC0, 8, 0, ADCHA_enChannelA, false}, \ + {EH_IO_GPSE4, ADCHA_enADC0, 9, 0, ADCHA_enChannelA, false}, \ + {EH_IO_GPSE5, ADCHA_enADC0, 13, 0, ADCHA_enChannelA, false}, \ + {EH_IO_GPSE6, ADCHA_enADC0, 12, 0, ADCHA_enChannelA, false}, \ + {EH_IO_GPSE7, ADCHA_enADC1, 10, 0, ADCHA_enChannelA, false}, \ + {EH_IO_GPSE8, ADCHA_enADC1, 11, 0, ADCHA_enChannelA, false}, \ + {EH_I_ADD1, ADCHA_enADC1, 0, 0, ADCHA_enChannelA, true}, \ + {EH_I_ADD2, ADCHA_enADC1, 1, 0, ADCHA_enChannelA, true}, \ + {EH_I_CMP1, ADCHA_enADCInvalid, 0, 0, ADCHA_enChannelA, false}, \ + {EH_I_CMP2, ADCHA_enADCInvalid, 0, 0, ADCHA_enChannelA, false}, \ + {IO_AD_Count, ADCHA_enADCInvalid, 0u, TRUE, FALSE, FALSE}, \ + {EH_IO_CAN1T, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_CAN1R, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_UART1_TX, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_UART1_RX, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_UART1_CTS, ADCHA_enADC1, 15, 0, ADCHA_enChannelA, FALSE}, \ + {EH_IO_UART1_RTS, ADCHA_enADC1, 14, 0, ADCHA_enChannelA, FALSE}, \ + {EH_IO_UART2_TX, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_UART2_RX, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_SPI1_MISO, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_SPI1_MOSI, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_SPI1_CLK, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_SPI1_CS, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR1, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR2, ADCHA_enADC1, 6, 0, ADCHA_enChannelA, false}, \ + {EH_IO_TMR3, ADCHA_enADC1, 7, 0, ADCHA_enChannelB, false}, \ + {EH_IO_TMR4, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR5, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR6, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR7, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR8, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR9, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR10, ADCHA_enADC0, 6, 0, ADCHA_enChannelB, false}, \ + {EH_IO_TMR11, ADCHA_enADC0, 7, 0, ADCHA_enChannelB, false}, \ + {EH_IO_TMR12, ADCHA_enADC0, 5, 0, ADCHA_enChannelB, false}, \ + {EH_IO_TMR13, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR14, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_TMR15, ADCHA_enADC1, 4, 0, ADCHA_enChannelB, false}, \ + {EH_IO_TMR16, ADCHA_enADC0, 7, 0, ADCHA_enChannelB, false}, \ + {EH_IO_TMR17, ADCHA_enADC0, 15, 0, ADCHA_enChannelA, false}, \ + {EH_IO_TMR18, ADCHA_enADC0, 4, 0, ADCHA_enChannelB, false}, \ + {EH_IO_IIC1_SCL, ADCHA_enADC0, 17, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IIC1_SDA, ADCHA_enADC0, 18, 0, ADCHA_enChannelA, false}, \ + {EH_O_DAC1, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_O_DAC2, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_GP1, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_GP2, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_GP3, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_GP4, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_GP5, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_GP6, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_GP7, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_GP8, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_GP9, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_GP10, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_GP11, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_GP12, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_GP13, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE}, \ + {EH_IO_GP14, ADCHA_enADCInvalid, 0, FALSE, FALSE, FALSE} \ +} +#endif + +#if defined(BUILD_SAM3X8E) && defined(BUILD_ARDUINO_DUE) +#define ADCHA_nChannelInfo \ +{ \ + {EH_IO_ADD1, ADCHA_enADC0, 7, ADCHA_enChannelA, true}, \ + {EH_IO_ADD2, ADCHA_enADC0, 6, ADCHA_enChannelA, true}, \ + {EH_IO_ADD3, ADCHA_enADC0, 5, ADCHA_enChannelA, true}, \ + {EH_IO_ADD4, ADCHA_enADC0, 4, ADCHA_enChannelA, true}, \ + {EH_IO_ADD5, ADCHA_enADC0, 3, ADCHA_enChannelA, true}, \ + {EH_IO_ADD6, ADCHA_enADC0, 2, ADCHA_enChannelA, true}, \ + {EH_IO_ADD7, ADCHA_enADC0, 1, ADCHA_enChannelA, true}, \ + {EH_IO_ADD8, ADCHA_enADC0, 0, ADCHA_enChannelA, true}, \ + {EH_IO_ADD9, ADCHA_enADC0, 10, ADCHA_enChannelA, true}, \ + {EH_IO_ADD10, ADCHA_enADC0, 11, ADCHA_enChannelA, true}, \ + {EH_IO_ADD11, ADCHA_enADC0, 12, ADCHA_enChannelA, true}, \ + {EH_IO_ADD12, ADCHA_enADC0, 13, ADCHA_enChannelA, true}, \ + {EH_IO_DAC1, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_DAC2, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_CAN1R, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_CAN1T, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO22, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO23, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO24, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO25, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO26, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO27, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO28, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO29, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO30, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO31, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO32, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO33, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO34, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO35, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO36, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO37, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO38, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO39, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO40, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO41, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO42, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO43, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO44, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO45, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO46, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO47, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO48, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO49, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO50, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO51, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IO52, ADCHA_enADC0, 14, ADCHA_enChannelA, true}, \ + {EH_IO_IO53, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IIC1_SCL, ADCHA_enADC0, 9, ADCHA_enChannelA, true}, \ + {EH_IO_IIC1_SDA, ADCHA_enADC0, 8, ADCHA_enChannelA, true}, \ + {EH_IO_UART1_RX, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_UART1_TX, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_UART2_RX, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_UART2_TX, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_UART3_RX, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_UART3_TX, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_UART5_RX, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_UART5_TX, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_TMR1, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_TMR2, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_TMR3, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_TMR4, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_TMR5, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_TMR6, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_TMR7, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_TMR8, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_TMR9, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_TMR10, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_TMR11, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_TMR12, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IIC2_SDA, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false}, \ + {EH_IO_IIC2_SCL, ADCHA_enADCModuleInvalid, 0, ADCHA_enChannelA, false} \ +} +#endif //BUILD_SAM3X8E + +#ifdef BUILD_MK60 +#define ADCHA_nIOResourceMap \ +{ \ + EH_I_ADD5, \ + IO_Total_Count, \ + EH_I_ADD5, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + EH_IO_GPSE10, \ + EH_IO_GPSE9, \ + EH_IO_GPSE2, \ + EH_IO_GPSE1, \ + IO_Total_Count, \ + IO_Total_Count, \ + EH_I_CMP2, \ + EH_IO_CAN2T, \ + EH_IO_CAN2R, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + EH_I_ADD7, \ + IO_Total_Count, \ + EH_I_ADD7, \ + IO_Total_Count, \ + EH_IO_ADSE7, \ + EH_IO_ADSE8, \ + EH_IO_ADSE9, \ + EH_IO_ADSE10, \ + IO_Total_Count, \ + IO_Total_Count, \ + EH_IO_ADSE4, \ + EH_IO_ADSE3, \ + EH_IO_ADSE2, \ + EH_IO_ADSE1, \ + EH_IO_ADSE6, \ + EH_IO_ADSE5, \ + EH_I_CMP1, \ + IO_Total_Count, \ + EH_I_CMP3, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + EH_I_ADD1, \ + IO_Total_Count, \ + EH_I_ADD1, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + EH_IO_ADSE11, \ + EH_IO_ADSE12, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + EH_I_ADD3, \ + IO_Total_Count, \ + EH_I_ADD3, \ + EH_I_ADD2, \ + EH_IO_GPSE7, \ + EH_IO_GPSE8, \ + IO_Total_Count, \ + EH_IO_GPSE6 \ +} +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +#define ADCHA_nIOResourceMap \ +{ \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + EH_IO_TMR18, \ + EH_IO_TMR12, \ + EH_IO_TMR10, \ + EH_IO_TMR11, \ + EH_IO_GPSE3, \ + EH_IO_GPSE4, \ + IO_Total_Count, \ + IO_Total_Count, \ + EH_IO_GPSE6, \ + EH_IO_GPSE5, \ + EH_IO_GPSE2, \ + EH_IO_TMR17, \ + EH_I_CMP1, \ + EH_IO_IIC1_SCL, \ + EH_IO_IIC1_SDA, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + EH_I_ADD1, \ + EH_I_ADD2, \ + IO_Total_Count, \ + IO_Total_Count, \ + EH_IO_TMR15, \ + EH_IO_TMR16, \ + EH_IO_TMR2, \ + EH_IO_TMR3, \ + IO_Total_Count, \ + IO_Total_Count, \ + EH_IO_GPSE7, \ + EH_IO_GPSE8, \ + EH_IO_GPSE2, \ + IO_Total_Count, \ + EH_IO_UART1_RTS, \ + EH_IO_UART1_CTS, \ + IO_Total_Count, \ + EH_IO_GPSE1, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ + IO_Total_Count, \ +} +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +#define ADCHA_nIOResourceMap \ +{ \ + EH_IO_ADD8, \ + EH_IO_ADD7, \ + EH_IO_ADD6, \ + EH_IO_ADD5, \ + EH_IO_ADD4, \ + EH_IO_ADD3, \ + EH_IO_ADD2, \ + EH_IO_ADD1, \ + EH_IO_IIC1_SDA, \ + EH_IO_IIC1_SCL, \ + EH_IO_ADD9, \ + EH_IO_ADD10, \ + EH_IO_ADD11, \ + EH_IO_ADD12, \ + EH_IO_IO52, \ + IO_Total_Count \ +} +#endif //BUILD_SAM3X8E + + +#ifdef BUILD_MK60 +#define ADCHA_xInitialise(x, y) \ +ADCHA_xRequestPortClock(x); \ +ADHAC_xCalibrate(x); \ +ADCHA_xInitInterrupts(x, y); +#define ADC_xRequestPortClock(x) \ +if (ADC0 == x){SIM_vSetReg32(SIM_SCGC6, SIM_SCGC6_ADC0_MASK);ADCHA_u32PortClockRequested |= 1;} \ +if (ADC1 == x){SIM_vSetReg32(SIM_SCGC3, SIM_SCGC3_ADC1_MASK);ADCHA_u32PortClockRequested |= 2;} \ +if (ADC2 == x){SIM_vSetReg32(SIM_SCGC6, SIM_SCGC6_ADC2_MASK);ADCHA_u32PortClockRequested |= 4;} \ +if (ADC3 == x){SIM_vSetReg32(SIM_SCGC3, SIM_SCGC3_ADC3_MASK);ADCHA_u32PortClockRequested |= 8;} \ +#define ADC_xCalibrate(x) \ +if (ADC0 == x){ADC_vCalibrate(ADC0, 0, 1);} \ +if (ADC1 == x){ADC_vCalibrate(ADC1, 1, 2);} \ +if (ADC2 == x){ADC_vCalibrate(ADC2, 2, 4);} \ +if (ADC3 == x){ADC_vCalibrate(ADC3, 3, 8);} \ +#define ADC_xInitInterrupts(x, y) \ +if (ADC0 == x){ADC_vInitInterrupts(y);} \ +if (ADC1 == x){ADC_vInitInterrupts(y);} \ +if (ADC2 == x){ADC_vInitInterrupts(y);} \ +if (ADC3 == x){ADC_vInitInterrupts(y);} +#endif + +#ifdef BUILD_MK64 +#define ADCHA_xInitialise(x, y) \ +ADCHA_xRequestPortClock(x); \ +ADCHA_xCalibrate(x); \ +ADCHA_xInitInterrupts(x, y); + + +#define ADCHA_xRequestPortClock(x)\ +if ((ADC0 == x) && (0 == (ADCHA_u32PortClockRequested & 1))){SIM_vSetReg32(SIM_SCGC6, SIM_SCGC6_ADC0_MASK);ADCHA_u32PortClockRequested |= 1;}\ +if ((ADC1 == x) && (0 == (ADCHA_u32PortClockRequested & 2))){SIM_vSetReg32(SIM_SCGC3, SIM_SCGC3_ADC1_MASK);ADCHA_u32PortClockRequested |= 2;} + + +#define ADCHA_xCalibrate(x) \ +if (ADC0 == x){ADCHA_vCalibrate(ADC0, 0, 1);}\ +if (ADC1 == x){ADCHA_vCalibrate(ADC1, 1, 2);} + + +#define ADCHA_xInitInterrupts(x, y) \ +if (ADC0 == x){ADCHA_vInitInterrupts(y);} \ +if (ADC1 == x){ADCHA_vInitInterrupts(y);} +#endif //BUILD MK64 + + + +#ifdef BUILD_SAM3X8E +#define ADCHA_xInitialise(x, y) +#endif //BUILD_SAM3X8E + +#ifdef BUILD_MK60 +typedef enum +{ + ADCHA_enADC0, + ADCHA_enADC1, + ADCHA_enADC2, + ADCHA_enADC3, + ADCHA_enADCModuleCount +} ADCHA_tenADCModule; +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +typedef enum +{ + ADCHA_enADC0, + ADCHA_enADC1, + ADCHA_enADCModuleCount, + ADCHA_enADCInvalid +} ADCHA_tenADCModule; +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +typedef enum +{ + ADCHA_enADC0, + ADCHA_enADCModuleCount, + ADCHA_enADCModuleInvalid +} ADCHA_tenADCModule; +#endif //BUILD_SAM3X8E + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +typedef enum +{ + ADCHA_enChannelA = 0, + ADCHA_enChannelB = 1, + ADCHA_enChannelCount +} ADCHA_tenChannelAB; +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E +typedef enum +{ + ADCHA_enChannelA = 0, + ADCHA_enChannelCount +} ADCHA_tenChannelAB; +#endif //BUILD_SAM3X8E + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +typedef struct +{ + IOAPI_tenEHIOResource enEHIOResource; + ADCHA_tenADCModule enADCModule; + uint32 u32ADChannel; + uint32 u32Samples; + ADCHA_tenChannelAB enChannelAB; + bool boIsDiff; +} ADCHA_tstADCChannel; +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E +typedef struct +{ + IOAPI_tenEHIOResource enEHIOResource; + ADCHA_tenADCModule enADCModule; + uint32 u32ADChannel; + bool boIsDiff; +} ADCHA_tstADCChannel; +#endif//BUILD_SAM3X8E + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +typedef struct +{ + uint32 u32OFS; + uint32 u32PG; + uint32 u32MG; + uint32 u32CRC; +} ADCHA_tstADCCalStruct; +#endif //BUILD_MK60 + +#ifdef BUILD_SAM3X8E +typedef struct +{ + uint32 u32Dummy; +} ADCHA_tstADCCalStruct; +#endif //BUILD_SAM3X8E + +typedef struct +{ + uint32 u32ResetCount; + uint32 u32ControlCount; + ADCHA_tstADCChannel stADCChannel; + ADCAPI_tpfResultCB pfResultCB; +} ADCHA_tstADCConversion; + +typedef enum +{ + ADCHA_enQueueCyclic, + ADCHA_enQueueTriggered1, + ADCHA_enQueueTriggered2, + ADCHA_enQueueTriggered3, + ADCHA_enQueueTriggered4, + ADCHA_enQueueCount +} ADCHA_tenQueue; + +void ADCHA_vStart(uint32* const); +bool ADCHA_boBackupCalibrations(void); +void ADCHA_vInitADCResourcePGA(ADCHA_tstADCConversion*); +void ADCHA_vTerminate(uint32* const); +bool ADCHA_boInitiateConversion(ADCHA_tstADCConversion*, ADCHA_tenQueue, uint32, bool); +IOAPI_tenEHIOResource ADCHA_enGetResourceAndResult(ADCHA_tenADCModule, tstADCModule*, uint32, puint32); +void ADCHA_vCalibrate(tstADCModule*, uint32, uint32); +void ADCHA_vInitConversion(IOAPI_tenEHIOResource, ADCHA_tstADCConversion*, ADCAPI_tstADCCB*, uint32); +bool ADCHA_boGetModuleBusy(ADCHA_tenADCModule); +void ADCHA_vInitChannel(IOAPI_tenEHIOResource); +tstADCModule* ADCHA_pstGetADCModule(ADCHA_tenADCModule); +uint32 ADCHA_u32GetAvailableResultCount(tstADCModule*); +void ADCHA_vClearModuleBusy(ADCHA_tenADCModule); +void ADCHA_vReset(ADCHA_tenADCModule enADCModule); + +#endif //ADCHA_H + diff --git a/source/Peripherals/CANHA.c b/source/Peripherals/CANHA.c new file mode 100644 index 0000000..58f7403 --- /dev/null +++ b/source/Peripherals/CANHA.c @@ -0,0 +1,544 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: CAN Hardware Abstraction */ +/* DESCRIPTION: This code provides functions for interacting with */ +/* the CAN hardware module/s */ +/* FILE NAME: CANHA.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include +#include "build.h" +#include "percan.h" +#include "macros.h" +#include "PERCAN.h" + +const CANHA_tstTimingSettings CANHA_astTimingSettings[] = CANHA_nSetTimingData; + +static sint32 CANHA_u32GetCANIndex(IOAPI_tenEHIOResource); + +#define CANHA_nTimingOptionsCount (sizeof(CANHA_astTimingSettings) / sizeof(CANHA_tstTimingSettings)) + +void CANHA_vStart(uint32* const u32Stat) +{ + + +} + +uint32 CANHA_u32InitBus(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tstPortConfigCB* pstPortConfigCB) +{ + tstCANModule* pstCAN; + IRQn_Type nCANIRQ; + sint32 i32IDX = CANHA_u32GetCANIndex(enEHIOResource); + uint32 u32MuxSel = ~0ul; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + REGSET_tstReg32Val astCANReg32Val[54]; + uint8 u8RegIDX = 0; + uint8 u8TimingIDX; + uint8 u8PRESDIV; + uint8 u8SJW = 3; + uint8 u8TSEG1 = 15; + uint8 u8TSEG2 = 7; + uint8 u8MBXIDX; + + + if ((-1 != i32IDX) && (TRUE == DLL_boInitDLLChannel(enEHIOResource, pstPortConfigCB))) + { + switch (enEHIOResource) + { + case EH_VIO_CAN1: + { + pstCAN = (CAN_Type*)CAN0_BASE; + nCANIRQ = CAN0_ORed_Message_buffer_IRQn; + /* turn on FLEXCAN1 clock */ + SIM_vSetReg32(SIM_SCGC6, SIM_SCGC6_FLEXCAN0_MASK); + break; + } +#ifdef BUILD_MK60 + case EH_VIO_CAN2: + { + pstCAN = (CAN_Type*)CAN1_BASE; + nCANIRQ = CAN1_ORed_Message_buffer_IRQn; + /* turn on FLEXCAN2 clock */ + SIM_vSetReg32(SIM_SCGC3, SIM_SCGC3_FLEXCAN1_MASK); + + break; + } +#endif + default: + { + pstCAN = NULL; + break; + } + } + + if (NULL != pstCAN) + { + for (u8TimingIDX = 0; u8TimingIDX < CANHA_nTimingOptionsCount; u8TimingIDX++) + { + if (CANHA_astTimingSettings[u8TimingIDX].u32BitRate == pstPortConfigCB->u32BaudRateHz) + { + u8PRESDIV = CANHA_astTimingSettings[u8TimingIDX].u8PRESDIV; + u8SJW = CANHA_astTimingSettings[u8TimingIDX].u8SJW; + u8TSEG1 = CANHA_astTimingSettings[u8TimingIDX].u8TSEG1; + u8TSEG2 = CANHA_astTimingSettings[u8TimingIDX].u8TSEG2; + break; + } + } + + pstCAN -> MCR &= ~CAN_MCR_MDIS_MASK; + pstCAN -> MCR |= CAN_MCR_SOFTRST_MASK; + while(pstCAN -> MCR & CAN_MCR_SOFTRST_MASK); + + pstCAN -> MCR |= CAN_MCR_FRZ_MASK; + pstCAN -> MCR |= CAN_MCR_HALT_MASK; + pstCAN -> MCR |= CAN_MCR_IRMQ_MASK; + while(!(pstCAN -> MCR & CAN_MCR_FRZACK_MASK)); + + astCANReg32Val[u8RegIDX].reg = (volatile uint32*)((uint32)pstCAN + (uint32)offsetof(CAN_Type, CTRL1)); + astCANReg32Val[u8RegIDX].val = CAN_CTRL1_PRESDIV(u8PRESDIV) + + CAN_CTRL1_PSEG1(u8TSEG1) + + CAN_CTRL1_PSEG2(u8TSEG2) + + CAN_CTRL1_RJW(u8SJW); + astCANReg32Val[u8RegIDX++].writeMode = REGSET_enOverwrite; + + /* Set the MBX RX CS fields */ + for (u8MBXIDX = 0; u8MBXIDX < CAN_nCANRXMailboxCount; u8MBXIDX++) + { + astCANReg32Val[u8RegIDX].reg = (volatile uint32*)((uint32)pstCAN + (uint32)offsetof(CAN_Type, MB[u8MBXIDX].CS)); + astCANReg32Val[u8RegIDX].val = CAN_CS_CODE(CAN_nCANMBXEmpty); + astCANReg32Val[u8RegIDX++].writeMode = REGSET_enOverwrite; + } + + /* Set the MBX TX CS fields */ + for (u8MBXIDX = CAN_nCANRXMailboxCount; u8MBXIDX < CAN_nCANMailboxCount; u8MBXIDX++) + { + astCANReg32Val[u8RegIDX].reg = (volatile uint32*)((uint32)pstCAN + (uint32)offsetof(CAN_Type, MB[u8MBXIDX].CS)); + astCANReg32Val[u8RegIDX].val = CAN_CS_CODE(CAN_nCANMBXInactive2); + astCANReg32Val[u8RegIDX++].writeMode = REGSET_enOverwrite; + } + + /* Set the global diag and diag MB ID fields */ + astCANReg32Val[u8RegIDX].reg = (volatile uint32*)((uint32)pstCAN + (uint32)offsetof(CAN_Type, MB[0].ID)); + astCANReg32Val[u8RegIDX].val = CAN_ID_STD(pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32GlobalCANDiagAddress) + | CAN_ID_PRIO(0); + astCANReg32Val[u8RegIDX++].writeMode = REGSET_enOverwrite; + astCANReg32Val[u8RegIDX].reg = (volatile uint32*)((uint32)pstCAN + (uint32)offsetof(CAN_Type, MB[1].ID)); + astCANReg32Val[u8RegIDX].val = CAN_ID_STD(pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32CANDiagAddress) + | CAN_ID_PRIO(0); + astCANReg32Val[u8RegIDX++].writeMode = REGSET_enOverwrite; + + /* Set the global diag and diag ID mask fields */ + astCANReg32Val[u8RegIDX].reg = (volatile uint32*)((uint32)pstCAN + (uint32)offsetof(CAN_Type, RXIMR[0])); + astCANReg32Val[u8RegIDX].val = 0x7ff << CAN_ID_STD_SHIFT; + astCANReg32Val[u8RegIDX++].writeMode = REGSET_enOverwrite; + astCANReg32Val[u8RegIDX].reg = (volatile uint32*)((uint32)pstCAN + (uint32)offsetof(CAN_Type, RXIMR[1])); + astCANReg32Val[u8RegIDX].val = 0x7ff << CAN_ID_STD_SHIFT; + astCANReg32Val[u8RegIDX++].writeMode = REGSET_enOverwrite; + + /* Set the priority MB ID fields */ + for (u8MBXIDX = 2; u8MBXIDX < 6; u8MBXIDX++) + { + astCANReg32Val[u8RegIDX].reg = (volatile uint32*)((uint32)pstCAN + (uint32)offsetof(CAN_Type, MB[u8MBXIDX].ID)); + + if (0x800u > pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityAddress[u8MBXIDX - 2]) + { + astCANReg32Val[u8RegIDX].val = CAN_ID_STD(pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityAddress[u8MBXIDX - 2]) + | CAN_ID_PRIO(0); + } + else + { + astCANReg32Val[u8RegIDX].val = CAN_ID_EXT(pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityAddress[u8MBXIDX - 2]) + | CAN_ID_PRIO(0); + } + astCANReg32Val[u8RegIDX++].writeMode = REGSET_enOverwrite; + } + + /* Set the priority ID mask fields */ + for (u8MBXIDX = 2; u8MBXIDX < 6; u8MBXIDX++) + { + astCANReg32Val[u8RegIDX].reg = (volatile uint32*)((uint32)pstCAN + (uint32)offsetof(CAN_Type, RXIMR[u8MBXIDX])); + + if (0x800u > pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityAddress[u8MBXIDX - 2]) + { + astCANReg32Val[u8RegIDX].val = pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityMask[u8MBXIDX - 2] << CAN_ID_STD_SHIFT; + } + else + { + astCANReg32Val[u8RegIDX].val = pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityMask[u8MBXIDX - 2] << CAN_ID_EXT_SHIFT; + } + astCANReg32Val[u8RegIDX++].writeMode = REGSET_enOverwrite; + } + + /* Clear remaining MB ID fields */ + for (u8MBXIDX = 6; u8MBXIDX < 16; u8MBXIDX++) + { + astCANReg32Val[u8RegIDX].reg = (volatile uint32*)((uint32)pstCAN + (uint32)offsetof(CAN_Type, MB[u8MBXIDX].ID)); + astCANReg32Val[u8RegIDX].val = 0u; + astCANReg32Val[u8RegIDX++].writeMode = REGSET_enOverwrite; + } + + /* Clear the remaining ID mask fields */ + for (u8MBXIDX = 6; u8MBXIDX < 16; u8MBXIDX++) + { + astCANReg32Val[u8RegIDX].reg = (volatile uint32*)((uint32)pstCAN + (uint32)offsetof(CAN_Type, RXIMR[u8MBXIDX])); + astCANReg32Val[u8RegIDX].val = 0u; + astCANReg32Val[u8RegIDX++].writeMode = REGSET_enOverwrite; + } + + astCANReg32Val[u8RegIDX].reg = NULL; + REGSET_vInitReg32(&astCANReg32Val[0]); + + pstCAN -> MCR &= ~CAN_MCR_HALT_MASK; + while((pstCAN -> MCR) & CAN_MCR_FRZACK_MASK); + + IRQ_vEnableIRQ(nCANIRQ, IRQ_enPRIO_15, CAN_vInterrupt, NULL); + pstCAN -> IMASK1 = 0x00000FFF; + + u32MuxSel = 2; + } + } +#endif + +#ifdef BUILD_SAM3X8E + can_mb_conf_t stMBConfig; + + if ((-1 != i32IDX) && (TRUE == DLL_boInitDLLChannel(enEHIOResource, pstPortConfigCB))) + { + switch (enEHIOResource) + { + case EH_VIO_CAN1: + { + pstCAN = (tstCANModule*)CAN0; + nCANIRQ = CAN0_IRQn; + break; + } + case EH_VIO_CAN2: + { + pstCAN = (tstCANModule*)CAN1; + nCANIRQ = CAN1_IRQn; + break; + } + default: + { + pstCAN = NULL; + break; + } + } + + if (NULL != pstCAN) + { + /* turn on peripheral clock */ + SIM_boEnablePeripheralClock(nCANIRQ); + can_init(pstCAN, SYS_FREQ_BUS, pstPortConfigCB->u32BaudRateHz / 1000u); + + stMBConfig.ul_mb_idx = 0; + stMBConfig.uc_obj_type = CAN_MB_TYPE_RX; + stMBConfig.uc_id_ver = pstPortConfigCB->enLLProtocol == PROTAPI_enLLCAN11 ? 0 : 1; + stMBConfig.uc_length = 8; + stMBConfig.uc_tx_prio = 0; + stMBConfig.ul_status = 0; + + if (pstPortConfigCB->enLLProtocol == PROTAPI_enLLCAN11) + { + stMBConfig.ul_id_msk = 0x7ff; + } + else + { + stMBConfig.ul_id_msk = 0x7ffffff; + } + + stMBConfig.ul_id = pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32CANDiagAddress; + stMBConfig.ul_fid = 0; + stMBConfig.ul_datal = 0; + stMBConfig.ul_datah = 0; + can_mailbox_init(pstCAN, &stMBConfig); + + stMBConfig.ul_mb_idx++;//1 + stMBConfig.ul_id = pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32GlobalCANDiagAddress; + can_mailbox_init(pstCAN, &stMBConfig); + + stMBConfig.ul_mb_idx++;//2 + stMBConfig.ul_id_msk = pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityMask[0]; + stMBConfig.ul_id = pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityAddress[0]; + can_mailbox_init(pstCAN, &stMBConfig); + + stMBConfig.ul_mb_idx++;//3 + stMBConfig.ul_id_msk = pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityMask[1]; + stMBConfig.ul_id = pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityAddress[1]; + can_mailbox_init(pstCAN, &stMBConfig); + + stMBConfig.ul_mb_idx++;//4 + stMBConfig.ul_id_msk = pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityMask[2]; + stMBConfig.ul_id = pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityAddress[2]; + can_mailbox_init(pstCAN, &stMBConfig); + + stMBConfig.ul_mb_idx++;//5 + stMBConfig.ul_id_msk = pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityMask[3]; + stMBConfig.ul_id = pstPortConfigCB->stNetConfig.uNetInfo.stCANNetInfo.u32CANPriorityAddress[3]; + can_mailbox_init(pstCAN, &stMBConfig); + + stMBConfig.ul_mb_idx++;//6 + stMBConfig.uc_obj_type = CAN_MB_TYPE_TX; + stMBConfig.ul_id_msk = 0; + stMBConfig.ul_id = 0; + can_mailbox_init(pstCAN, &stMBConfig); + + stMBConfig.ul_mb_idx++;//7 + can_mailbox_init(pstCAN, &stMBConfig); + + can_enable_interrupt(pstCAN, 0x3f); + IRQ_vEnableIRQ(nCANIRQ, IRQ_enPRIO_15, CAN_vInterrupt, NULL); + u32MuxSel = 0; + } + } +#endif //BUILD SAM3X8E + + return u32MuxSel; +} + +void CANHA_vRun(uint32* const u32Stat) +{ + +} + +void CANHA_vInterrupt(IOAPI_tenEHIOResource enEHIOResource) +{ + CANHA_tstCANMB stCANMB; + tstCANModule* pstCAN; + uint32 u32MailboxReadCount = CAN_nCANRXMailboxCount; + + switch (enEHIOResource) + { + case EH_VIO_CAN1: + { + pstCAN = CAN0; + break; + } +#ifdef BUILD_MK60 + case EH_VIO_CAN2: + { + pstCAN = CAN1; + break; + } +#endif //BUILD_MK64 + default: + { + pstCAN = NULL; + } + } + + if (NULL != pstCAN) + { + bool boReadOK = TRUE; + + while ((TRUE == boReadOK) && (0 < u32MailboxReadCount)) + { + boReadOK = CANHA_boReadMB(pstCAN, &stCANMB); + + if (TRUE == boReadOK) + { + DLL_vFrameRXCB(enEHIOResource, (puint8)&stCANMB); + } + + u32MailboxReadCount--; + } + } +} + +void CANHA_vInitTransfer(IOAPI_tstTransferCB* pstTransferCB) +{ + tstCANModule* pstCAN = NULL; + PROTAPI_tstCANMsg* pstCANMsg; + + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + CANHA_tstCANMB* pstCANMB; + + uint32 u32MBXIDX; + + switch (pstTransferCB->enEHIOResource) + { + case EH_VIO_CAN1: + { + pstCAN = (CAN_Type*)CAN0_BASE; + break; + } +#ifdef BUILD_MK60 + case EH_VIO_CAN2: + { + pstCAN = (CAN_Type*)CAN1_BASE; + break; + } +#endif //BUILD_MK60 + default: + { + break; + } + } + + if (NULL != pstCAN) + { + for (u32MBXIDX = CAN_nCANRXMailboxCount; u32MBXIDX < CAN_nCANMailboxCount; u32MBXIDX++) + { + if (CAN_nCANMBXInactive2 == ((pstCAN->MB[u32MBXIDX].CS & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT)) + { + pstCANMB = (CANHA_tstCANMB*)&pstCAN->MB[u32MBXIDX]; + + /* Data must be CAN frame so cast the pointer */ + pstCANMsg = (PROTAPI_tstCANMsg*)pstTransferCB->pvData; + + if (0x800u > pstCANMsg->u32ID) + { + pstCANMB->u32ID = CAN_ID_STD(pstCANMsg->u32ID) + | CAN_ID_PRIO(0); + } + else + { + pstCANMB->u32ID = CAN_ID_EXT(pstCANMsg->u32ID) + | CAN_ID_PRIO(0); + } + + pstCANMB->u32DWH = pstCANMsg->u32DWH; + pstCANMB->u32DWL = pstCANMsg->u32DWL; + pstCANMB->u32CS = CAN_CS_CODE(CAN_nCANMBXData) | + CAN_CS_DLC(pstCANMsg->u8DLC); + break; + } + } + } +#endif + +#ifdef BUILD_SAM3X8E + uint32 u32MBIDX; + + switch (pstTransferCB->enEHIOResource) + { + case EH_VIO_CAN1: + { + pstCAN = CAN0; + break; + } + case EH_VIO_CAN2: + { + pstCAN = CAN1; + break; + } + default: + { + pstCAN = NULL; + break; + } + } + + if (NULL != pstCAN) + { + /* Data must be CAN frame so cast the pointer */ + pstCANMsg = (PROTAPI_tstCANMsg*)pstTransferCB->pvData; + (void)CANHA_boWriteMB(pstCAN, pstCANMsg); + } +#endif + + +} + +bool CANHA_boReadMB(tstCANModule* pstCAN, CANHA_tstCANMB* pstCANMB) +{ + bool boReadOK = false; + uint8 u8MBXIDX; + uint32 u32MBXMask; + +#ifdef BUILD_SAM3X8E + can_mb_conf_t mailbox; + + uint8 u32MBMask = 1; + uint32 u32TempSource; + uint32 u32TempDest; + + + while (u8MBIDX < 8) + { + if (0 < (u32MBMask & (pstCAN->CAN_SR))) + { + break; + } + u32MBMask *= 2; + u8MBIDX++; + } + + if (u8MBIDX < 8) + { + mailbox.ul_mb_idx = u8MBIDX; + mailbox.ul_status = pstCAN->CAN_MB[u8MBIDX].CAN_MSR; + + can_mailbox_read(pstCAN, &mailbox); + + pstCANMB->u32ID = mailbox.ul_fid; + + u32TempSource = mailbox.ul_datal; + u32TempDest = HTONL(u32TempSource); + pstCANMB->u32DWH = u32TempDest; + + u32TempSource = mailbox.ul_datah; + u32TempDest = HTONL(u32TempSource); + pstCANMB->u32DWL = u32TempDest; + + boReadOK = true; + } +#endif //BUILD_SAM3X8E + +#ifdef BUILD_MK64 + u32MBXMask = 1; + + for (u8MBXIDX = 0; u8MBXIDX < CAN_nCANRXMailboxCount; u8MBXIDX++) + { + if (CAN_nCANMBXFull == ((pstCAN->MB[u8MBXIDX].CS & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) && + (0 != (u32MBXMask & pstCAN->IFLAG1))) + { + boReadOK = true; + pstCANMB->u32CS = pstCAN->MB[u8MBXIDX].CS; + pstCANMB->u32ID = pstCAN->MB[u8MBXIDX].ID; + pstCANMB->u32DWH = pstCAN->MB[u8MBXIDX].WORD0; + pstCANMB->u32DWL = pstCAN->MB[u8MBXIDX].WORD1; + pstCAN->IFLAG1 = u32MBXMask; + break; + } + + u32MBXMask *= 2; + } +#endif //BUILD_SAM3X8E + + return boReadOK; +} + + +void CANHA_vTerminate(uint32* const u32Stat) +{ + +} + +static sint32 CANHA_u32GetCANIndex(IOAPI_tenEHIOResource enEHIOResource) +{ + sint32 i32IDX = -1; +#ifdef BUILD_MK60 + if ((EH_VIO_CAN1 <= enEHIOResource) && (EH_VIO_CAN2 >= enEHIOResource)) +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 + if (EH_VIO_CAN1 <= enEHIOResource) +#endif //BUILD_MK64 + { + i32IDX = enEHIOResource - EH_VIO_CAN1; + } + + return i32IDX; +} + + + + diff --git a/source/Peripherals/CANHA.h b/source/Peripherals/CANHA.h new file mode 100644 index 0000000..f2ff88a --- /dev/null +++ b/source/Peripherals/CANHA.h @@ -0,0 +1,135 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: CANHA Header File */ +/* DESCRIPTION: CAN Hardware Adaption */ +/* FILE NAME: CANHA.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef CANHA_H +#define CANHA_H + +#include "types.h" +#include "IOAPI.h" +#include "SYSAPI.h" + +#define CANHA_nSetTimingData \ +{ \ + { 33333, 59, 10, 7, 2 }, \ + { 50000, 58, 7, 7, 2 }, \ + { 62500, 49, 7, 6, 2 }, \ + { 83333, 49, 5, 4, 2 }, \ + { 100000, 49, 4, 3, 2 }, \ + { 125000, 24, 7, 6, 2 }, \ + { 250000, 9, 10, 7, 2 }, \ + { 500000, 3, 3, 1, 1 }, \ + { 1000000, 4, 6, 1, 1 } \ +} + + +#define CAN_nCANModules 2 +#define CAN_nInRingBuffSize 16u +#define CAN_nCANMailboxCount 16u +#define CAN_nCANRXMailboxCount 12u + + +#define CAN_nCANMBXInactive1 0x00 +#define CAN_nCANMBXBusy 0x01 +#define CAN_nCANMBXFull 0x02 +#define CAN_nCANMBXEmpty 0x04 +#define CAN_nCANMBXOverrun 0x06 +#define CAN_nCANMBXInactive2 0x08 +#define CAN_nCANMBXAbort 0x09 +#define CAN_nCANMBXRAnswer 0x0A +#define CAN_nCANMBXData 0x0C +#define CAN_nCANMBXTAnswer 0x0E + +#define CANHA_nCANIDSTDSHIFT 18 + +typedef struct +{ + uint32 u32BitRate; + uint8 u8PRESDIV; + uint8 u8TSEG1; + uint8 u8TSEG2; + uint8 u8SJW; +} CANHA_tstTimingSettings; + +typedef struct +{ + uint32 biTimestamp : 16; + uint32 biDLC : 4; + uint32 biRTR : 1; + uint32 biIDE : 1; + uint32 biSRR : 1; + uint32 biCAN : 1; + uint32 biTimestampHighNibble : 4; + uint32 biChannel : 4; +} CANHA_tstCANCS; + +#ifdef BUILD_MK60 +typedef struct +{ + uint32 u32CS; + uint32 u32ID; + uint32 u32DWH; + uint32 u32DWL; +} CANHA_tstCANMB; +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +typedef struct +{ + uint32 u32CS; + uint32 u32ID; + uint32 u32DWH; + uint32 u32DWL; +} CANHA_tstCANMB; +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +typedef struct +{ + uint32 u32MR; + uint32 u32AM; + uint32 u32ID; + uint32 u32FID; + uint32 u32CS; + uint32 u32DWL; + uint32 u32DWH; + uint32 u32CR; +} CANHA_tstCANMB; +#endif //BUILD_SAM3X8E + + +#ifdef BUILD_MK60 +#include "mk60f12.h" +typedef CAN_Type tstCANModule; +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +#include "mk64f12.h" +typedef CAN_Type tstCANModule; +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +#include "sam3xa.h" +typedef Can tstCANModule; +#define CAN_MB_TYPE_NDIS 0 +#define CAN_MB_TYPE_RX 1 +#define CAN_MB_TYPE_TX 3 +#endif + +void CANHA_vStart(uint32* const); +void CANHA_vRun(uint32* const); +void CANHA_vTerminate(uint32* const); +void CANHA_vInitTransfer(IOAPI_tstTransferCB*); +uint32 CANHA_u32InitBus(IOAPI_tenEHIOResource, IOAPI_tstPortConfigCB*); +bool CANHA_boReadMB(tstCANModule*, CANHA_tstCANMB*); +void CANHA_vInterrupt(IOAPI_tenEHIOResource); + +#endif //CANHA_H + diff --git a/source/Peripherals/CRC16.c b/source/Peripherals/CRC16.c new file mode 100644 index 0000000..ffc34dc --- /dev/null +++ b/source/Peripherals/CRC16.c @@ -0,0 +1,48 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: CRC16 */ +/* DESCRIPTION: This code provides CRC16 functions */ +/* */ +/* FILE NAME: CRC16.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#include "mk64f12.h" +#include "SIM.h" +#ifdef KERNEL + +#include "CRC16.h" +#include + + +void CRC16_vStart(uint32* const u32Stat) +{ + CRC16HA_vStart(u32Stat); +} + +void CRC16_vRun(uint32* const u32Stat) +{ + +} + +void CRC16_vTerminate(uint32* const u32Stat) +{ + +} + +uint16 CRC16_u16CalcCRC(uint16 u16CRC, uint8* pu8Data, uint16 u16Len) +{ + return CRC16HA_u16CalcCRC(u16CRC, pu8Data, u16Len); +} + +puint16 CRC16_pu16CalcCRC(uint16 u16CRC, uint8* pu8Data, uint16 u16Len) +{ + return CRC16HA_pu16CalcCRC(u16CRC, pu8Data, u16Len); +} + +#endif //KERNEL + diff --git a/source/Peripherals/CRC16.h b/source/Peripherals/CRC16.h new file mode 100644 index 0000000..044d741 --- /dev/null +++ b/source/Peripherals/CRC16.h @@ -0,0 +1,31 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: CRC16 Header Fil */ +/* DESCRIPTION: This code provides CRC16 function definitions */ +/* */ +/* FILE NAME: CRC16.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#ifdef KERNEL + +#ifndef CRC16_H +#define CRC16_H + +#include "CRC16HA.h" +#include "types.h" + +void CRC16_vStart(uint32* const); +void CRC16_vRun(uint32* const); +void CRC16_vTerminate(uint32* const); +puint16 CRC16_pu16CalcCRC(uint16, puint8, uint16); +uint16 CRC16_u16CalcCRC(uint16, puint8, uint16); + +#endif // CRC16_H + +#endif // KERNEL + diff --git a/source/Peripherals/CRC16HA.c b/source/Peripherals/CRC16HA.c new file mode 100644 index 0000000..33e288a --- /dev/null +++ b/source/Peripherals/CRC16HA.c @@ -0,0 +1,122 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: CRC16 */ +/* DESCRIPTION: This code provides CRC16 functions */ +/* */ +/* FILE NAME: CRC16HA.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define CRC16HA_C +#include "sys.h" +#include "CPUAbstract.h" +#include "declarations.h" +#include "SIM.h" + + +#include "CRC16.h" +#include "types.h" + +uint16 CRC16_u16CRC; + + + +#ifdef BUILD_SAM3X8E +static uint16 CRC16HA_u16CalcTableCRC(uint16, puint8, uint16); +static puint16 CRC16HA_pu16CalcTableCRC(uint16, puint8, uint16); +#endif //BUILD_SAM3X8E + +void CRC16HA_vStart(uint32* const u32Stat) +{ +#if defined(BUILD_MK60) || defined(BUILD_MK64) + SIM_vSetReg32(SIM_SCGC6, SIM_SCGC6_CRC_MASK); +#endif +} + +void CRC16HA_vRun(uint32* const u32Stat) +{ + +} + +void CRC16HA_vTerminate(uint32* const u32Stat) +{ + +} + +uint16 CRC16HA_u16CalcCRC(uint16 u16CRC, uint8* pu8Data, uint16 u16Len) +{ +#if defined(BUILD_MK60) || defined(BUILD_MK64) + uint16 u16IDX; + CRC_Type* pstCRC0 = (CRC_Type*)CRC_BASE; + + pstCRC0 -> GPOLY_ACCESS16BIT.GPOLYL = CRC_GPOLY_LOW(0x1021); + pstCRC0 -> CTRL |= CRC_CTRL_WAS_MASK; + pstCRC0 -> DATA = u16CRC; + pstCRC0 -> CTRL &= ~CRC_CTRL_WAS_MASK; + + for (u16IDX = 0; u16IDX < u16Len; u16IDX++) + { + pstCRC0 -> ACCESS8BIT.DATALL = pu8Data[u16IDX]; + } + + return (uint16)pstCRC0 -> ACCESS16BIT.DATAL; +#endif //BUILD_MK6X + + +#ifdef BUILD_SAM3X8E +return CRC16HA_u16CalcTableCRC(u16CRC, pu8Data, u16Len); +#endif + +} + +puint16 CRC16HA_pu16CalcCRC(uint16 u16CRC, uint8* pu8Data, uint16 u16Len) +{ +#if defined(BUILD_MK60) || defined(BUILD_MK64) + uint16 u16IDX; + CRC_Type* pstCRC0 = (CRC_Type*)CRC_BASE; + + pstCRC0 -> GPOLY_ACCESS16BIT.GPOLYL = CRC_GPOLY_LOW(0x1021); + pstCRC0 -> CTRL |= CRC_CTRL_WAS_MASK; + pstCRC0 -> ACCESS16BIT.DATAL = u16CRC; + pstCRC0 -> CTRL &= ~CRC_CTRL_WAS_MASK; + + for (u16IDX = 0; u16IDX < u16Len; u16IDX++) + { + pstCRC0 -> ACCESS8BIT.DATALU = pu8Data[u16IDX]; + } + + CRC16_u16CRC = (uint16)pstCRC0 -> ACCESS16BIT.DATAL; + return (puint16)&CRC16_u16CRC; +#endif + +#ifdef BUILD_SAM3X8E + return CRC16HA_pu16CalcTableCRC(u16CRC, pu8Data, u16Len); +#endif +} + +#ifdef BUILD_SAM3X8E +static uint16 CRC16HA_u16CalcTableCRC(uint16 crc_seed, puint8 pu8Data, uint16 len) +{ + uint16 crc = crc_seed; + while (len--){ + crc = (crc << 8) ^ CRC16HA_au16CRCTable[((crc >> 8) ^ *pu8Data++)]; + } + return (crc); +} +#endif //BUILD_SAM3X8E + +#ifdef BUILD_SAM3X8E +static puint16 CRC16HA_pu16CalcTableCRC(uint16 crc_seed, puint8 pu8Data, uint16 len) +{ + CRC16_u16CRC = crc_seed; + while (len--){ + CRC16_u16CRC = (CRC16_u16CRC << 8) ^ CRC16HA_au16CRCTable[((CRC16_u16CRC >> 8) ^ *pu8Data++)]; + } + return (puint16)&CRC16_u16CRC; +} +#endif //BUILD_SAM3X8E + + diff --git a/source/Peripherals/CRC16HA.h b/source/Peripherals/CRC16HA.h new file mode 100644 index 0000000..1e284e2 --- /dev/null +++ b/source/Peripherals/CRC16HA.h @@ -0,0 +1,72 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: CRC16 Header File */ +/* DESCRIPTION: This code provides CRC16 function definitions */ +/* */ +/* FILE NAME: CRC16.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef CRC16HA_H +#define CRC16HA_H + +#include "CPUAbstract.h" +#include "SIM.h" + +#include "build.h" +#ifdef BUILD_MK60 +#include "mk60f12.h" +typedef CRC_Type tstCRCModule; +#endif + +#ifdef CRC16HA_C +uint16 CRC16HA_au16CRCTable[256] = +{ + 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, + 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, + 0x0919, 0x1890, 0x2A0B, 0x3B82, 0x4F3D, 0x5EB4, 0x6C2F, 0x7DA6, + 0x8551, 0x94D8, 0xA643, 0xB7CA, 0xC375, 0xD2FC, 0xE067, 0xF1EE, + 0x1232, 0x03BB, 0x3120, 0x20A9, 0x5416, 0x459F, 0x7704, 0x668D, + 0x9E7A, 0x8FF3, 0xBD68, 0xACE1, 0xD85E, 0xC9D7, 0xFB4C, 0xEAC5, + 0x1B2B, 0x0AA2, 0x3839, 0x29B0, 0x5D0F, 0x4C86, 0x7E1D, 0x6F94, + 0x9763, 0x86EA, 0xB471, 0xA5F8, 0xD147, 0xC0CE, 0xF255, 0xE3DC, + 0x2464, 0x35ED, 0x0776, 0x16FF, 0x6240, 0x73C9, 0x4152, 0x50DB, + 0xA82C, 0xB9A5, 0x8B3E, 0x9AB7, 0xEE08, 0xFF81, 0xCD1A, 0xDC93, + 0x2D7D, 0x3CF4, 0x0E6F, 0x1FE6, 0x6B59, 0x7AD0, 0x484B, 0x59C2, + 0xA135, 0xB0BC, 0x8227, 0x93AE, 0xE711, 0xF698, 0xC403, 0xD58A, + 0x3656, 0x27DF, 0x1544, 0x04CD, 0x7072, 0x61FB, 0x5360, 0x42E9, + 0xBA1E, 0xAB97, 0x990C, 0x8885, 0xFC3A, 0xEDB3, 0xDF28, 0xCEA1, + 0x3F4F, 0x2EC6, 0x1C5D, 0x0DD4, 0x796B, 0x68E2, 0x5A79, 0x4BF0, + 0xB307, 0xA28E, 0x9015, 0x819C, 0xF523, 0xE4AA, 0xD631, 0xC7B8, + 0x48C8, 0x5941, 0x6BDA, 0x7A53, 0x0EEC, 0x1F65, 0x2DFE, 0x3C77, + 0xC480, 0xD509, 0xE792, 0xF61B, 0x82A4, 0x932D, 0xA1B6, 0xB03F, + 0x41D1, 0x5058, 0x62C3, 0x734A, 0x07F5, 0x167C, 0x24E7, 0x356E, + 0xCD99, 0xDC10, 0xEE8B, 0xFF02, 0x8BBD, 0x9A34, 0xA8AF, 0xB926, + 0x5AFA, 0x4B73, 0x79E8, 0x6861, 0x1CDE, 0x0D57, 0x3FCC, 0x2E45, + 0xD6B2, 0xC73B, 0xF5A0, 0xE429, 0x9096, 0x811F, 0xB384, 0xA20D, + 0x53E3, 0x426A, 0x70F1, 0x6178, 0x15C7, 0x044E, 0x36D5, 0x275C, + 0xDFAB, 0xCE22, 0xFCB9, 0xED30, 0x998F, 0x8806, 0xBA9D, 0xAB14, + 0x6CAC, 0x7D25, 0x4FBE, 0x5E37, 0x2A88, 0x3B01, 0x099A, 0x1813, + 0xE0E4, 0xF16D, 0xC3F6, 0xD27F, 0xA6C0, 0xB749, 0x85D2, 0x945B, + 0x65B5, 0x743C, 0x46A7, 0x572E, 0x2391, 0x3218, 0x0083, 0x110A, + 0xE9FD, 0xF874, 0xCAEF, 0xDB66, 0xAFD9, 0xBE50, 0x8CCB, 0x9D42, + 0x7E9E, 0x6F17, 0x5D8C, 0x4C05, 0x38BA, 0x2933, 0x1BA8, 0x0A21, + 0xF2D6, 0xE35F, 0xD1C4, 0xC04D, 0xB4F2, 0xA57B, 0x97E0, 0x8669, + 0x7787, 0x660E, 0x5495, 0x451C, 0x31A3, 0x202A, 0x12B1, 0x0338, + 0xFBCF, 0xEA46, 0xD8DD, 0xC954, 0xBDEB, 0xAC62, 0x9EF9, 0x8F70 +}; +#endif //CRC16HA_C + +void CRC16HA_vStart(uint32* const); +void CRC16HA_vRun(uint32* const); +void CRC16HA_vTerminate(uint32* const); +puint16 CRC16HA_pu16CalcCRC(uint16, puint8, uint16); +uint16 CRC16HA_u16CalcCRC(uint16, puint8, uint16); + +#endif //CRC16HA_H + + + diff --git a/source/Peripherals/DAC.c b/source/Peripherals/DAC.c new file mode 100644 index 0000000..6b17dde --- /dev/null +++ b/source/Peripherals/DAC.c @@ -0,0 +1,48 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include "DAC.h" + +DACAPI_tpfEventCB DAC_apfEvent[DACHA_nDACCount]; + + +void DAC_vStart(puint32 const pu32Stat) +{ + uint32 u32DACIDX; + + for (u32DACIDX = 0; u32DACIDX < DACHA_nDACCount; u32DACIDX++) + { + DAC_apfEvent[u32DACIDX] = NULL; + } +} + +void DAC_vRun(puint32 const pu32Stat) +{ + DACHA_vRun(pu32Stat); +} + +void DAC_vTerminate(puint32 const pu32Stat) +{ + +} + +SYSAPI_tenSVCResult DAC_vInitDACResource(IOAPI_tenEHIOResource enEHIOResource, DACAPI_tstDACCB* pstDACCB) +{ + return DACHA_vInitDACResource(enEHIOResource, pstDACCB); +} + +void DAC_vWriteDACQueue(IOAPI_tenEHIOResource enEHIOResource, DACAPI_ttOutputVoltage* pOutputVoltage) +{ + uint32 u32Stat; + + DACHA_vWriteDACQueue(enEHIOResource, pOutputVoltage); + DACHA_vRun(&u32Stat); +} diff --git a/source/Peripherals/DAC.h b/source/Peripherals/DAC.h new file mode 100644 index 0000000..4ebb4aa --- /dev/null +++ b/source/Peripherals/DAC.h @@ -0,0 +1,34 @@ +/******************************************************************************/ +/* DAC header file */ +/******************************************************************************/ +/* */ +/* Copyright (c) 2013 MD Automotive Controls. All rights reserved. */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#ifndef DAC_H +#define DAC_H + +#include "CPUAbstract.h" +#include "DACAPI.h" +#include "DACHA.h" +#include "declarations.h" +#include "IOAPI.h" +#include "os.h" +#include "regset.h" +#include "SIM.h" +#include "SYSAPI.h" +#include "sys.h" +#include "types.h" + +#define DAC_nDACCount 2u +#define DAC_nQueueSize 16u + +void DAC_vStart(puint32 const); +void DAC_vRun(puint32 const); +void DAC_vTerminate(puint32 const); +SYSAPI_tenSVCResult DAC_vInitDACResource(IOAPI_tenEHIOResource, DACAPI_tstDACCB*); +void DAC_vWriteDACQueue(IOAPI_tenEHIOResource, DACAPI_ttOutputVoltage*); +#endif // DAC_H + diff --git a/source/Peripherals/DACHA.c b/source/Peripherals/DACHA.c new file mode 100644 index 0000000..80e0a63 --- /dev/null +++ b/source/Peripherals/DACHA.c @@ -0,0 +1,131 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include "CPUAbstract.h" +#include "regset.h" +#include "sys.h" +#include "declarations.h" +#include "os.h" +#include "IOAPI.h" +#include "DACAPI.h" +#include "DAC.h" +#include "types.h" +#include "SIM.h" + +DACAPI_ttOutputVoltage DACHA_atQueue[DACHA_nDACCount][DAC_nQueueSize]; +uint32 DACHA_au32QueueIDX[DACHA_nDACCount]; +uint32 DACHA_u32PortClockRequested; + +void DACHA_vStart(puint32 const pu32Stat) +{ + +} + +void DACHA_vRun(puint32 const pu32Stat) +{ + tstDACModule* pstDAC = NULL; + uint32 u32QueueIDX; + uint32 u32DACIDX; + uint32 u32ClockReq = 1; + + for (u32DACIDX = 0; u32DACIDX < DACHA_nDACCount; u32DACIDX++) + { + if (u32ClockReq == (u32ClockReq & DACHA_u32PortClockRequested)) + { +#if defined(BUILD_MK60) || defined(BUILD_MK64) + pstDAC = (0 == u32DACIDX) ? DAC0 : DAC1; + + if ((pstDAC->C2 & DAC_C2_DACBFUP_MASK) < ++DACHA_au32QueueIDX[u32DACIDX]) + { + for (u32QueueIDX = 0; u32QueueIDX <= (pstDAC->C2 & DAC_C2_DACBFUP_MASK); u32QueueIDX++) + { + pstDAC->DAT[u32QueueIDX].DATH = (DACHA_atQueue[u32DACIDX][u32QueueIDX] & 0x0f00) >> 8; + pstDAC->DAT[u32QueueIDX].DATL = DACHA_atQueue[u32DACIDX][u32QueueIDX] & 0xff; + } + DACHA_au32QueueIDX[u32DACIDX] = 0; + } + + /* Set the read pointer */ + pstDAC->C2 = (pstDAC->C2 & DAC_C2_DACBFUP_MASK) | DAC_C2_DACBFRP(DACHA_au32QueueIDX[u32DACIDX]); +#endif //BUILD_MK60 + } + u32ClockReq *= 2; + } +} + +void DACHA_vTerminate(puint32 const pu32Stat) +{ + +} + + +SYSAPI_tenSVCResult DACHA_vInitDACResource(IOAPI_tenEHIOResource enEHIOResource, DACAPI_tstDACCB* pstDACCB) +{ + tstDACModule* pstDAC = NULL; + SYSAPI_tenSVCResult enResult = SYSAPI_enBadResource; + + switch (enEHIOResource) + { +#if defined(BUILD_MK60) || defined(BUILD_MK64) + case EH_O_DAC1: + { + pstDAC = DAC0; + SIM_vSetReg32(SIM_SCGC2, SIM_SCGC2_DAC0_MASK); + DACHA_u32PortClockRequested |= 1; + break; + } + case EH_O_DAC2: + { + pstDAC = DAC1; + SIM_vSetReg32(SIM_SCGC2, SIM_SCGC2_DAC1_MASK); + DACHA_u32PortClockRequested |= 2; + break; + } +#endif //BUILD_MK60 + default: + pstDAC = NULL; + break; + } + + if (NULL != pstDAC) + { + enResult = SYSAPI_enOK; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + pstDAC->C0 |= (DAC_C0_DACEN_MASK | DAC_C0_DACRFS_MASK); + if (DACAPI_enSoftwareTrigger == pstDACCB->enTriggerType) pstDAC->C0 |= DAC_C0_DACTRGSEL_MASK; + if (TRUE == pstDACCB->boWaterMarkEventEnable) pstDAC->C0 |= DAC_C0_DACBWIEN_MASK; + if (TRUE == pstDACCB->boPointerTopEventEnable) pstDAC->C0 |= DAC_C0_DACBTIEN_MASK; + if (TRUE == pstDACCB->boPointerBottomEventEnable) pstDAC->C0 |= DAC_C0_DACBBIEN_MASK; + pstDAC->C1 = DAC_C1_DACBFWM(pstDACCB->enWatermarkWords) | DAC_C1_DACBFEN_MASK; + pstDAC->C2 = DAC_C2_DACBFUP(pstDACCB->enQueueDepth); +#endif //BUILD_MK60 + } + + return enResult; +} + +void DACHA_vWriteDACQueue(IOAPI_tenEHIOResource enEHIOResource, DACAPI_ttOutputVoltage* pOutputVoltage) +{ + uint32 u32QueueIDX; + tstDACModule* pstDAC; + uint32 u32Queue; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + pstDAC = (EH_O_DAC1 == enEHIOResource) ? DAC0 : DAC1; + u32Queue = (EH_O_DAC1 == enEHIOResource) ? 0 : 1; + + for (u32QueueIDX = 0; u32QueueIDX <= (pstDAC->C2 & DAC_C2_DACBFUP_MASK); u32QueueIDX++) + { + DACHA_atQueue[u32Queue][u32QueueIDX] = *pOutputVoltage++; + } +#endif //BUILD_MK60 +} diff --git a/source/Peripherals/DACHA.h b/source/Peripherals/DACHA.h new file mode 100644 index 0000000..f10bad1 --- /dev/null +++ b/source/Peripherals/DACHA.h @@ -0,0 +1,49 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef DACHA_H +#define DACHA_H + +#include "CPUAbstract.h" +#include "regset.h" +#include "sys.h" +#include "declarations.h" +#include "os.h" +#include "IOAPI.h" +#include "DACAPI.h" +#include "SYSAPI.h" +#include "types.h" +#include "SIM.h" + +#define DACHA_nDACCount 2u + +#ifdef BUILD_MK60 +#include "mk60f12.h" +typedef DAC_Type tstDACModule; +#endif + +#ifdef BUILD_MK64 +#include "mk64f12.h" +typedef DAC_Type tstDACModule; +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +#include "sam3x8e.h" +typedef struct Dacc tstDACModule; +#endif + +void DACHA_vStart(puint32 const); +void DACHA_vRun(puint32 const); +void DACHA_vTerminate(puint32 const); +SYSAPI_tenSVCResult DACHA_vInitDACResource(IOAPI_tenEHIOResource, DACAPI_tstDACCB*); +void DACHA_vWriteDACQueue(IOAPI_tenEHIOResource, DACAPI_ttOutputVoltage*); +#endif //DACHA_H + diff --git a/source/Peripherals/FEE.c b/source/Peripherals/FEE.c new file mode 100644 index 0000000..619dc8a --- /dev/null +++ b/source/Peripherals/FEE.c @@ -0,0 +1,247 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include "FEE.h" +#include "FEEHA.h" + +FEE_tstWriteControlBlock FEE_stWriteControlBlock; +FEE_tenPgmErrCode FEE_enPgmErrCode; +FEE_tstWorkingPage FEE_stWorkingPage; + +#if BUILD_SBL + uint8 FEE_au8ProgBuff[FEE_PFLASH_SCTR_BYTES]; +#else + uint8 FEE_au8ProgBuff[1]; +#endif + + +void FEE_vStartSBL(void) +{ +#if BUILD_SBL + FEEHA_vStartSBL(); +#endif +} + +bool FEE_boCheckPartition(void) +{ + bool boRetVal = false; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + return FEEHA_boCheckPartition(); +#endif + +#ifdef BUILD_SAM3X8E + boRetVal = true; +#endif //BUILD_SAM3X8E + + return boRetVal; +} + +bool FEE_boSetWorkingData(puint8 pu8WorkingAddress, uint16 u16WorkingDataCount) +{ + bool boWorkingDataOK = FALSE; + + if (((puint8)FEEHA_WORK_DATA_START <= pu8WorkingAddress) && + ((puint8)FEEHA_WORK_DATA_END >= pu8WorkingAddress) && + ((uint16)FEEHA_WORK_DATA_MAX > u16WorkingDataCount) && + (2 <= u16WorkingDataCount)) + { + FEE_stWorkingPage.pu8WorkingData = pu8WorkingAddress; + FEE_stWorkingPage.s16WorkingDataCount = (sint16)u16WorkingDataCount; + boWorkingDataOK = TRUE; + } + + return boWorkingDataOK; +} + +bool FEE_boNVMWorkingCopy(bool boNVMToWorking, bool boCheckCRC16MakeCRC16) +{ + bool boCopyOK; + + boCopyOK = FEEHA_boNVMWorkingCopy(boNVMToWorking, boCheckCRC16MakeCRC16); + + return boCopyOK; +} + +bool FEE_boWriteNVM(puint8 pu8SourceData, puint8 pu8DestData, uint32 u32DataByteCount) +{ + bool boCopyOK = TRUE; + + boCopyOK = FEEHA_boWriteNVM(pu8SourceData, pu8DestData, u32DataByteCount); + + return boCopyOK; +} + + +bool FEE_boNVMClear(void) +{ + bool boClearOK; + + boClearOK = FEEHA_boNVMClear(); + + return boClearOK; +} + +bool FEE_boEraseForDownload(puint8 pu8TargetAddress, uint32 u32EraseCount) +{ + bool boEraseErr = false; + + boEraseErr = FEEHA_boEraseForDownload(pu8TargetAddress, u32EraseCount); + + return boEraseErr; +} + + +void FEE_vStart(uint32* const pu32Stat) +{ + bool boStartOK; + + boStartOK = FEEHA_boStart(pu32Stat); + + if (false == boStartOK) + { + *pu32Stat = false; + } + else + { + FEE_stWriteControlBlock.boProgramming = false; + FEE_stWriteControlBlock.boProgErr = false; + *pu32Stat = true; + } + + FEE_stWorkingPage.pu8WorkingData = NULL; + FEE_stWorkingPage.s16WorkingDataCount = -1; + + OS_xModuleStartOK(*pu32Stat); +} + +void FEE_vRun(uint32* const u32Stat) +{ + FEEHA_vRun(u32Stat); +} + + +void FEE_vTerminate(uint32* const u32Stat) +{ + +} + +bool FEE_boPartition(void) +{ + bool boRetVal; + + boRetVal = FEE_boCheckPartition(); + + if (FALSE == boRetVal) + { + boRetVal = FEEHA_boPartition(); + } + + return boRetVal; +} + +void FEE_vWriteExceptionRecord(puint8 pu8ExceptionRecord) +{ +#if 0 + puint8 pu8Search = (uint8*)FEEHA_EXC_RECS_START; + uint32 u32ErasedCounts = 0; + + while (pu8Search <= (puint8)FEEHA_EXC_RECS_END) + { + if (0xff == *pu8Search) + { + u32ErasedCounts++; + + if (32 == u32ErasedCounts) + { + break; + } + } + else + { + u32ErasedCounts = 0; + } + + pu8Search++; + } + + if (32 == u32ErasedCounts) + { + pu8ExceptionRecord -= FEEHA_EXC_RECS_START; + FEEHA_boWriteNVM(pu8ExceptionRecord, pu8Search, 32); + } +#endif +} + +bool FEE_boWriteControlBlock(COMMONNL_tstRXLargeBuffer* const pstParamSourceBuffer, + uint8* const pu8ParamTargetAddress, + uint32 u32ParamWriteCount) +{ + if ((false == FEE_stWriteControlBlock.boProgramming) && + (false == FEE_stWriteControlBlock.boProgErr)) + { + FEE_stWriteControlBlock.pstSourceBuffer = pstParamSourceBuffer; + FEE_stWriteControlBlock.pu8TargetAddress = pu8ParamTargetAddress; + FEE_stWriteControlBlock.u32WriteCount = u32ParamWriteCount; + FEE_stWriteControlBlock.u32AccumulateCount = 0; + FEE_stWriteControlBlock.boProgramming = true; + } + else + { + FEE_stWriteControlBlock.boProgramming = false; + } + + return FEE_stWriteControlBlock.boProgramming; +} + +bool FEE_boUpdateControlBlock(uint32 u32BlockWriteCount) +{ + puint8 pu8SourceData; + puint8 pu8BufferData; + + if (FEE_stWriteControlBlock.boProgramming == true) + { + if ((FEEHA_PFLASH_SCTR_BYTES >= + (u32BlockWriteCount + FEE_stWriteControlBlock.u32AccumulateCount)) && + (0 != u32BlockWriteCount)) + { + pu8SourceData = (puint8)&FEE_stWriteControlBlock.pstSourceBuffer->u8Data[0]; + pu8BufferData = (puint8)((uint32)&FEE_au8ProgBuff + FEE_stWriteControlBlock.u32AccumulateCount); + + memcpy((void*)pu8BufferData, (void*)pu8SourceData, u32BlockWriteCount); + + FEE_stWriteControlBlock.u32AccumulateCount += u32BlockWriteCount; + + if (FEEHA_PFLASH_SCTR_BYTES == FEE_stWriteControlBlock.u32AccumulateCount) + { + FEE_stWriteControlBlock.u32AccumulateCount = 0; + FEEHA_boWriteSector(); + } + else if (FEEHA_PFLASH_SCTR_BYTES < FEE_stWriteControlBlock.u32AccumulateCount) + { + /* Uh oh too many bytes received - ran past the sector size */ + /* matthew deal with this */ + FEE_stWriteControlBlock.boProgramming = false; + } + else if (FEE_stWriteControlBlock.u32WriteCount <= FEE_stWriteControlBlock.u32AccumulateCount) + { + FEE_stWriteControlBlock.u32AccumulateCount = 0; + FEEHA_boWriteSector(); + } + } + else + { + FEE_stWriteControlBlock.boProgramming = false; + } + } + + return FEE_stWriteControlBlock.boProgramming; +} diff --git a/source/Peripherals/FEE.h b/source/Peripherals/FEE.h new file mode 100644 index 0000000..a57e6de --- /dev/null +++ b/source/Peripherals/FEE.h @@ -0,0 +1,86 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef FEE_H +#define FEE_H + +#include +#include +#include "COMMONNL.h" +#include "CRC16.h" +#include "sys.h" +#include "types.h" + + +// FEE MDAC error codes +typedef enum +{ + enErrNone, + enErrPViol, + enErrOOR, + enErrAlign, + enErrContig, + enErrAccess, + enErrBusy +} FEE_tenPgmErrCode; + +typedef enum +{ + enMarginNormal, + enMarginUser, + enMarginFactory +} FEE_tenMarginChoice; + +#define FEE_nReg8Set \ +{ \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FPROT3)), (uint8)FEE_PFLASH_PRT3, REGSET_enOverwrite }, \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FPROT2)), (uint8)FEE_PFLASH_PRT2, REGSET_enOverwrite }, \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FPROT1)), (uint8)FEE_PFLASH_PRT1, REGSET_enOverwrite }, \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FPROT0)), (uint8)FEE_PFLASH_PRT0, REGSET_enOverwrite }, \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FDPROT)), (uint8)FEE_DFLASH_PROT, REGSET_enOverwrite }, \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FEPROT)), (uint8)FEE_EFLASH_PROT, REGSET_enOverwrite }, \ + { NULL, 0, REGSET_enOverwrite } \ +} + +typedef struct +{ + puint8 pu8WorkingData; + sint16 s16WorkingDataCount; +} FEE_tstWorkingPage; + +typedef struct +{ + COMMONNL_tstRXLargeBuffer* pstSourceBuffer; + uint8* pu8TargetAddress; + uint32 u32WriteCount; + uint32 u32AccumulateCount; + bool boProgramming; + bool boProgErr; +} FEE_tstWriteControlBlock; + +void FEE_vStart( uint32* const ); +void FEE_vRun( uint32* const ); +void FEE_vTerminate( uint32* const ); +void FEE_vStartSBL(void); +bool FEE_boCheckPartition(void); +bool FEE_boSetWorkingData(puint8, uint16); +bool FEE_boNVMWorkingCopy(bool, bool); +bool FEE_boNVMClear(void); +bool FEE_boPartition(void); +bool FEE_boWriteControlBlock(COMMONNL_tstRXLargeBuffer* const, + uint8* const, + uint32 ); +bool FEE_boUpdateControlBlock( uint32); +bool FEE_boEraseForDownload(puint8, uint32); +bool FEE_boWriteNVM(puint8, puint8, uint32); + +#endif // FEE_H + diff --git a/source/Peripherals/FEEHA.c b/source/Peripherals/FEEHA.c new file mode 100644 index 0000000..ccf805c --- /dev/null +++ b/source/Peripherals/FEEHA.c @@ -0,0 +1,1062 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#include +#include "mk64f12.h" +#include +#include +#include + +/* include the header files */ +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" +#include "SSD_FTFx_Device.h" + +#include "IOAPI.h" +#include "regset.h" +#include "os.h" +#include "DLL.h" +#include "COMMONNL.h" +#include "FEE.h" +#include "FEEHA.h" + +#ifdef BUILD_SAM3X8E +#include "FLASHHA.h" +#endif //BUILD_SAM3X8E + +#include "TEPM.h" + +tstFTFEConfig FEE_stFlashSSDConfig; + +uint32 returnCode; /* Return code from each SSD function */ +uint32 destination; /* Address of the target location */ +uint32 size; +uint32 source; +uint32 protectStatus; /* Store Protection Status Value of PFLASH */ +uint8 protectStatus1; /* Store Protection Status Value of DFLASH or EEPROM */ +uint32 FailAddr; +uint8 FailData; +uint8 marginLevel; +uint16 phraseNumber; /* Number of phrase to be verified*/ +uint8 EEEDataSizeCode; +uint8 DEPartitionCode; +uint32 Sum; +uint32 unsecure_key; +uint32 i; +uint8 u8WriteCount; +uint32 FEE_u32RunCount; +uint32 FEE_u32InhibitNVMCount; + +extern FEE_tstWriteControlBlock FEE_stWriteControlBlock; +extern FEE_tenPgmErrCode FEE_enPgmErrCode; +extern FEE_tstWorkingPage FEE_stWorkingPage; + +#if BUILD_SBL + extern uint8 FEE_au8ProgBuff[FEE_PFLASH_SCTR_BYTES]; +#else + extern uint8 FEE_au8ProgBuff[1]; +#endif + +const REGSET_tstReg8Val FEEHA_rastFTFEReg8Val[] = FEEHA_nReg8Set; + +static bool FEEHA_boPartitionDFlash(void); +static void FEEHA_vInitFlashConfig(void); +static bool FEEHA_boGetSem(bool); +static uint8* FEEHA_pu8GetPartitionAddress(void); +static uint8* FEEHA_pu8GetFreePartitionAddress(void); + +void FEEHA_vStartSBL(void) +{ +#if BUILD_SBL + FTFE_Type* pstFTFE = FTFE; + + if (((pstFTFE -> FCNFG) & FTFE_FCNFG_RAMRDY_MASK) != FTFE_FCNFG_RAMRDY_MASK) + { + /* Make FlexRAM available as RAM for programming */ + pSetEEEEnable(&FEE_stFlashSSDConfig, 0xff); + } +#endif +} + +bool FEEHA_boCheckPartition(void) +{ + bool boPartitionOK = false; + +#if defined(BUILD_MK60) + tstFTFEModule* pstFTFE; + pstFTFE = FTFE; + + if (((pstFTFE -> FCNFG) & FTFE_FCNFG_EEERDY_MASK) != FTFE_FCNFG_EEERDY_MASK) + /* If DFlash not already partitioned */ + { + boPartitionOK = FALSE; + } + else + { + boPartitionOK = TRUE; + } +#endif //BUILD_MK60 + +#if defined(BUILD_MK64) + uint32* pu32NVRecordBase = (uint32*)(FEEHA_DFLASH_END - FEEHA_WORK_DATA_MAX + 1); + + while ((uint32*)FEEHA_DFLASH_START <= pu32NVRecordBase) + { + if (~0 != *pu32NVRecordBase) + { + boPartitionOK = TRUE; + break; + } + + pu32NVRecordBase -= (FEEHA_WORK_DATA_MAX / sizeof(uint32)); + } +#endif //BUILD_MK64 + + return boPartitionOK; +} + +bool FEEHA_boSetWorkingData(puint8 pu8WorkingAddress, uint16 u16WorkingDataCount) +{ + bool boWorkingDataOK = FALSE; + + if (((puint8)FEEHA_WORK_DATA_START <= pu8WorkingAddress) && + ((puint8)FEEHA_WORK_DATA_END >= pu8WorkingAddress) && + ((uint16)FEEHA_WORK_DATA_MAX > u16WorkingDataCount) && + (2 <= u16WorkingDataCount)) + { + FEE_stWorkingPage.pu8WorkingData = pu8WorkingAddress; + FEE_stWorkingPage.s16WorkingDataCount = (sint16)u16WorkingDataCount; + boWorkingDataOK = TRUE; + } + + return boWorkingDataOK; +} + + + +bool FEEHA_boNVMWorkingCopy(bool boNVMToWorking, bool boCheckCRC16MakeCRC16) +{ + bool boCopyOK = false; + puint16 pu16CRC16Computed; + puint16 pu16CRC16Stored; + +#if defined(BUILD_MK60) + tstFTFEModule* pstFTFE; + boCopyOK = FEEHA_boCheckPartition(); + uint32 u32RetCode = FTFx_OK; + pstFTFE = FTFE; + uint32 u32NVMWordCount; + uint32 u32NVMWordIDX; + uint32 u32SourceWord; + uint32 u32DestinationWord; + + if ((TRUE == boCopyOK) && + (0 < FEE_stWorkingPage.s16WorkingDataCount) && + (NULL != FEE_stWorkingPage.pu8WorkingData)) + { + if (TRUE == boNVMToWorking) + /* Copy NVM page to working page */ + { + pu16CRC16Computed = (puint16)(CRC16_pu16CalcCRC(0xffff, (puint8)FEEHA_EEPROM_START, + FEE_stWorkingPage.s16WorkingDataCount - 2)); + + pu16CRC16Stored = (puint16)((uint32)FEEHA_EEPROM_START + + (uint32)FEE_stWorkingPage.s16WorkingDataCount - 2); + + if (TRUE == boCheckCRC16MakeCRC16) + { + if (*pu16CRC16Stored == *pu16CRC16Computed) + { + memcpy((void*)FEE_stWorkingPage.pu8WorkingData, + (void*)FEEHA_EEPROM_START, FEE_stWorkingPage.s16WorkingDataCount); + boCopyOK = TRUE; + } + else + { + boCopyOK = FALSE; + } + } + else + { + memcpy((void*)FEE_stWorkingPage.pu8WorkingData, + (void*)FEEHA_EEPROM_START, FEE_stWorkingPage.s16WorkingDataCount); + boCopyOK = TRUE; + } + } + else + /* Copy working page to NVM page */ + { + if (TRUE == boCheckCRC16MakeCRC16) + { + pu16CRC16Computed = (puint16)(CRC16_pu16CalcCRC(0xffff, FEE_stWorkingPage.pu8WorkingData, + FEE_stWorkingPage.s16WorkingDataCount - 2)); + + pu16CRC16Stored = (puint16)((uint32)FEE_stWorkingPage.pu8WorkingData + + (uint32)FEE_stWorkingPage.s16WorkingDataCount - 2); + + /* Copy the computed CRC into the working page */ + *pu16CRC16Stored = *pu16CRC16Computed; + } + + if (((pstFTFE -> FSTAT) & FTFE_FSTAT_ACCERR_MASK) == FTFE_FSTAT_ACCERR_MASK) + { + pstFTFE -> FSTAT &= FTFE_FSTAT_ACCERR_MASK; + } + + u32NVMWordCount = FEE_stWorkingPage.s16WorkingDataCount / 4; + u32NVMWordCount = (0 == FEE_stWorkingPage.s16WorkingDataCount % 4) ? + u32NVMWordCount : u32NVMWordCount + 1; + boCopyOK = TRUE; + + for (u32NVMWordIDX = 0; u32NVMWordIDX < u32NVMWordCount; u32NVMWordIDX++) + { + u32SourceWord = (uint32)FEE_stWorkingPage.pu8WorkingData + 4 * u32NVMWordIDX; + u32DestinationWord = (uint32)FEEHA_EEPROM_START + 4 * u32NVMWordIDX; + + if (*(puint32)u32SourceWord != *(puint32)u32DestinationWord) + /* Only call write if words are different */ + { + if (FTFx_OK == u32RetCode) + { + u32RetCode = pEEEWrite(&FEE_stFlashSSDConfig, + u32DestinationWord, 4, u32SourceWord); + } + else + { + boCopyOK = false; + } + } + } + } + } +#endif //BUILD_MK60 + +#if defined(BUILD_MK64) + tstFTFEModule* pstFTFE; + uint32 u32RetCode = FTFx_OK; + pstFTFE = FTFE; + uint32 u32NVMSectorCount; + uint32 u32NVMSectorIDX; + uint32 u32SourceWord; + uint32 u32DestinationWord; + uint8* pu8PartitionBase; + + if ((0 < FEE_stWorkingPage.s16WorkingDataCount) && + (NULL != FEE_stWorkingPage.pu8WorkingData) && + (0 == FEE_u32InhibitNVMCount)) + { + if (TRUE == boNVMToWorking) + /* Copy NVM page to working page */ + { + uint8* pu8PartitionBase = FEEHA_pu8GetPartitionAddress(); + + if (((uint8*)~0) != pu8PartitionBase) + { + pu16CRC16Computed = (puint16)(CRC16_pu16CalcCRC(0xffff, (puint8)pu8PartitionBase, + FEE_stWorkingPage.s16WorkingDataCount - 2)); + + pu16CRC16Stored = (puint16)((uint32)pu8PartitionBase + + (uint32)FEE_stWorkingPage.s16WorkingDataCount - 2); + + if (TRUE == boCheckCRC16MakeCRC16) + { + if (*pu16CRC16Stored == *pu16CRC16Computed) + { + memcpy((void*)FEE_stWorkingPage.pu8WorkingData, + (void*)pu8PartitionBase, FEE_stWorkingPage.s16WorkingDataCount); + boCopyOK = TRUE; + } + else + { + boCopyOK = FALSE; + } + } + else + { + memcpy((void*)FEE_stWorkingPage.pu8WorkingData, + (void*)FEEHA_EEPROM_START, FEE_stWorkingPage.s16WorkingDataCount); + boCopyOK = TRUE; + } + } + } + else + /* Copy working page to NVM page */ + { + /* No copy for another 10 seconds */ + FEE_u32InhibitNVMCount = 10000; + + if (TRUE == boCheckCRC16MakeCRC16) + { + pu16CRC16Computed = (puint16)(CRC16_pu16CalcCRC(0xffff, FEE_stWorkingPage.pu8WorkingData, + FEE_stWorkingPage.s16WorkingDataCount - 2)); + + pu16CRC16Stored = (puint16)((uint32)FEE_stWorkingPage.pu8WorkingData + + (uint32)FEE_stWorkingPage.s16WorkingDataCount - 2); + + /* Copy the computed CRC into the working page */ + *pu16CRC16Stored = *pu16CRC16Computed; + } + + if (((pstFTFE -> FSTAT) & FTFE_FSTAT_ACCERR_MASK) == FTFE_FSTAT_ACCERR_MASK) + { + pstFTFE -> FSTAT &= FTFE_FSTAT_ACCERR_MASK; + } + + if (((pstFTFE -> FSTAT) & FTFE_FSTAT_FPVIOL_MASK) == FTFE_FSTAT_FPVIOL_MASK) + { + pstFTFE -> FSTAT &= FTFE_FSTAT_FPVIOL_MASK; + } + + u32NVMSectorCount = FEE_stWorkingPage.s16WorkingDataCount / FEEHA_EEPROM_SCTR_BYTES; + u32NVMSectorCount = (0 == FEE_stWorkingPage.s16WorkingDataCount % FEEHA_EEPROM_SCTR_BYTES) ? + u32NVMSectorCount : u32NVMSectorCount + 1; + boCopyOK = TRUE; + + pu8PartitionBase = FEEHA_pu8GetFreePartitionAddress(); + + if (((uint8*)~0) != pu8PartitionBase) + { + for (u32NVMSectorIDX = 0; u32NVMSectorIDX < u32NVMSectorCount; u32NVMSectorIDX++) + { + u32SourceWord = (uint32)FEE_stWorkingPage.pu8WorkingData + FEEHA_EEPROM_SCTR_BYTES * u32NVMSectorIDX; + u32DestinationWord = (uint32)pu8PartitionBase + FEEHA_EEPROM_SCTR_BYTES * u32NVMSectorIDX; + + if (FTFx_OK == u32RetCode) + { + u32RetCode = FlashProgramPhrase(&FEE_stFlashSSDConfig, + u32DestinationWord, FEEHA_EEPROM_SCTR_BYTES, u32SourceWord, &FlashCommandSequence); + } + else + { + boCopyOK = false; + } + + } + } + } + } +#endif //BUILD_MK60 + +#ifdef BUILD_SAM3X8E + if (TRUE == boNVMToWorking) + /* Copy NVM page to working page */ + { + if (TRUE == boCheckCRC16MakeCRC16) + { + pu16CRC16Computed = (puint16)(CRC16_pu16CalcCRC(0xffff, (puint8)FEEHA_EEPROM_START, + FEE_stWorkingPage.s16WorkingDataCount - 2)); + + pu16CRC16Stored = (puint16)((uint32)FEEHA_EEPROM_START + + (uint32)FEE_stWorkingPage.s16WorkingDataCount - 2); + + if ((NULL != FEE_stWorkingPage.pu8WorkingData) && (*pu16CRC16Stored == *pu16CRC16Computed)) + { + memcpy(FEE_stWorkingPage.pu8WorkingData, 0x000c0000, FEE_stWorkingPage.s16WorkingDataCount); + boCopyOK = true; + } + } + } + else + /* Copy working page to NVM page */ + { + if ((NULL != FEE_stWorkingPage.pu8WorkingData) && (10000 < (FEE_u32RunCount - u32LastWriteCount))) + { + pu16CRC16Computed = (puint16)(CRC16_pu16CalcCRC(0xffff, FEE_stWorkingPage.pu8WorkingData, + FEE_stWorkingPage.s16WorkingDataCount - 2)); + + pu16CRC16Stored = (puint16)((uint32)FEE_stWorkingPage.pu8WorkingData + + (uint32)FEE_stWorkingPage.s16WorkingDataCount - 2); + + /* Copy the computed CRC into the working page */ + *pu16CRC16Stored = *pu16CRC16Computed; + + uint32_t u32LoopDelay = 0x1800000; + + TEPM_vEnableSequences(FALSE); + IRQ_vEnableRTOS(FALSE); + + while (0 != u32LoopDelay) + { + u32LoopDelay--; + } + + /* Erase flash */ + flash_erase_all(0x00c0000); + + /* Write working page to flash */ + flash_write(0x00c0000, FEE_stWorkingPage.pu8WorkingData, FEE_stWorkingPage.s16WorkingDataCount , 1u); + u32LastWriteCount = FEE_u32RunCount; + + u32LoopDelay = ~0; + + while (0 != u32LoopDelay) + { + u32LoopDelay--; + } + } + } +#endif //BUILD_SAM3X8E + + return boCopyOK; +} + +bool FEEHA_boWriteNVM(puint8 pu8SourceData, puint8 pu8DestData, uint32 u32DataByteCount) +{ + tstFTFEModule* pstFTFE; + bool boCopyOK = TRUE; + uint32 u32SourceWord = (uint32)pu8SourceData; + uint32 u32DestinationWord = (uint32)pu8DestData; + uint32 u32RetCode; + + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + pstFTFE = FTFE; + u32RetCode = FTFx_OK; + + if (((pstFTFE -> FSTAT) & FTFE_FSTAT_ACCERR_MASK) == FTFE_FSTAT_ACCERR_MASK) + { + pstFTFE -> FSTAT &= FTFE_FSTAT_ACCERR_MASK; + } + + if (TRUE == FEEHA_boGetSem(TRUE)) + { + while (4 < u32DataByteCount) + { + if (*(puint32)u32SourceWord != *(puint32)u32DestinationWord) + /* Only call write if words are different */ + { + if (FTFx_OK == u32RetCode) + { + u32RetCode = pEEEWrite(&FEE_stFlashSSDConfig, + u32DestinationWord, 4, u32SourceWord); + } + else + { + boCopyOK = false; + } + } + + u32DestinationWord += sizeof(uint32); + u32SourceWord += sizeof(uint32); + u32DataByteCount -= sizeof(uint32); + } + + if (0 < u32DataByteCount) + { + if (0 != memcmp((void*)u32SourceWord, (void*)u32DestinationWord, u32DataByteCount)) + /* Only call write if bytes are different */ + { + if (FTFx_OK == u32RetCode) + { + u32RetCode = pEEEWrite(&FEE_stFlashSSDConfig, + u32DestinationWord, u32DataByteCount, u32SourceWord); + } + else + { + boCopyOK = FALSE; + } + } + } + + FEEHA_boGetSem(FALSE); + } + else + { + boCopyOK = FALSE; + } +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + /* Write working page to flash */ + u32RetCode = flash_write(0x00c0000 + (uint32)pu8DestData, (uint32)pu8SourceData, u32DataByteCount, 0u); + + boCopyOK = 0 == u32RetCode; +#endif + + return boCopyOK; +} + + +bool FEEHA_boNVMClear(void) +{ + bool boClearOK = false; + +#if defined(BUILD_MK60) + tstFTFEModule* pstFTFE; + + uint32 u32NVMWordCount; + uint32 u32NVMWordIDX; + uint32 u32SourceWord = 0; + uint32 u32DestinationWord; + uint32 u32RetCode; + u32RetCode = FTFx_OK; + + boClearOK = FEE_boCheckPartition(); + + if ((TRUE == boClearOK) && + (0 < FEE_stWorkingPage.s16WorkingDataCount) && + (NULL != FEE_stWorkingPage.pu8WorkingData)) + { + /* Clear NVM page */ + { + if (((pstFTFE -> FSTAT) & FTFE_FSTAT_ACCERR_MASK) == FTFE_FSTAT_ACCERR_MASK) + { + pstFTFE -> FSTAT &= FTFE_FSTAT_ACCERR_MASK; + } + + u32NVMWordCount = FEE_stWorkingPage.s16WorkingDataCount / 4; + u32NVMWordCount = (0 == FEE_stWorkingPage.s16WorkingDataCount % 4) ? + u32NVMWordCount : u32NVMWordCount + 1; + boClearOK = TRUE; + + for (u32NVMWordIDX = 0; u32NVMWordIDX < u32NVMWordCount; u32NVMWordIDX++) + { + u32DestinationWord = (uint32)FEEHA_EEPROM_START + 4 * u32NVMWordIDX; + + if (FTFx_OK == u32RetCode) + { + u32RetCode = pEEEWrite(&FEE_stFlashSSDConfig, + u32DestinationWord, 4, (uint32)&u32SourceWord); + } + else + { + boClearOK = false; + } + } + } + } +#endif //BUILD_MK60 + +#if defined(BUILD_MK64) + bool boEraseErr = TRUE; + + if (0 == FEE_u32InhibitNVMCount) + { + boEraseErr = FEEHA_boEraseForDownload((uint8*)FEEHA_DFLASH_START, FEEHA_DFLASH_END - FEEHA_DFLASH_START + 1); + } + + boClearOK = false == boEraseErr ? TRUE : FALSE; +#endif //BUILD_MK64 + + return boClearOK; +} + +bool FEEHA_boEraseForDownload(puint8 pu8TargetAddress, uint32 u32EraseCount) +{ + tstFTFEModule* pstFTFE; + uint32 u32ReturnCode; + uint16 u16WordCount; + uint16 u16SectorEraseCount; + uint32* pu32SectorWord; + puint32 pu32TargetAddress; + bool boEraseErr = false; + FEE_enPgmErrCode = enErrNone; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + pstFTFE = FTFE; + if (((pstFTFE -> FSTAT) & FTFE_FSTAT_CCIF_MASK) == FTFE_FSTAT_CCIF_MASK) + { + if (((pstFTFE -> FSTAT) & FTFE_FSTAT_ACCERR_MASK) == FTFE_FSTAT_ACCERR_MASK) + { + pstFTFE -> FSTAT &= FTFE_FSTAT_ACCERR_MASK; + } + + if (((pstFTFE -> FSTAT) & FTFE_FSTAT_FPVIOL_MASK) == FTFE_FSTAT_FPVIOL_MASK) + { + pstFTFE -> FSTAT &= FTFE_FSTAT_FPVIOL_MASK; + } + + if (0 == (uint32)pu8TargetAddress % 4) + { + pu32TargetAddress = (puint32)(uint32)pu8TargetAddress; + } + else + { + pu32TargetAddress = (puint32)0xffffffff; + } + + /* PFLASH erase */ +#if (0 < FEE_PFLASH_START) + if (((uint32)pu32TargetAddress >= FEE_PFLASH_START) && + (((uint32)pu32TargetAddress + u32EraseCount <= FEE_PFLASH_END))) +#else + if ((uint32)pu32TargetAddress + u32EraseCount <= FEEHA_PFLASH_END) +#endif + { + u16WordCount = u32EraseCount / FEEHA_PFLASH_BYTES_WORD; + + if (((uint32)pu32TargetAddress % FEEHA_PFLASH_BYTES_WORD) != 0) + { + /* abort on non-word boundary */ + boEraseErr = true; + } + else + { + /* calculate target sector count */ + if (u16WordCount > FEEHA_PFLASH_SCTR_WORDS) + { + if ((u16WordCount % FEEHA_PFLASH_SCTR_WORDS) == 0) + { + u16SectorEraseCount = u16WordCount / FEEHA_PFLASH_SCTR_WORDS; + } + else + { + u16SectorEraseCount = u16WordCount / FEEHA_PFLASH_SCTR_WORDS + 1; + } + } + else + { + u16SectorEraseCount = 1; + } + + pu32SectorWord = (uint32*)((uint32)pu32TargetAddress - ((uint32)pu32TargetAddress % FEEHA_PFLASH_SCTR_WORDS)); + + while(u16SectorEraseCount-- > 0) + /* erase any target sectors that are not erased */ + { + u32ReturnCode = FlashVerifySection(&FEE_stFlashSSDConfig, (uint32)pu32SectorWord, u16WordCount, enMarginNormal, pFlashCommandSequence); + + if (((pstFTFE -> FSTAT) & FTFE_FSTAT_MGSTAT0_MASK) == FTFE_FSTAT_MGSTAT0_MASK) + /* erase sector not blank */ + { + u32ReturnCode = FlashEraseSector(&FEE_stFlashSSDConfig, (uint32)pu32SectorWord, FTFx_PSECTOR_SIZE, pFlashCommandSequence); + boEraseErr = 0 != u32ReturnCode ? true : boEraseErr; + } + + /* update the sector base pointer to next sector */ + pu32SectorWord = (uint32*)((uint32)pu32SectorWord + FEEHA_PFLASH_SCTR_BYTES); + } + } + } + /* DFLASH erase */ + else if (((uint32)pu32TargetAddress >= FEEHA_DFLASH_START) && + (((uint32)pu32TargetAddress + u32EraseCount <= (FEEHA_DFLASH_END + 1)))) + { + if ((FEEHA_DFLASH_END - FEEHA_DFLASH_START + 1) == u32EraseCount) + { + u32ReturnCode = FlashEraseBlock (&FEE_stFlashSSDConfig, (uint32)pu8TargetAddress, pFlashCommandSequence); + boEraseErr = 0 == u32ReturnCode ? FALSE : TRUE; + } + } + else + { + boEraseErr = true; + } + } +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + + +#endif //BUILD_SAM3X8E + + return boEraseErr; +} + +static bool FEEHA_boPartitionDFlash(void) +{ + tstFTFEModule* pstFTFE; + uint32* pu32SectorWord; + + bool boWriteErr = false; + + FEE_enPgmErrCode = enErrNone; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + pstFTFE = FTFE; + + if (((pstFTFE -> FSTAT) & FTFE_FSTAT_CCIF_MASK) == FTFE_FSTAT_CCIF_MASK) + { + if (((pstFTFE -> FSTAT) & FTFE_FSTAT_ACCERR_MASK) == FTFE_FSTAT_ACCERR_MASK) + { + pstFTFE -> FSTAT &= FTFE_FSTAT_ACCERR_MASK; + } + + if (((pstFTFE -> FSTAT) & FTFE_FSTAT_FPVIOL_MASK) == 0) + { + pstFTFE -> FSTAT &= FTFE_FSTAT_FPVIOL_MASK; + } + + if (((pstFTFE -> FCNFG) & FTFE_FCNFG_EEERDY_MASK) != FTFE_FCNFG_EEERDY_MASK) + /* If DFlash not already partitioned */ + { + pu32SectorWord = (uint32*)FEEHA_DFLASH_START; + returnCode = FlashVerifyBlock(&FEE_stFlashSSDConfig, (uint32)pu32SectorWord, enMarginNormal, pFlashCommandSequence); + + if (((pstFTFE -> FSTAT) & FTFE_FSTAT_MGSTAT0_MASK) == FTFE_FSTAT_MGSTAT0_MASK) + /* Erase sector not blank */ + { + FEE_boEraseForDownload((puint8)FEEHA_DFLASH_START, FEEHA_DFLASH_END - FEEHA_DFLASH_START + 1); + } + + /* Partition DFlash */ + returnCode = pDEFlashPartition(&FEE_stFlashSSDConfig, 0x00, 0x08, pFlashCommandSequence); + + while(FEEHA_xWaitCmdToComplete()) {} + + //pSetEEEEnable(&FEE_stFlashSSDConfig, 0x00); + } + } +#endif //BUILD_MK6X + + return boWriteErr; +} + +bool FEEHA_boWriteSector(void) +{ + tstFTFEModule* pstFTFE; + uint32* pu32ProgramWord; + uint32* pu32SourceWord; + uint32* pu32SectorWord; + uint16 u16WordCount; + uint16 u16ByteCount; + bool boWriteErr = false; + + FEE_enPgmErrCode = enErrNone; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + pstFTFE = FTFE; + if (((pstFTFE -> FSTAT) & FTFE_FSTAT_CCIF_MASK) == FTFE_FSTAT_CCIF_MASK) + { + if (((pstFTFE -> FSTAT) & FTFE_FSTAT_ACCERR_MASK) == FTFE_FSTAT_ACCERR_MASK) + { + pstFTFE -> FSTAT &= FTFE_FSTAT_ACCERR_MASK; + } + + if (((pstFTFE -> FSTAT) & FTFE_FSTAT_FPVIOL_MASK) == 0) + { + pstFTFE -> FSTAT &= FTFE_FSTAT_FPVIOL_MASK; + } + + /* PFLASH program */ +#if (0 < FEE_PFLASH_START) + if (((uint32)FEE_stWriteControlBlock.pu8TargetAddress >= FEE_PFLASH_START) && + (((uint32)FEE_stWriteControlBlock.pu8TargetAddress + + (FEE_PFLASH_SCTR_BYTES - 1) <= (uint32)FEE_PFLASH_END))) +#else + if (((uint32)FEE_stWriteControlBlock.pu8TargetAddress + + (FEEHA_PFLASH_SCTR_BYTES - 1) <= (uint32)FEEHA_PFLASH_END)) +#endif + { + if (FEEHA_PFLASH_SCTR_BYTES < FEE_stWriteControlBlock.u32WriteCount) + { + u16WordCount = FEEHA_PFLASH_SCTR_BYTES / FEEHA_PFLASH_BYTES_WORD; + u16ByteCount = FEEHA_PFLASH_SCTR_BYTES; + } + else + { + if (0 == (FEE_stWriteControlBlock.u32WriteCount % FEEHA_PFLASH_BYTES_WORD)) + { + u16WordCount = FEE_stWriteControlBlock.u32WriteCount / FEEHA_PFLASH_BYTES_WORD; + } + else + { + u16WordCount = (FEE_stWriteControlBlock.u32WriteCount / FEEHA_PFLASH_BYTES_WORD) + 1; + } + + u16ByteCount = u16WordCount * FEEHA_PFLASH_BYTES_WORD; + } + + pu32ProgramWord = (uint32*)FEE_stWriteControlBlock.pu8TargetAddress; + pu32SourceWord = (uint32*)&FEE_au8ProgBuff[0]; + + if (((uint32)pu32ProgramWord % FEEHA_PFLASH_BYTES_WORD) != 0) + { + /* abort on non-word boundary */ + u16WordCount = 0; + } + + pu32SectorWord = (uint32*)((uint32)pu32ProgramWord - ((uint32)pu32ProgramWord % FEEHA_PFLASH_SCTR_WORDS)); + returnCode = FlashVerifySection(&FEE_stFlashSSDConfig, (uint32)pu32SectorWord, u16WordCount, enMarginNormal, pFlashCommandSequence); + + if (((pstFTFE -> FSTAT) & FTFE_FSTAT_MGSTAT0_MASK) == FTFE_FSTAT_MGSTAT0_MASK) + /* erase sector not blank */ + { + boWriteErr = true; + u16WordCount = 0; + u8WriteCount = 0x34; + } + + /* program PFLASH words */ + if (u16WordCount > 0) + { + /* copy large diag buffer to RAM accelaration buffer */ + memcpy((void*)EERAM_BLOCK_BASE, (void*)pu32SourceWord, (uint32)u16ByteCount); + + /* program the values to PFLASH */ + if (0 == (u16ByteCount % FEEHA_PFLASH_BYTES_PHRS)) + { + phraseNumber = u16ByteCount / FEEHA_PFLASH_BYTES_PHRS; + } + else + { + phraseNumber = u16ByteCount / FEEHA_PFLASH_BYTES_PHRS + 1; + } + + destination = (uint32)pu32ProgramWord; + returnCode = pFlashProgramSection(&FEE_stFlashSSDConfig, destination, phraseNumber, pFlashCommandSequence); + if (FTFx_OK != returnCode) + { + u16WordCount = 0; + } + + u8WriteCount++; + + /* update write address and decrement write count */ + FEE_stWriteControlBlock.pu8TargetAddress += FEEHA_PFLASH_SCTR_BYTES; + + if (FEEHA_PFLASH_SCTR_BYTES < FEE_stWriteControlBlock.u32WriteCount) + { + FEE_stWriteControlBlock.u32WriteCount -= FEEHA_PFLASH_SCTR_BYTES; + } + else + { + FEE_stWriteControlBlock.u32WriteCount = 0; + FEE_stWriteControlBlock.boProgramming = false; + } + } + } + else + { + boWriteErr = true; + u8WriteCount = 0x55; + } + + while(FEEHA_xWaitCmdToComplete()) {} + } +#endif //BUILD_MK6X + + return boWriteErr; +} + + +bool FEEHA_boStart(uint32* const u32Stat) +{ + bool boStartOK = false; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + u8WriteCount = 0; + unsecure_key = 0xFFFFFFFE; + + REGSET_vInitReg8(&FEEHA_rastFTFEReg8Val[0]); + FEEHA_vInitFlashConfig(); + + returnCode = pFlashInit(&FEE_stFlashSSDConfig); + + if (FTFx_OK == returnCode) + { + FEE_stWriteControlBlock.boProgramming = false; + FEE_stWriteControlBlock.boProgErr = false; + boStartOK = true; + } +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + uint32 u32Err; + + u32Err = flash_init(128u, 10u); + + if (FLASH_RC_OK == u32Err) + { + FEE_stWriteControlBlock.boProgramming = false; + FEE_stWriteControlBlock.boProgErr = false; + boStartOK = true; + } +#endif + + return boStartOK; +} + +void FEEHA_vRun(uint32* const u32Stat) +{ + FEE_u32RunCount++; + + if (0 < FEE_u32InhibitNVMCount) + { + FEE_u32InhibitNVMCount--; + } +} + +void FEEHA_vTerminate(uint32* const u32Stat) +{ + +} + +bool FEEHA_boPartition(void) +{ + bool boRetVal; + + boRetVal = FEEHA_boPartitionDFlash(); + + return boRetVal; +} + +bool FEEHA_boWriteControlBlock(COMMONNL_tstRXLargeBuffer* const pstParamSourceBuffer, + uint8* const pu8ParamTargetAddress, + uint32 u32ParamWriteCount) +{ + if ((false == FEE_stWriteControlBlock.boProgramming) && + (false == FEE_stWriteControlBlock.boProgErr)) + { + FEE_stWriteControlBlock.pstSourceBuffer = pstParamSourceBuffer; + FEE_stWriteControlBlock.pu8TargetAddress = pu8ParamTargetAddress; + FEE_stWriteControlBlock.u32WriteCount = u32ParamWriteCount; + FEE_stWriteControlBlock.u32AccumulateCount = 0; + FEE_stWriteControlBlock.boProgramming = true; + } + else + { + FEE_stWriteControlBlock.boProgramming = false; + } + + return FEE_stWriteControlBlock.boProgramming; +} + +bool FEEHA_boUpdateControlBlock(uint32 u32BlockWriteCount) +{ + puint8 pu8SourceData; + puint8 pu8BufferData; + + if (FEE_stWriteControlBlock.boProgramming == true) + { + if ((FEEHA_PFLASH_SCTR_BYTES >= + (u32BlockWriteCount + FEE_stWriteControlBlock.u32AccumulateCount)) && + (0 != u32BlockWriteCount)) + { + pu8SourceData = (puint8)&FEE_stWriteControlBlock.pstSourceBuffer->u8Data[0]; + pu8BufferData = (puint8)((uint32)&FEE_au8ProgBuff + FEE_stWriteControlBlock.u32AccumulateCount); + + memcpy((void*)pu8BufferData, (void*)pu8SourceData, u32BlockWriteCount); + + FEE_stWriteControlBlock.u32AccumulateCount += u32BlockWriteCount; + + if (FEEHA_PFLASH_SCTR_BYTES == FEE_stWriteControlBlock.u32AccumulateCount) + { + FEE_stWriteControlBlock.u32AccumulateCount = 0; + /* TODO FEE_boWriteSector(); */ + } + else if (FEEHA_PFLASH_SCTR_BYTES < FEE_stWriteControlBlock.u32AccumulateCount) + { + /* Uh oh too many bytes received - ran past the sector size */ + /* matthew deal with this */ + FEE_stWriteControlBlock.boProgramming = false; + } + else if (FEE_stWriteControlBlock.u32WriteCount <= FEE_stWriteControlBlock.u32AccumulateCount) + { + FEE_stWriteControlBlock.u32AccumulateCount = 0; + /* TODO FEE_boWriteSector(); */ + } + } + else + { + FEE_stWriteControlBlock.boProgramming = false; + } + } + + return FEE_stWriteControlBlock.boProgramming; +} + + +static bool FEEHA_boGetSem(bool boGet) +{ + static bool FEE_boSem = false; + bool boRetVal = false; + + if (TRUE == boGet) + { + if (false == FEE_boSem) + { + FEE_boSem = TRUE; + boRetVal = TRUE; + } + } + else + { + FEE_boSem = FALSE; + boRetVal = TRUE; + } + + return boRetVal; +} + +static void FEEHA_vInitFlashConfig(void) +{ +#if defined(BUILD_MK60) || defined(BUILD_MK64) + FEE_stFlashSSDConfig.ftfxRegBase = FTFx_REG_BASE; + FEE_stFlashSSDConfig.PFlashBlockBase = PFLASH_BLOCK_BASE; + FEE_stFlashSSDConfig.PFlashBlockSize = PBLOCK_SIZE; + FEE_stFlashSSDConfig.DFlashBlockBase = DEFLASH_BLOCK_BASE; + FEE_stFlashSSDConfig.DFlashBlockSize = 0; + FEE_stFlashSSDConfig.EERAMBlockBase = EERAM_BLOCK_BASE; + FEE_stFlashSSDConfig.EERAMBlockSize = EERAM_BLOCK_SIZE; + FEE_stFlashSSDConfig.EEEBlockSize = 0; + FEE_stFlashSSDConfig.DebugEnable = DEBUGENABLE; + FEE_stFlashSSDConfig.CallBack = NULL_CALLBACK; +#endif //BUILD_MK6X +} + +static uint8* FEEHA_pu8GetPartitionAddress(void) +{ + uint8* pu8NVRecordBase = (uint8*)~0; +#if defined(BUILD_MK64) + pu8NVRecordBase = (uint8*)(FEEHA_DFLASH_END - FEEHA_WORK_DATA_MAX + 1); + + while (((uint8*)FEEHA_DFLASH_START) <= pu8NVRecordBase) + { + if (0xff != *pu8NVRecordBase) //caveat!!!! + { + break; + } + + pu8NVRecordBase -= FEEHA_WORK_DATA_MAX; + } +#endif //BUILD_MK64 + + return pu8NVRecordBase; +} + +static uint8* FEEHA_pu8GetFreePartitionAddress(void) +{ + uint8* pu8NVFreeBase; + uint8* pu8RetVal = (uint8*)~0; +#if defined(BUILD_MK64) + pu8NVFreeBase = (uint8*)FEEHA_DFLASH_START; + bool boEraseErr; + + while (((uint8*)FEEHA_DFLASH_END) > pu8NVFreeBase) + { + if (0xff == *pu8NVFreeBase) //caveat!!!! + { + pu8RetVal = pu8NVFreeBase; + break; + } + + pu8NVFreeBase += FEEHA_WORK_DATA_MAX; + } + + + if (((uint8*)~0) == pu8RetVal) + { + boEraseErr = FEEHA_boEraseForDownload((uint8*)FEEHA_DFLASH_START, FEEHA_DFLASH_END - FEEHA_DFLASH_START + 1); + + if (FALSE == boEraseErr) + { + pu8RetVal = (uint8*)FEEHA_DFLASH_START; + } + } +#endif //BUILD_MK64 + + return pu8RetVal; +} + + diff --git a/source/Peripherals/FEEHA.h b/source/Peripherals/FEEHA.h new file mode 100644 index 0000000..944942e --- /dev/null +++ b/source/Peripherals/FEEHA.h @@ -0,0 +1,200 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef FEEHA_H +#define FEEHA_H + +#include +#include +#include "COMMONNL.h" +#include "CRC16.h" +#include "declarations.h" +#include "DLL.h" +#include "FEE.h" +#include "IOAPI.h" +#include "macros.h" +#include "os.h" +#include "regset.h" +#include "sys.h" +#include "types.h" + + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +#include "SSD_Types.h" +#include "SSD_FTFx.h" +#include "SSD_FTFx_Internal.h" +//#include "NormalDemo.h" + +#define M8(adr) (*((volatile unsigned char *) (adr))) +#define M16(adr) (*((volatile unsigned short *) (adr))) +#define M32(adr) (*((volatile unsigned long *) (adr))) + +// FEE programming interface address ranges +#define FEEHA_PFLASH_START 0x00000000u // Program Flash base address +#define FEEHA_PFLASH_END 0x0007FFFFu // Program Flash end address +#define FEEHA_DFLASH_START 0x10000000u // Data Flash base address +#define FEEHA_DFLASH_END 0x1001FFFFu // Data Flash end address +#define FEEHA_EEPROM_START 0x14000000u // EEprom Base address +#define FEEHA_EEPROM_END 0x14003FFFu // EEprom Base address +#define FEEHA_WORK_DATA_START 0x20000000u +#define FEEHA_WORK_DATA_END 0x2001FFFFu +#define FEEHA_WORK_DATA_MAX 0x4000u + +// FEE sector sizes +#define FEEHA_PFLASH_SCTR_BYTES 4096u // Program Flash bytes per sector +#define FEEHA_DFLASH_SCTR_BYTES 4096u // Data Flash bytes per sector +#define FEEHA_EEPROM_SCTR_BYTES 1024u // EEprom bytes per sector + +#define FEEHA_PFLASH_BYTES_PHRS 0x10 // Program Flash bytes per phrase +#define FEEHA_DFLASH_BYTES_PHRS 0x10 // Data Flash bytes per phrase +#define FEEHA_EEPROM_BYTES_PHRS 0x10 // EEprom bytes per phrase + +#define FEEHA_PFLASH_BYTES_WORD 0x08 // Program Flash bytes per word +#define FEEHA_DFLASH_BYTES_WORD 0x08 // Data Flash bytes per word +#define FEEHA_EEPROM_BYTES_WORD 0x01 // EEprom bytes per word + +#define FEEHA_PFLASH_SCTR_WORDS (FEEHA_PFLASH_SCTR_BYTES / FEEHA_PFLASH_BYTES_WORD) +#define FEEHA_DFLASH_SCTR_WORDS (FEEHA_DFLASH_SCTR_BYTES / FEEHA_DFLASH_BYTES_WORD) +#define FEEHA_EEPROM_SCTR_WORDS (FEEHA_EEPROM_SCTR_BYTES / FEEHA_EEPROM_BYTES_WORD) + +#define FEEHA_PFLASH_SCTR_PHRS (FEEHA_PFLASH_SCTR_BYTES / FEEHA_PFLASH_BYTES_PHRS) +#define FEEHA_DFLASH_SCTR_PHRS (FEEHA_DFLASH_SCTR_BYTES / FEEHA_DFLASH_BYTES_PHRS) +#define FEEHA_EEPROM_SCTR_PHRS (FEEHA_EEPROM_SCTR_BYTES / FEEHA_EEPROM_BYTES_PHRS) + +// FEE Commands +#define FEEHA_CMD_READ1SB 0x00 // Verify block erased +#define FEEHA_CMD_READ1SS 0x01 // Verify section erased +#define FEEHA_CMD_PRGCHK 0x02 // Checks programmed phrases at margin read +#define FEEHA_CMD_READIFR 0x03 // READ IFR field +#define FEEHA_CMD_PRG 0x07 // Program 8 bytes +#define FEEHA_CMD_ERASEB 0x08 // Erase Flash block +#define FEEHA_CMD_ERASES 0x09 // Erase Flash sector +#define FEEHA_CMD_PRGS 0x0B // program data from section program buffer +#define FEEHA_CMD_READ1SL 0x40 // Verify all blocks erased +#define FEEHA_CMD_ERASEL 0x44 // Erase all blocks + +// FEE constants +#define FEEHA_PFLASH_PRT3 0xFF +#define FEEHA_PFLASH_PRT2 0xFF +#define FEEHA_PFLASH_PRT1 0xFF +#define FEEHA_PFLASH_PRT0 0xFE +#define FEEHA_DFLASH_PROT 0xFF +#define FEEHA_EFLASH_PROT 0xFF +#define FEEHA_SEC 0x02 + +// FEE records addresses +#define FEEHA_ADCREC_ADDRESS 0x14003FC0u + +// FEE macros +#define FEEHA_xWaitCmdToComplete() ((pstFTFE -> FSTAT) & FTFE_FSTAT_CCIF_MASK) != FTFE_FSTAT_CCIF_MASK + +typedef FTFE_Type tstFTFEModule; +typedef FLASH_SSD_CONFIG tstFTFEConfig; + + +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E +typedef Efc tstFTFEModule; +typedef struct +{ + bool boDummy; +} tstFTFEConfig;//matthew to be found in driver later + +// FEE programming interface address ranges +#define FEEHA_PFLASH_START 0x00000000u // Program Flash base address +#define FEEHA_PFLASH_END 0x0007FFFFu // Program Flash end address +#define FEEHA_DFLASH_START 0x10000000u // Data Flash base address +#define FEEHA_DFLASH_END 0x1007FFFFu // Data Flash end address +#define FEEHA_EEPROM_START 0x000c0000u // EEprom Base address +#define FEEHA_EEPROM_END 0x000c7FFFu // EEprom Base address +#define FEEHA_WORK_DATA_START 0x20070000u +#define FEEHA_WORK_DATA_END 0x2007FFFFu +#define FEEHA_WORK_DATA_MAX 0x4000u + +#define FEEHA_EXC_RECS_START (FEEHA_EEPROM_START + 0x7000) +#define FEEHA_EXC_RECS_END (FEEHA_EEPROM_START + 0x7000 + 0xfff) + +// FEE sector sizes +#define FEEHA_PFLASH_SCTR_BYTES 4096u // Program Flash bytes per sector +#define FEEHA_DFLASH_SCTR_BYTES 4096u // Data Flash bytes per sector +#define FEEHA_EEPROM_SCTR_BYTES 1024u // EEprom bytes per sector + +#define FEEHA_PFLASH_BYTES_PHRS 0x10 // Program Flash bytes per phrase +#define FEEHA_DFLASH_BYTES_PHRS 0x10 // Data Flash bytes per phrase +#define FEEHA_EEPROM_BYTES_PHRS 0x10 // EEprom bytes per phrase + +#define FEEHA_PFLASH_BYTES_WORD 0x08 // Program Flash bytes per word +#define FEEHA_DFLASH_BYTES_WORD 0x08 // Data Flash bytes per word +#define FEEHA_EEPROM_BYTES_WORD 0x01 // EEprom bytes per word + +#define FEEHA_PFLASH_SCTR_WORDS (FEEHA_PFLASH_SCTR_BYTES / FEEHA_PFLASH_BYTES_WORD) +#define FEEHA_DFLASH_SCTR_WORDS (FEEHA_DFLASH_SCTR_BYTES / FEEHA_DFLASH_BYTES_WORD) +#define FEEHA_EEPROM_SCTR_WORDS (FEEHA_EEPROM_SCTR_BYTES / FEEHA_EEPROM_BYTES_WORD) + +#define FEEHA_PFLASH_SCTR_PHRS (FEEHA_PFLASH_SCTR_BYTES / FEEHA_PFLASH_BYTES_PHRS) +#define FEEHA_DFLASH_SCTR_PHRS (FEEHA_DFLASH_SCTR_BYTES / FEEHA_DFLASH_BYTES_PHRS) +#define FEEHA_EEPROM_SCTR_PHRS (FEEHA_EEPROM_SCTR_BYTES / FEEHA_EEPROM_BYTES_PHRS) + +#endif //BUILD_SAM3X8E + + +#ifdef BUILD_MK60 +#define FEEHA_nReg8Set \ +{ \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FPROT3)), (uint8)FEE_PFLASH_PRT3, REGSET_enOverwrite }, \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FPROT2)), (uint8)FEE_PFLASH_PRT2, REGSET_enOverwrite }, \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FPROT1)), (uint8)FEE_PFLASH_PRT1, REGSET_enOverwrite }, \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FPROT0)), (uint8)FEE_PFLASH_PRT0, REGSET_enOverwrite }, \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FDPROT)), (uint8)FEE_DFLASH_PROT, REGSET_enOverwrite }, \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FEPROT)), (uint8)FEE_EFLASH_PROT, REGSET_enOverwrite }, \ + { NULL, 0, REGSET_enOverwrite } \ +} +#endif + +#ifdef BUILD_MK64 +#define FEEHA_nReg8Set \ +{ \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FPROT3)), (uint8)FEEHA_PFLASH_PRT3, REGSET_enOverwrite }, \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FPROT2)), (uint8)FEEHA_PFLASH_PRT2, REGSET_enOverwrite }, \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FPROT1)), (uint8)FEEHA_PFLASH_PRT1, REGSET_enOverwrite }, \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FPROT0)), (uint8)FEEHA_PFLASH_PRT0, REGSET_enOverwrite }, \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FDPROT)), (uint8)FEEHA_DFLASH_PROT, REGSET_enOverwrite }, \ + { (volatile uint8*)(FTFE_BASE + offsetof(FTFE_Type, FEPROT)), (uint8)FEEHA_EFLASH_PROT, REGSET_enOverwrite }, \ + { NULL, 0, REGSET_enOverwrite } \ +} +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +#define FEEHA_nReg8Set \ +{ \ + { NULL, 0, REGSET_enOverwrite } \ +} +#endif + +bool FEEHA_boStart(uint32* const); +void FEEHA_vRun(uint32* const); +void FEEHA_vTerminate(uint32* const); +void FEEHA_vStartSBL(void); +bool FEEHA_boCheckPartition(void); +bool FEEHA_boSetWorkingData(puint8, uint16); +bool FEEHA_boNVMWorkingCopy(bool, bool); +bool FEEHA_boNVMClear(void); +bool FEEHA_boPartition(void); +bool FEEHA_boWriteControlBlock(COMMONNL_tstRXLargeBuffer* const, + uint8* const, + uint32); +bool FEEHA_boUpdateControlBlock(uint32); +bool FEEHA_boEraseForDownload(puint8, uint32); +bool FEEHA_boWriteNVM(puint8, puint8, uint32); +bool FEEHA_boWriteSector(void); +#endif //FEEHA_H + diff --git a/source/Peripherals/IIC.c b/source/Peripherals/IIC.c new file mode 100644 index 0000000..54bbdeb --- /dev/null +++ b/source/Peripherals/IIC.c @@ -0,0 +1,54 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include "IIC.h" +#include "IICHA.h" +#include "SYSAPI.h" + + +void IIC_vStart(puint32 const pu32Stat) +{ + IICHA_vStart(pu32Stat); +} + +void IIC_vRun(puint32 const pu32Stat) +{ + +} + +void IIC_vTerminate(puint32 const pu32Stat) +{ + +} + +SYSAPI_tenSVCResult IIC_enInitBus(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tstPortConfigCB* pstPortConfigCB) +{ + return IICHA_enInitBus(enEHIOResource, pstPortConfigCB); +} + +void IIC_vInitTransfer(IOAPI_tstTransferCB* pstTransferCB) +{ + IICHA_vInitTransfer(pstTransferCB); +} + +void IIC_vInterrupt(IOAPI_tenEHIOResource enEHIOResource) +{ + IICHA_vInterrupt(enEHIOResource); +} + + + + + + + + + diff --git a/source/Peripherals/IIC.h b/source/Peripherals/IIC.h new file mode 100644 index 0000000..272afd3 --- /dev/null +++ b/source/Peripherals/IIC.h @@ -0,0 +1,27 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef IIC_H +#define IIC_H + +#include "IOAPI.h" +#include "SYSAPI.h" +#include "types.h" + +void IIC_vStart(puint32 const); +void IIC_vRun(puint32 const); +void IIC_vTerminate(puint32 const); +SYSAPI_tenSVCResult IIC_enInitBus(IOAPI_tenEHIOResource, IOAPI_tstPortConfigCB*); +void IIC_vInitTransfer(IOAPI_tstTransferCB*); +void IIC_vInterrupt(IOAPI_tenEHIOResource); + +#endif //IIC_H + diff --git a/source/Peripherals/IICHA.c b/source/Peripherals/IICHA.c new file mode 100644 index 0000000..82caf22 --- /dev/null +++ b/source/Peripherals/IICHA.c @@ -0,0 +1,202 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include "IICHA.h" + + +const REGSET_tstReg8Val IICHA_rastPIMReg8ValIIC0[] = IICHA_nReg8SetIIC0; +const REGSET_tstReg8Val IICHA_rastPIMReg8ValIIC1[] = IICHA_nReg8SetIIC1; +const IICHA_tstDivisorMap IICHA_rastDivisorMap[] = IICHA_nDivisorMap; +IOAPI_tstTransferCB* IICHA_pstTransferCB; +uint32 IICHA_u32BytesToTransfer; +void* IICHA_pvData; +IOAPI_tpfTransferCB IICHA_pfCB; +tstI2CModule* IICHA_pstIIC; + +uint32 IIC_u32PortClockRequested; + +static sint32 IICHA_u32GetIICIndex(IOAPI_tenEHIOResource); + +void IICHA_vStart(puint32 const u32Stat) +{ + IICHA_pfCB = NULL; + IICHA_pstIIC = NULL; + IICHA_u32BytesToTransfer = 0; + OS_xModuleStartOK(*u32Stat); +} + +void IICHA_vRun(puint32 const pu32Stat) +{ + +} + +void IICHA_vTerminate(puint32 const pu32Stat) +{ + +} + +SYSAPI_tenSVCResult IICHA_enInitBus(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tstPortConfigCB* pstPortConfigCB) +{ + SYSAPI_tenSVCResult enSVCResult = SYSAPI_enResourceAlreadyAllocated; + + sint32 i32IDX = IICHA_u32GetIICIndex(enEHIOResource); + + if ((-1 != i32IDX) && (TRUE == DLL_boInitDLLChannel(enEHIOResource, pstPortConfigCB))) + + switch (enEHIOResource) + { +#ifdef BUILD_MK60 + uint32 u32Mul; + uint32 u32DivCalc; + uint32 u32Div; + uint32 u32DivMapIDX; + tstI2CModule* pstIIC; + IRQn_Type enIRQType; + REGSET_tstReg32Val IIC_astIICReg32Val[3]; + + case EH_VIO_IIC1: + { + IIC_xRequestPortClock(SIM_SCGC4_IIC0_MASK); + + IIC_astIICReg32Val[0].reg = (vpuint32)(PORTD_BASE + offsetof(PORT_Type, PCR[8])); + IIC_astIICReg32Val[0].val = (uint32)(PORT_PCR_MUX(2) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK); + IIC_astIICReg32Val[0].writeMode = REGSET_enOverwrite; + + IIC_astIICReg32Val[1].reg = (vpuint32)(PORTD_BASE + offsetof(PORT_Type, PCR[9])); + IIC_astIICReg32Val[1].val = (uint32)(PORT_PCR_MUX(2) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK); + IIC_astIICReg32Val[1].writeMode = REGSET_enOverwrite; + + IIC_astIICReg32Val[2].reg = NULL; + REGSET_vInitReg32(&IIC_astIICReg32Val[0]); + + enSVCResult = SYSAPI_enBaudRateUnavailable; + pstIIC = I2C0; + + IIC_xRequestPortClock(SIM_SCGC4_IIC0_MASK); + u32Mul = pstPortConfigCB->u32BaudRateHz / (SYS_FREQ_BUS / IIC_rastDivisorMap[0].u32SCLDivider); + u32Mul = (4 < u32Mul) ? 4 : u32Mul; + + switch (u32Mul) + { + case 0: u32Mul = 1; break; + case 3: u32Mul = 2; break; + default: u32Mul = 4; break; + } + + u32DivCalc = SYS_FREQ_BUS / (u32Mul * pstPortConfigCB->u32BaudRateHz); + + if (IIC_rastDivisorMap[63].u32SCLDivider < u32DivCalc) break; + enSVCResult = SYSAPI_enOK; + + IIC_xCalcDivisor; + enIRQType = I2C0_IRQn; + break; + } + case EH_VIO_IIC2: + { + IIC_xRequestPortClock(SIM_SCGC4_IIC1_MASK); + break; + } +#endif //BUILD_MK60 + default: + { + break; + } + } + + if (SYSAPI_enOK == enSVCResult) + { +#ifdef BUILD_MK60 + pstIIC->F = (I2C_F_MULT(u32Mul) | I2C_F_ICR(u32Div)); + pstIIC->C1 |= I2C_C1_IICEN_MASK; + IRQ_vEnableIRQ(enIRQType); +#endif //BUILD_MK60 + } + + return enSVCResult; +} + +void IICHA_vInitTransfer(IOAPI_tstTransferCB* pstTransferCB) +{ + IICHA_pstTransferCB = pstTransferCB; + + switch (pstTransferCB->enEHIOResource) + { +#ifdef BUILD_MK60 + case EH_VIO_IIC1: + { + IICHA_pstIIC = I2C0; + IICHA_u32BytesToTransfer = pstTransferCB->u32ByteCount - 1; + IICHA_pfCB = pstTransferCB->pfCB; + IICHA_pvData = pstTransferCB->pvData; + IICHA_pstIIC->C1 |= (I2C_C1_TX_MASK | I2C_C1_IICIE_MASK | I2C_C1_MST_MASK); + IICHA_pstIIC->D = *(uint8*)IIC_pvData; + IICHA_pvData = (void*)((uint32)IIC_pvData + 1); + } +#endif //BUILD_MK60 + default: + { + break; + } + } + +} + +void IICHA_vInterrupt(IOAPI_tenEHIOResource enEHIOResource) +{ + if (NULL != IICHA_pstIIC) + { +#ifdef BUILD_MK60 + IOAPI_tenPortMode enMode; + IICHA_pstIIC->S |= I2C_S_IICIF_MASK; + + if (0 < IICHA_u32BytesToTransfer) + { + IICHA_pstIIC->D = *(uint8*)IIC_pvData; + IICHA_pvData = (void*)((uint32)IIC_pvData + 1); + IICHA_u32BytesToTransfer -= 1; + } + else + { + IICHA_pstIIC->C1 &= ~(I2C_C1_IICIE_MASK | I2C_C1_MST_MASK); + + enMode = DLL_enGetChannelMode(enEHIOResource); + + if (IOAPI_enPortSerialTransfer == enMode) + { + SRLTFR_vNotifyCB(EH_VIO_IIC1); + } + else if (IOAPI_enPortComms == enMode) + { + //DLL_vFrameRXCB(enEHIOResource, &CAN_stRXDLLData); + } + } +#endif //BUILD_MK60 + } +} + +static sint32 IICHA_u32GetIICIndex(IOAPI_tenEHIOResource enEHIOResource) +{ + sint32 i32IDX = -1; + + if ((EH_VIO_IIC1 <= enEHIOResource) && (EH_VIO_IIC2 >= enEHIOResource)) + { + i32IDX = enEHIOResource - EH_VIO_IIC1; + } + + return i32IDX; +} + + + + + + diff --git a/source/Peripherals/IICHA.h b/source/Peripherals/IICHA.h new file mode 100644 index 0000000..f82cf52 --- /dev/null +++ b/source/Peripherals/IICHA.h @@ -0,0 +1,186 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef IICHA_H +#define IICHA_H + +#include +#include "CPUAbstract.h" +#include "declarations.h" +#include "DLL.h" +#include "IOAPI.h" +#include "MATH.h" +#include "OS.h" +#include "PIM.h" +#include "PIMAPI.h" +#include "regset.h" +#include "RESM.h" +#include "SIM.h" +#include "SRLTFR.h" +#include "sys.h" +#include "types.h" + +#ifdef BUILD_MK60 +#define IICHA_nReg8SetIIC0 \ +{ \ + { (volatile uint8*)(I2C0_BASE + offsetof(I2C_Type, C1)), (uint8)I2C_C1_IICEN_MASK, REGSET_enOverwrite }, \ + { NULL, 0, REGSET_enOverwrite } \ +}; +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +#define IICHA_nReg8SetIIC0 \ +{ \ + { (volatile uint8*)(I2C0_BASE + offsetof(I2C_Type, C1)), (uint8)I2C_C1_IICEN_MASK, REGSET_enOverwrite }, \ + { NULL, 0, REGSET_enOverwrite } \ +}; +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +#define IICHA_nReg8SetIIC0 \ +{ \ + { NULL, 0, REGSET_enOverwrite } \ +}; +#endif //BUILD_SAM3X8E + +#ifdef BUILD_MK60 +#define IICHA_nReg8SetIIC1 \ +{ \ + { (volatile uint8*)(I2C1_BASE + offsetof(I2C_Type, C1)), (uint8)I2C_C1_IICEN_MASK, REGSET_enOverwrite }, \ + { NULL, 0, REGSET_enOverwrite } \ +}; +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +#define IICHA_nReg8SetIIC1 \ +{ \ + { (volatile uint8*)(I2C1_BASE + offsetof(I2C_Type, C1)), (uint8)I2C_C1_IICEN_MASK, REGSET_enOverwrite }, \ + { NULL, 0, REGSET_enOverwrite } \ +}; +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +#define IICHA_nReg8SetIIC1 \ +{ \ + { NULL, 0, REGSET_enOverwrite } \ +}; +#endif //BUILD_SAM3X8E + +#define IICHA_nDivisorMap \ +{ \ + {20, 7}, \ + {22, 7}, \ + {24, 8}, \ + {26, 8}, \ + {28, 9}, \ + {30, 9}, \ + {34, 10}, \ + {40, 10}, \ + {28, 7}, \ + {32, 7}, \ + {36, 9}, \ + {40, 9}, \ + {44, 11}, \ + {48, 11}, \ + {56, 13}, \ + {68, 13}, \ + {48, 9}, \ + {56, 9}, \ + {64, 13}, \ + {72, 13}, \ + {80, 17}, \ + {88, 17}, \ + {104, 21}, \ + {128, 21}, \ + {80, 9}, \ + {96, 9}, \ + {112, 17}, \ + {128, 17}, \ + {144, 25}, \ + {160, 25}, \ + {192, 33}, \ + {240, 33}, \ + {160, 17}, \ + {192, 17}, \ + {224, 33}, \ + {256, 33}, \ + {288, 49}, \ + {320, 49}, \ + {384, 65}, \ + {480, 65}, \ + {320, 33}, \ + {384, 33}, \ + {448, 65}, \ + {512, 65}, \ + {576, 97}, \ + {640, 97}, \ + {768, 129}, \ + {960, 129}, \ + {640, 65}, \ + {768, 65}, \ + {896, 129}, \ + {1024, 129}, \ + {1152, 193}, \ + {1280, 193}, \ + {1536, 257}, \ + {1920, 257}, \ + {1280, 129}, \ + {1536, 129}, \ + {1792, 257}, \ + {2048, 257}, \ + {2304, 385}, \ + {2560, 385}, \ + {3072, 513}, \ + {3840, 513} \ +} + +#define IIC_xRequestPortClock(x) \ +/* turn on clock */ \ +SIM_vSetReg32(SIM_SCGC4, x); \ +IIC_u32PortClockRequested |= x + +#define IIC_xCalcDivisor \ +for (u32DivMapIDX = 0; \ + u32DivMapIDX < (sizeof(IIC_rastDivisorMap) / sizeof(IIC_tstDivisorMap)); \ + u32DivMapIDX++) \ +{ \ + u32Div = u32DivMapIDX; \ + if (IIC_rastDivisorMap[u32DivMapIDX].u32SCLDivider > u32DivCalc) break; \ +} + +typedef struct +{ + uint32 u32SCLDivider; + uint32 u32SDAHold; +} IICHA_tstDivisorMap; + +#ifdef BUILD_MK60 +typedef I2C_Type tstI2CModule; +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +typedef I2C_Type tstI2CModule; +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +typedef Twi tstI2CModule; +#endif //BUILD_SAM3X8E + + +void IICHA_vStart(puint32 const); +void IICHA_vRun(puint32 const); +void IICHA_vTerminate(puint32 const); +SYSAPI_tenSVCResult IICHA_enInitBus(IOAPI_tenEHIOResource, IOAPI_tstPortConfigCB*); +void IICHA_vInitTransfer(IOAPI_tstTransferCB*); +void IICHA_vInterrupt(IOAPI_tenEHIOResource); + +#endif //IICHA_H + diff --git a/source/Peripherals/PERADC.c b/source/Peripherals/PERADC.c new file mode 100644 index 0000000..4263c28 --- /dev/null +++ b/source/Peripherals/PERADC.c @@ -0,0 +1,407 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#include +#include "CPUAbstract.h" +#include "IOAPI.h" +#include "ADCAPI.h" +#include "types.h" +#include "ADCHA.h" +#include "PERADC.h" +#include "client.h" +#include "CQUEUE.h" +#include "CRC16.h" +#include "declarations.h" +#include "FEE.h" +#include "IRQ.h" +#include "MSG.h" +#include "regset.h" +#include "SIM.h" +#include "sys.h" + +ADCHA_tstADCConversion ADC_astADCConversions[ADCHA_enQueueCount][ADC_nConversionsMax]; +CQUEUE_tstQueue ADC_astConversionQueue[ADCHA_enQueueCount]; +bool ADC_boCyclicQueuePending; +ADC_tstADCResult ADC_astResult[ADCHA_enQueueCount][ADC_nConversionsMax]; +MSG_tstMBX* ADC_apstMBX[ADCHA_enQueueCount][ADC_nConversionsMax]; +sint32 ADC_i32CyclicQueueIDX; + +/* Array to determine which queue triggered the last module conversion. Allows + same AD channel to appear in different queues! */ +ADCHA_tenQueue ADC_astADCActiveQueue[ADCHA_enADCModuleCount]; + +static bool ADC_boInitiateConversion(ADCHA_tstADCConversion*, ADCHA_tenQueue, uint32); + +#ifdef ADC_CALIBRATE +static void ADC_vCalibrate(tstADCModule*, uint32, uint32); +#endif //ADC_CALIBRATE + +#ifdef BUILD_MK60 +static void ADC_vInitInterrupts(IRQn_Type); +#endif //BUILD_MK60 + +static void ADC_vRunConversionQueues(void); + + +void ADC_vStart(uint32* const pu32Stat) +{ + uint32 u32QueueIDX; + uint32 u32QueueElementIDX; + + for (u32QueueIDX = 0; u32QueueIDX < ADCHA_enQueueCount; u32QueueIDX++) + { + for (u32QueueElementIDX = 0; u32QueueElementIDX < ADC_nConversionsMax; u32QueueElementIDX++) + { + /* NULL the mailbox pointer array */ + ADC_apstMBX[u32QueueIDX][u32QueueElementIDX] = NULL; + } + } + + for (u32QueueIDX = 0; u32QueueIDX < 0xff; u32QueueIDX++) + { + ;/* Waste some time *///matthew review + } + + ADCHA_vStart(pu32Stat); + + CQUEUE_xInit(ADC_astConversionQueue, ADC_nConversionsMax, ADC_astADCConversions); + CQUEUE_xInit(ADC_astConversionQueue + 1, ADC_nConversionsMax, (uint32)ADC_astADCConversions + sizeof(ADCHA_tstADCConversion) * ADC_nConversionsMax * 1); + CQUEUE_xInit(ADC_astConversionQueue + 2, ADC_nConversionsMax, (uint32)ADC_astADCConversions + sizeof(ADCHA_tstADCConversion) * ADC_nConversionsMax * 2); + CQUEUE_xInit(ADC_astConversionQueue + 3, ADC_nConversionsMax, (uint32)ADC_astADCConversions + sizeof(ADCHA_tstADCConversion) * ADC_nConversionsMax * 3); + CQUEUE_xInit(ADC_astConversionQueue + 4, ADC_nConversionsMax, (uint32)ADC_astADCConversions + sizeof(ADCHA_tstADCConversion) * ADC_nConversionsMax * 4); + + ADC_i32CyclicQueueIDX = -1; + ADC_boCyclicQueuePending = FALSE; + OS_xModuleStartOK(*pu32Stat); +} + +void ADC_vRun(uint32* const pu32Stat) +{ + uint32 u32CyclicQueueIDX; + static uint32 u32ADCQueueStuckCount; + ADCHA_tenQueue enQueue; + + if ((ADC_astConversionQueue[ADCHA_enQueueCyclic].u32Tail > ADC_astConversionQueue[ADCHA_enQueueCyclic].u32Head) && (-1 == ADC_i32CyclicQueueIDX)) + { + for (u32CyclicQueueIDX = ADC_astConversionQueue[ADCHA_enQueueCyclic].u32Head; + u32CyclicQueueIDX <= ADC_astConversionQueue[ADCHA_enQueueCyclic].u32Tail; + u32CyclicQueueIDX++) + { + if (0 < ADC_astADCConversions[ADCHA_enQueueCyclic][u32CyclicQueueIDX].u32ControlCount) + { + ADC_astADCConversions[ADCHA_enQueueCyclic][u32CyclicQueueIDX].u32ControlCount -= 1; + } + } + + /* EC - don't want AD conversion complete interrupting here */ + CPU_xEnterCritical(); + + for (u32CyclicQueueIDX = ADC_astConversionQueue[0].u32Head; + u32CyclicQueueIDX <= ADC_astConversionQueue[0].u32Tail; + u32CyclicQueueIDX++) + { + if (0 == ADC_astADCConversions[ADCHA_enQueueCyclic][u32CyclicQueueIDX].u32ControlCount) + { + ADC_i32CyclicQueueIDX = u32CyclicQueueIDX; + //ADC_boCyclicQueuePending = ADC_boInitiateConversion(&ADC_astADCConversions[ADCHA_enQueueCyclic][ADC_astConversionQueue[ADCHA_enQueueCyclic].u32Head], ADCHA_enQueueCyclic, ADC_astConversionQueue[0].u32Tail); + break; + } + } + + CPU_xExitCritical(); + } + + /* Check if the ADC queues are stuck */ + for (enQueue = ADCHA_enQueueCyclic; enQueue < ADCHA_enQueueCount; enQueue++) + { + if (ADC_astConversionQueue[enQueue].u32Head != ADC_astConversionQueue[enQueue].u32Tail) + { + u32ADCQueueStuckCount++; + } + } + + if (5 < u32ADCQueueStuckCount) + { + ADCHA_vReset(ADCHA_enADC0); + u32ADCQueueStuckCount = 0; + } +} + +bool ADC_boBackupCalibrations(void) +{ + return ADCHA_boBackupCalibrations(); +} + +SYSAPI_tenSVCResult ADC_vInitADCResource(IOAPI_tenEHIOResource enIOResource, IOAPI_tenEHIOType enEHIOType, ADCAPI_tstADCCB* pstADCCB) +{ + uint32 u32QueueIDX; + SYSAPI_tenSVCResult enResult = SYSAPI_enOK; + ADCHA_tstADCConversion* pstADCConversion; + + u32QueueIDX = (ADCAPI_enTrigger1 > pstADCCB->enTrigger) ? 0 : pstADCCB->enTrigger - ADCAPI_en1Hz; + + if (!CQUEUE_xIsFull(ADC_astConversionQueue + u32QueueIDX)) + { + CPU_xEnterCritical(); + + pstADCConversion = &ADC_astADCConversions[u32QueueIDX][0] + + ADC_astConversionQueue[u32QueueIDX].u32Tail; + ADCHA_vInitConversion(enIOResource, pstADCConversion, pstADCCB, u32QueueIDX); + + switch (pstADCCB->enTrigger) + { + case ADCAPI_en1000Hz: pstADCConversion->u32ResetCount = 1; break; + case ADCAPI_en500Hz: pstADCConversion->u32ResetCount = 2; break; + case ADCAPI_en250Hz: pstADCConversion->u32ResetCount = 4; break; + case ADCAPI_en125Hz: pstADCConversion->u32ResetCount = 8; break; + case ADCAPI_en64Hz: pstADCConversion->u32ResetCount = 31; break; + case ADCAPI_en32Hz: pstADCConversion->u32ResetCount = 32; break; + case ADCAPI_en16Hz: pstADCConversion->u32ResetCount = 63; break; + case ADCAPI_en8Hz: pstADCConversion->u32ResetCount = 125; break; + case ADCAPI_en4Hz: pstADCConversion->u32ResetCount = 250; break; + case ADCAPI_en2Hz: pstADCConversion->u32ResetCount = 500; break; + case ADCAPI_en1Hz: pstADCConversion->u32ResetCount = 1000; break; + default: pstADCConversion->u32ResetCount = 1000; break; + } + + CQUEUE_xAddItem(ADC_astConversionQueue + u32QueueIDX); + + /* Remove to leave it in the queue but exhaust the queue */ + CQUEUE_xRemoveItem(ADC_astConversionQueue + u32QueueIDX); + + if (IOAPI_enADD == enEHIOType) + { + ADCHA_vInitADCResourcePGA(pstADCConversion); + } + + ADCHA_vInitChannel(enIOResource); + CPU_xExitCritical(); + } + else + { + enResult = SYSAPI_enQueueFull; + } + + return enResult; +} + +void ADC_vTerminate(uint32* const u32Stat) +{ + +} + +void ADC_vInterruptHandler(IOAPI_tenEHIOResource enEHIOResource, void* pvData) +{ + uint32 enADCModule; + uint32 u32ADCChannel; + MSG_tstMBX* pstMBX; + uint32 u32QueueIDX; + ADCHA_tenQueue enQueue; + CLIENT_tenErr enErr; + tpfClientCB pfClientCB; + uint32 u32ADCResult; + tstADCModule* pstADC; + uint32 u32ADCResultAvailableCount; + uint32 u32DequeueIDX; + + enADCModule = enEHIOResource - EH_VIO_ADC0; + + /* Which queue initiated this conversion? */ + u32QueueIDX = (ADCHA_enQueueCyclic == ADC_astADCActiveQueue[enADCModule]) ? + (uint32)ADC_i32CyclicQueueIDX : + ADC_astConversionQueue[ADC_astADCActiveQueue[enADCModule]].u32Head; + + pstADC = ADCHA_pstGetADCModule(enADCModule); + u32ADCResultAvailableCount = ADCHA_u32GetAvailableResultCount(pstADC); + u32ADCResultAvailableCount = MIN(u32ADCResultAvailableCount, ADC_astConversionQueue[ADC_astADCActiveQueue[enADCModule]].u32Tail); + + for (u32DequeueIDX = u32QueueIDX; u32DequeueIDX < u32QueueIDX + u32ADCResultAvailableCount; u32DequeueIDX++) + { + enQueue = ADC_astADCActiveQueue[enADCModule]; + u32ADCChannel = ADC_astADCConversions[enQueue][u32DequeueIDX].stADCChannel.u32ADChannel; + enEHIOResource = ADCHA_enGetResourceAndResult(enADCModule, pstADC, u32ADCChannel, &u32ADCResult); + + /* Populate the result array - the reference of the element will + be posted to the client MBX* queue for callback to user */ + ADC_astResult[enQueue][u32DequeueIDX].u32Result = u32ADCResult; + ADC_astResult[enQueue][u32DequeueIDX].enEHIOResource = enEHIOResource; + + pstMBX = ADC_apstMBX[enQueue][u32DequeueIDX]; + MSG_vMBXPost(pstMBX, (void*)&ADC_astResult[enQueue][u32DequeueIDX]); + pfClientCB = (tpfClientCB)ADC_astADCConversions[enQueue][u32DequeueIDX].pfResultCB; + + if ((NULL != pfClientCB) && (MSG_boMBXValid(pstMBX))) + { + enErr = CLIENT_enEnqueueCB(pstMBX, pfClientCB); + } + + if (ADCHA_enQueueCyclic == enQueue) + { + while (-1 != ADC_i32CyclicQueueIDX) + { + ADC_i32CyclicQueueIDX = ((ADC_astConversionQueue[ADCHA_enQueueCyclic].u32Tail - 1) > ADC_i32CyclicQueueIDX) ? ADC_i32CyclicQueueIDX + 1 : -1; + if (-1 != ADC_i32CyclicQueueIDX) + { + if (0 == ADC_astADCConversions[ADCHA_enQueueCyclic][ADC_i32CyclicQueueIDX].u32ControlCount) + { + break; + } + } + } + } + else + { + CQUEUE_xRemoveItem(ADC_astConversionQueue + enQueue); + + if (ADC_astConversionQueue[enQueue].u32Head == ADC_astConversionQueue[enQueue].u32Tail) + { + /* Release the ADC module now the conversion queue has been processed */ + ADCHA_vClearModuleBusy(enADCModule); + } + } + } + + ADC_vRunConversionQueues(); + + /* TODO suppress warning */ + (void)enErr; +} + +bool ADC_vTriggerQueue(ADCAPI_tenTrigger enTrigger) +{ + ADCHA_tenQueue enQueue; + bool boResult = FALSE; + + if ((ADCAPI_enTrigger1 <= enTrigger) && (ADCAPI_enTriggerCount > enTrigger)) + { + enQueue = (ADCHA_tenQueue)(enTrigger - ADCAPI_enTrigger1 + 1); + + if (false == ADCHA_boGetModuleBusy(ADCHA_enADC0)) + { + ADC_astConversionQueue[enQueue].u32Head = 0; + ADC_vRunConversionQueues(); + boResult = TRUE; + } + } + + return boResult; +} + +static bool ADC_boInitiateConversion(ADCHA_tstADCConversion* pstADCConversion, ADCHA_tenQueue enQueue, uint32 u32QueueTail) +{ + bool boADCInitPending = TRUE; + uint32 u32QueueIDX; + MSG_tenMBXErr enMBXErr = MSG_enOK; + uint32 u32ConversionIDX; + + u32QueueIDX = (ADCHA_enQueueCyclic == enQueue) ? ADC_i32CyclicQueueIDX : + ADC_astConversionQueue[enQueue].u32Head; + + for (u32ConversionIDX = u32QueueIDX; u32ConversionIDX < u32QueueTail; u32ConversionIDX++) + { + /* Check if a mailbox is allocated for this conversion */ + if (NULL == ADC_apstMBX[enQueue][u32ConversionIDX]) + { + enMBXErr = MSG_enMBXNew((MSG_tstMBX**)&ADC_apstMBX[enQueue][u32ConversionIDX], + MSG_enADCResult); + } + } + + if (MSG_enOK == enMBXErr) + { + /* Remember which queue initiated this conversion */ + ADC_astADCActiveQueue[pstADCConversion->stADCChannel.enADCModule] = enQueue; + boADCInitPending = ADCHA_boInitiateConversion(pstADCConversion, enQueue, u32QueueTail, FALSE); + pstADCConversion->u32ControlCount = pstADCConversion->u32ResetCount; + } + + return boADCInitPending; +} + +#ifdef ADC_CALIBRATE +static void ADC_vCalibrate(tstADCModule* pstADC, uint32 u32ADCIDX, uint32 u32CalFlag) +{ + ADCHA_vCalibrate(pstADC, u32ADCIDX, u32CalFlag); +} +#endif //ADC_CALIBRATE + + +static void ADC_vRunConversionQueues(void) +{ + ADCHA_tenQueue enQueue; + bool boModuleBusy[ADCHA_enADCModuleCount]; + ADCHA_tenADCModule enADCModule; + bool boConversionPending; + ADCHA_tstADCConversion* pstConversion; + uint32 u32QueueIDX; + + for(enADCModule = ADCHA_enADC0; enADCModule < ADCHA_enADCModuleCount; enADCModule++) + { + boModuleBusy[enADCModule] = ADCHA_boGetModuleBusy(enADCModule); + } + + for (enQueue = ADCHA_enQueueCyclic; enQueue < ADCHA_enQueueCount; enQueue++) + { + switch (enQueue) + { + case ADCHA_enQueueCyclic: + { + if (-1 < ADC_i32CyclicQueueIDX) + { + pstConversion = &ADC_astADCConversions[enQueue][ADC_i32CyclicQueueIDX]; + enADCModule = pstConversion->stADCChannel.enADCModule; + + if (FALSE == boModuleBusy[enADCModule]) + { + boConversionPending = ADC_boInitiateConversion(pstConversion, enQueue, ADC_astConversionQueue[enQueue].u32Tail); + if (!boConversionPending) + { + boModuleBusy[enADCModule] = TRUE; + } + } + } + break; + } + case ADCHA_enQueueTriggered1: + case ADCHA_enQueueTriggered2: + case ADCHA_enQueueTriggered3: + case ADCHA_enQueueTriggered4: + { + if (false == CQUEUE_xIsEmpty((CQUEUE_tstQueue*)&ADC_astConversionQueue + enQueue)) + { + u32QueueIDX = ADC_astConversionQueue[enQueue].u32Head; + pstConversion = &ADC_astADCConversions[enQueue][u32QueueIDX]; + enADCModule = pstConversion->stADCChannel.enADCModule; + + if (FALSE == boModuleBusy[enADCModule]) + { + boConversionPending = ADC_boInitiateConversion(pstConversion, enQueue, ADC_astConversionQueue[enQueue].u32Tail); + + if (!boConversionPending) + { + boModuleBusy[enADCModule] = TRUE; + } + } + } + break; + } + default: + { + break; + } + } + } +} + + + + diff --git a/source/Peripherals/PERCAN.c b/source/Peripherals/PERCAN.c new file mode 100644 index 0000000..043f198 --- /dev/null +++ b/source/Peripherals/PERCAN.c @@ -0,0 +1,54 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: CAN */ +/* DESCRIPTION: This code provides functions for interacting with */ +/* the CAN hardware module/s */ +/* FILE NAME: CAN.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include "PERCAN.h" + +void CAN_vStart(uint32* const u32Stat) +{ + +} + +SYSAPI_tenSVCResult CAN_enInitBus(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tstPortConfigCB* pstPortConfigCB) +{ + return CANHA_u32InitBus(enEHIOResource, pstPortConfigCB); +} + +void CAN_vRun(uint32* const u32Stat) +{ + +} + +bool CAN_boReadMB(tstCANModule* pstCAN, CANHA_tstCANMB* pstCANMB) +{ + return CANHA_boReadMB(pstCAN, pstCANMB); +} + +void CAN_vInterrupt(IOAPI_tenEHIOResource enEHIOResource, void* pvData) +{ + CANHA_vInterrupt(enEHIOResource); +} + +void CAN_vInitTransfer(IOAPI_tstTransferCB* pstTransferCB) +{ + CANHA_vInitTransfer(pstTransferCB); +} + +void CAN_vTerminate(uint32* const u32Stat) +{ + +} + + + + + + diff --git a/source/Peripherals/PERCAN.h b/source/Peripherals/PERCAN.h new file mode 100644 index 0000000..ed50e58 --- /dev/null +++ b/source/Peripherals/PERCAN.h @@ -0,0 +1,41 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: CAN Header File */ +/* DESCRIPTION: This code provides functions for interacting with */ +/* the CAN hardware module/s */ +/* FILE NAME: CAN.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef CAN_H +#define CAN_H + +#include +#include "CANHA.h" +#include "CPUAbstract.h" +#include "declarations.h" +#include "DLL.h" +#include "IOAPI.h" +#include "IRQ.h" +#include "MATH.h" +#include "CPUAbstract.h" +#include "os.h" +#include "protapi.h" +#include "regset.h" +#include "SIM.h" +#include "types.h" + + +void CAN_vStart(uint32* const); +void CAN_vRun(uint32* const); +void CAN_vTerminate(uint32* const); +void CAN_vInitTransfer(IOAPI_tstTransferCB*); +bool CAN_boReadMB(tstCANModule*, CANHA_tstCANMB*); +SYSAPI_tenSVCResult CAN_enInitBus(IOAPI_tenEHIOResource, IOAPI_tstPortConfigCB*); +void CAN_vInterrupt(IOAPI_tenEHIOResource, void* pvData); + +#endif //CAN_H + diff --git a/source/Peripherals/PERSPI.c b/source/Peripherals/PERSPI.c new file mode 100644 index 0000000..7791186 --- /dev/null +++ b/source/Peripherals/PERSPI.c @@ -0,0 +1,54 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include "PERSPI.h" +#include "SPIHA.h" +#include "SYSAPI.h" + + +void SPI_vStart(puint32 const pu32Stat) +{ + SPIHA_vStart(pu32Stat); +} + +void SPI_vRun(puint32 const pu32Stat) +{ + +} + +void SPI_vTerminate(puint32 const pu32Stat) +{ + +} + +uint32 SPI_u32InitBus(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tstPortConfigCB* pstPortConfigCB) +{ + return SPIHA_u32InitBus(enEHIOResource, pstPortConfigCB); +} + +void SPI_vInitTransfer(IOAPI_tstTransferCB* pstTransferCB) +{ + SPIHA_vInitTransfer(pstTransferCB); +} + +void SPI_vInterrupt(IOAPI_tenEHIOResource enEHIOResource) +{ + SPIHA_vInterruptHandler(enEHIOResource); +} + + + + + + + + + diff --git a/source/Peripherals/PERSPI.h b/source/Peripherals/PERSPI.h new file mode 100644 index 0000000..f8bf7af --- /dev/null +++ b/source/Peripherals/PERSPI.h @@ -0,0 +1,27 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef SPI_H +#define SPI_H + +#include "IOAPI.h" +#include "SYSAPI.h" +#include "types.h" + +void SPI_vStart(puint32 const); +void SPI_vRun(puint32 const); +void SPI_vTerminate(puint32 const); +uint32 SPI_u32InitBus(IOAPI_tenEHIOResource, IOAPI_tstPortConfigCB*); +void SPI_vInitTransfer(IOAPI_tstTransferCB*); +void SPI_vInterrupt(IOAPI_tenEHIOResource); + +#endif //SPI_H + diff --git a/source/Peripherals/PERUART.c b/source/Peripherals/PERUART.c new file mode 100644 index 0000000..735f813 --- /dev/null +++ b/source/Peripherals/PERUART.c @@ -0,0 +1,141 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include +#include "CPUAbstract.h" +#include "CQUEUE.h" +#include "peruart.h" +#include "DLL.h" +#include "regset.h" +#include "sys.h" +#include "IRQ.h" +#include "declarations.h" +#include "os.h" +#include "DLL.h" +#include "types.h" +#include "SIM.h" + +CQUEUE_tstQueue UART_astCBQueue[EH_LAST_UART - EH_FIRST_UART + 1]; +uint8 UART_aau8ByteQueue[EH_LAST_UART - EH_FIRST_UART + 1][UART_nByteQueueSize]; + + +void UART_vStart(uint32* const u32Stat) +{ + OS_xModuleStartOK(*u32Stat); + + CQUEUE_xInit(&UART_astCBQueue[0], UART_nByteQueueSize, &UART_aau8ByteQueue[0][0]); + CQUEUE_xInit(&UART_astCBQueue[1], UART_nByteQueueSize, &UART_aau8ByteQueue[1][0]); +} + +void UART_vRun(uint32* const u32Stat) +{ + +} + +void UART_vTerminate(uint32* const u32Stat) +{ + +} + +SYSAPI_tenSVCResult UART_enInitBus(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tstPortConfigCB* pstPortConfigCB) +{ + SYSAPI_tenSVCResult enSVCResult; + + enSVCResult = UARTHA_enInitBus(enEHIOResource, pstPortConfigCB); + + return enSVCResult; +} + +void UART_vSendChar(IOAPI_tenEHIOResource enEHIOResource, uint8 ucData) +{ + UARTHA_vSendChar(enEHIOResource, ucData); +} + +uint8 UART_u8GetChar(IOAPI_tenEHIOResource enEHIOResource) +{ + return UARTHA_u8GetChar(enEHIOResource); +} + +void UART_vDisableTXInterrupt(IOAPI_tenEHIOResource enEHIOResource) +{ + UARTHA_vDisableTXInterrupt(enEHIOResource); +} + +void UART_vEnableTXInterrupt(IOAPI_tenEHIOResource enEHIOResource) +{ + UARTHA_vEnableTXInterrupt(enEHIOResource); +} + +void UART_vDisableRXInterrupt(IOAPI_tenEHIOResource enEHIOResource) +{ + UARTHA_vDisableRXInterrupt(enEHIOResource); +} + +void UART_vEnableRXInterrupt(IOAPI_tenEHIOResource enEHIOResource) +{ + UART_vEnableRXInterrupt(enEHIOResource); +} + +void UART_vInterrupt(IOAPI_tenEHIOResource enEHIOResource, void* pvData) +{ + uint32 u32UARTIDX = enEHIOResource - EH_VIO_UART1; + uint8 u8Data; + DLL_tstRXDLLData* pstRXDLLData = (DLL_tstRXDLLData*)pvData; + + while (!CQUEUE_xIsFull(&UART_astCBQueue[u32UARTIDX])) + { + if (0 < pstRXDLLData->u8DataCount) + { + u8Data = pstRXDLLData->u8Data[pstRXDLLData->u8RXByteIDX]; + UART_aau8ByteQueue[u32UARTIDX][UART_astCBQueue[u32UARTIDX].u32Tail] = u8Data; + CQUEUE_xAddItem(&UART_astCBQueue[u32UARTIDX]); + pstRXDLLData->u8DataCount--; + } + + if (0 == pstRXDLLData->u8DataCount) break; + } +} + +uint8 UART_u8GetQueuedChar(IOAPI_tenEHIOResource enEHIOResource) +{ + uint8 u8Data; + uint32 u32UARTIDX = enEHIOResource - EH_VIO_UART1; + + u8Data = UART_aau8ByteQueue[u32UARTIDX][UART_astCBQueue[u32UARTIDX].u32Head]; + CQUEUE_xRemoveItem(&UART_astCBQueue[u32UARTIDX]); + + return u8Data; +} + +uint8* UART_pu8GetQueueBuffer(IOAPI_tenEHIOResource enEHIOResource) +{ + uint8* pu8Data; + uint32 u32UARTIDX = enEHIOResource - EH_VIO_UART1; + + pu8Data = &UART_aau8ByteQueue[u32UARTIDX][0]; + + return pu8Data; +} + +CQUEUE_tstQueue* UART_pstGetQueue(IOAPI_tenEHIOResource enEHIOResource) +{ + CQUEUE_tstQueue* pstQueue; + uint32 u32UARTIDX = enEHIOResource - EH_VIO_UART1; + + pstQueue = &UART_astCBQueue[u32UARTIDX]; + + return pstQueue; +} + + + + diff --git a/source/Peripherals/PERUART.h b/source/Peripherals/PERUART.h new file mode 100644 index 0000000..cf9713b --- /dev/null +++ b/source/Peripherals/PERUART.h @@ -0,0 +1,53 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef UART_H +#define UART_H + +#include +#include "CQUEUE.h" +#include "CPUAbstract.h" +#include "DLL.h" +#include "IOAPI.h" +#include "SIMHA.h" +#include "sys.h" +#include "types.h" +#include "UARTHA.h" + +#define UART_nByteQueueSize 8 + +typedef struct +{ + uint32 u32SourceClockHz; + SIMHA_tenReg enSIMReg; + uint32 u32SIMRegMask; + tstUARTModule* pstUART; + IRQn_Type IRQn; +} UART_tstUARTCB; + +void UART_vStart(uint32* const); +void UART_vRun(uint32* const); +void UART_vTerminate(uint32* const); +SYSAPI_tenSVCResult UART_enInitBus(IOAPI_tenEHIOResource, IOAPI_tstPortConfigCB*); +void UART_vSendChar(IOAPI_tenEHIOResource, uint8); +uint8 UART_u8GetChar(IOAPI_tenEHIOResource); +void UART_vDisableTXInterrupt(IOAPI_tenEHIOResource); +void UART_vEnableTXInterrupt(IOAPI_tenEHIOResource); +void UART_vDisableRXInterrupt(IOAPI_tenEHIOResource); +void UART_vEnableRXInterrupt(IOAPI_tenEHIOResource); +void UART_vInterrupt(IOAPI_tenEHIOResource, void*); +uint8* UART_pu8GetQueueBuffer(IOAPI_tenEHIOResource); +CQUEUE_tstQueue* UART_pstGetQueue(IOAPI_tenEHIOResource); +uint8 UART_u8GetQueuedChar(IOAPI_tenEHIOResource); + + +#endif //UART_H + diff --git a/source/Peripherals/PERUSB.c b/source/Peripherals/PERUSB.c new file mode 100644 index 0000000..e56755f --- /dev/null +++ b/source/Peripherals/PERUSB.c @@ -0,0 +1,65 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include +#include "CPUAbstract.h" +#include "perusb.h" + +#include "regset.h" +#include "sys.h" +#include "IRQ.h" +#include "declarations.h" +#include "os.h" +#include "DLL.h" +#include "types.h" +#include "SIM.h" + + +void USB_vStart(uint32* const u32Stat) +{ + OS_xModuleStartOK(*u32Stat); +} + +void USB_vRun(uint32* const u32Stat) +{ + +} + +void USB_vTerminate(uint32* const u32Stat) +{ + +} + +SYSAPI_tenSVCResult USB_enInitBus(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tstPortConfigCB* pstPortConfigCB) +{ + SYSAPI_tenSVCResult enSVCResult; + + enSVCResult = USBHA_enInitBus(enEHIOResource, pstPortConfigCB); + + return enSVCResult; +} + +void USB_vSend(IOAPI_tenEHIOResource enEHIOResource, uint8* pu8Data, uint32 u32TXByteCount) +{ + USBHA_vSend(enEHIOResource, pu8Data, u32TXByteCount); +} + +uint8 USB_u8Receive(IOAPI_tenEHIOResource enEHIOResource) +{ + /* TODO */ + return NULL; +} + + + + + diff --git a/source/Peripherals/PERUSB.h b/source/Peripherals/PERUSB.h new file mode 100644 index 0000000..358f09b --- /dev/null +++ b/source/Peripherals/PERUSB.h @@ -0,0 +1,42 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef PERUSB_H +#define PERUSB_H + +#include +#include "CPUAbstract.h" +#include "DLL.h" +#include "IOAPI.h" +#include "SIMHA.h" +#include "sys.h" +#include "types.h" +#include "USBHA.h" + + +typedef struct +{ + uint32 u32SourceClockHz; + SIMHA_tenReg enSIMReg; + uint32 u32SIMRegMask; + IRQn_Type IRQn; +} USB_tstUSBCB; + +void USB_vStart(uint32* const); +void USB_vRun(uint32* const); +void USB_vTerminate(uint32* const); +SYSAPI_tenSVCResult USB_enInitBus(IOAPI_tenEHIOResource, IOAPI_tstPortConfigCB*); +void USB_vSend(IOAPI_tenEHIOResource, puint8, uint32); +puint8 USB_pu8Receive(IOAPI_tenEHIOResource); + + +#endif //PERUSB_H + diff --git a/source/Peripherals/PERWDT.c b/source/Peripherals/PERWDT.c new file mode 100644 index 0000000..12d4540 --- /dev/null +++ b/source/Peripherals/PERWDT.c @@ -0,0 +1,24 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: WDT */ +/* DESCRIPTION: This code provides watchdog functions */ +/* */ +/* FILE NAME: PERWDT.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include "PERWDT.h" + +void WDT_vStart(uint16 u16ResetVal, uint16 u16WindowVal) +{ + WDTHA_vStart(u16ResetVal, u16WindowVal); +} + +bool WDT_boReset(uint16 u16InputVal) +{ + return WDTHA_boReset(u16InputVal); +} + diff --git a/source/Peripherals/PERWDT.h b/source/Peripherals/PERWDT.h new file mode 100644 index 0000000..e1ace2c --- /dev/null +++ b/source/Peripherals/PERWDT.h @@ -0,0 +1,26 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: WDT header file */ +/* DESCRIPTION: This code provides wathdog functions */ +/* */ +/* FILE NAME: PERWDT.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef PERWDT_H +#define PERWDT_H + +#include "types.h" +#include "WDTHA.h" + +void WDT_vStart(uint16, uint16); +bool WDT_boReset(uint16); + +#endif //PERWDT_H + + + + diff --git a/source/Peripherals/SDHC.c b/source/Peripherals/SDHC.c new file mode 100644 index 0000000..ecfaab1 --- /dev/null +++ b/source/Peripherals/SDHC.c @@ -0,0 +1,62 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: SDHC */ +/* DESCRIPTION: This code provides setup and functions for the SDHC */ +/* hardware module */ +/* FILE NAME: SDHC.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include "types.h" +#include "CPUAbstract.h" +#include "regset.h" +#include "declarations.h" +#include "disk.h" +#include "sdhc.h" +#include "timer.h" +#include "sim.h" +#include "SDHCHA.h" + + +void SDHC_vStart(uint32* const pu32Stat) +{ + SDHCHA_vStart(pu32Stat) ; +} + +void SDHC_vRun(uint32* const pu32Stat) +{ + SDHCHA_vRun(pu32Stat); +} + +void SDHC_vTerminate(uint32* const pu32Stat) +{ + SDHC_vTerminate(pu32Stat); +} + +void SDHC_vHWInit(void) +{ + SDHCHA_vHWInit(); +} + +void SDHC_vHWDeInit(void) +{ + SDHC_vHWDeInit(); +} + +uint8 SDHC_u8DiskRead(uint8* const pu8Buf, const uint32 u32Sector, const uint16 u16SectorCount) +{ + SDHC_u8DiskRead(pu8Buf, u32Sector, u16SectorCount); + + return 0; +} + +uint8 SDHC_u8DiskWrite(uint8* const pu8Buf, const uint32 u32Sector, const uint16 u16SectorCount) +{ + return 0; +} + + + diff --git a/source/Peripherals/SDHC.h b/source/Peripherals/SDHC.h new file mode 100644 index 0000000..8c04d2f --- /dev/null +++ b/source/Peripherals/SDHC.h @@ -0,0 +1,29 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: SDHC Header File */ +/* DESCRIPTION: This code provides macros for setup and control of the */ +/* SDHC hardware module */ +/* FILE NAME: SDHC.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef SDHC_H +#define SDHC_H + +#include "types.h" + + +void SDHC_vStart(uint32* const); +void SDHC_vRun(uint32* const); +void SDHC_vTerminate(uint32* const); +void SDHC_vHWInit(void); +void SDHC_vHWDeInit(void); +uint8 SDHC_u8DiskRead(uint8* const, const uint32, const uint16); +uint8 SDHC_u8DiskWrite(uint8* const, const uint32, const uint16); + + +#endif //SDHC_H + diff --git a/source/Peripherals/SDHC1HA.c b/source/Peripherals/SDHC1HA.c new file mode 100644 index 0000000..ca32107 --- /dev/null +++ b/source/Peripherals/SDHC1HA.c @@ -0,0 +1,2879 @@ +/** ################################################################### +** THIS COMPONENT MODULE IS GENERATED BY THE TOOL. DO NOT MODIFY IT. +** Filename : SDHC1.c +** Project : ProcessorExpert +** Processor : MK60DN512ZVMD10 +** Component : SDHC_LDD +** Version : Component 00.001, Driver 01.03, CPU db: 3.00.003 +** Compiler : CodeWarrior ARM C Compiler +** Date/Time : 2012-07-29, 21:43, # CodeGen: 371 +** Abstract : +** This component implements a SD host controller driver +** interface. Handles control and data transfers to/from +** SD and MMC cards. +** Settings : +** Component name : SDHC1 +** Device : SDHC +** Settings : +** Interface : 4-bit data mode +** Bus clock : 390.625 kHz +** Data timeout exponent : 20 +** DMA : +** Read watermark : 16 +** Write watermark : 16 +** Buffers : +** Transfer buffer table size : 8 +** Interrupt service/event : Enabled +** SDHC : INT_SDHC +** SDHC priority : medium priority +** Pins : 4-bit data mode +** CLK pin : PTE2/SPI1_SCK/UART1_CTS_b/SDHC0_DCLK/ADC1_SE6a +** CLK pin signal : SD_CLK +** CMD pin : PTE3/SPI1_SIN/UART1_RTS_b/SDHC0_CMD/ADC1_SE7a +** CMD pin signal : SD_CMD +** Data : +** DAT0 pin : PTE1/SPI1_SOUT/UART1_RX/SDHC0_D0/I2C1_SCL/ADC1_SE5a +** DAT0 pin signal : SD_DATA0 +** DAT1 : Enabled +** DAT1 pin : PTE0/SPI1_PCS1/UART1_TX/SDHC0_D1/I2C1_SDA/ADC1_SE4a +** DAT1 pin signal : SD_DATA1 +** DAT2 : Enabled +** DAT2 pin : PTE5/SPI1_PCS2/UART3_RX/SDHC0_D2 +** DAT2 pin signal : SD_DATA2 +** DAT3 : Enabled +** DAT3 pin : PTE4/SPI1_PCS0/UART3_TX/SDHC0_D3 +** DAT3 pin signal : SD_DATA3 +** Initialization : +** Enable device : yes +** Auto initialization : no +** Event mask : +** OnCardInserted : Enabled +** OnCardRemoved : Enabled +** OnFinished : Enabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Contents : +** Init - LDD_TDeviceData* SDHC1_Init(LDD_TUserData *UserDataPtr); +** Deinit - void SDHC1_Deinit(LDD_TDeviceData *DeviceDataPtr); +** Enable - LDD_TError SDHC1_Enable(LDD_TDeviceData *DeviceDataPtr); +** Disable - LDD_TError SDHC1_Disable(LDD_TDeviceData *DeviceDataPtr); +** SetEventMask - LDD_TError SDHC1_SetEventMask(LDD_TDeviceData *DeviceDataPtr, LDD_TEventMask... +** GetEventMask - LDD_TEventMask SDHC1_GetEventMask(LDD_TDeviceData *DeviceDataPtr); +** DetectCards - LDD_TError SDHC1_DetectCards(LDD_TDeviceData *DeviceDataPtr); +** SelectCard - LDD_TError SDHC1_SelectCard(LDD_TDeviceData *DeviceDataPtr, uint8_t Id); +** GetCardInfo - LDD_TError SDHC1_GetCardInfo(LDD_TDeviceData *DeviceDataPtr,... +** TransferBlocks - LDD_TError SDHC1_TransferBlocks(LDD_TDeviceData *DeviceDataPtr,... +** EraseBlocks - LDD_TError SDHC1_EraseBlocks(LDD_TDeviceData *DeviceDataPtr, uint32_t... +** SetDataWidth - LDD_TError SDHC1_SetDataWidth(LDD_TDeviceData *DeviceDataPtr, uint8_t Width); +** SelectBusClock - LDD_TError SDHC1_SelectBusClock(LDD_TDeviceData *DeviceDataPtr,... +** SetVoltage - LDD_TError SDHC1_SetVoltage(LDD_TDeviceData *DeviceDataPtr, LDD_SDHC_TVoltage... +** SetWriteProtection - LDD_TError SDHC1_SetWriteProtection(LDD_TDeviceData *DeviceDataPtr,... +** GetWriteProtection - LDD_TError SDHC1_GetWriteProtection(LDD_TDeviceData *DeviceDataPtr, uint32_t... +** CancelOperation - LDD_TError SDHC1_CancelOperation(LDD_TDeviceData *DeviceDataPtr); +** GetStatus - LDD_SDHC_TStatus SDHC1_GetStatus(LDD_TDeviceData *DeviceDataPtr); +** GetError - LDD_SDHC_TError SDHC1_GetError(LDD_TDeviceData *DeviceDataPtr, uint32_t... +** ConnectPin - LDD_TError SDHC1_ConnectPin(LDD_TDeviceData *DeviceDataPtr, LDD_TPinMask... +** SetOperationMode - LDD_TError SDHC1_SetOperationMode(LDD_TDeviceData *DeviceDataPtr,... +** GetDriverState - LDD_TDriverState SDHC1_GetDriverState(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2011 Freescale Semiconductor, Inc. All Rights Reserved. +** +** http : www.freescale.com +** mail : support@freescale.com +** ###################################################################*/ + +/* MODULE SDHC1 */ + +/*lint -save -esym(960,10.1) -e961 Disable MISRA rule (10.1,12.1) checking. */ + +#include +#include +#include +#include +#include "mk64f12.h" +#include "sim.h" +#include "irq.h" + + +LDD_SDHC1_TDeviceData SDHC1_stDeviceData; + +/* {FreeRTOS RTOS Adapter} Global variable used for passing a parameter into ISR */ +static LDD_SDHC1_TDeviceData* INT_SDHC__BAREBOARD_RTOS_ISRPARAM; + +/* Internal method prototypes */ +static void VoltageValidation(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response); +static void CardRegistration(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response); +static void CardInfoRetrieval(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response); +static bool CardSelection(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response); +static bool Transfer(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response); +static bool Erasion(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response); +static bool DataWidthSelection(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response); +static bool BusClockSelection(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response); +static bool WriteProtectionSetup(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response); +static bool WriteProtectionRetrieval(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response); +static void SetBusClockPrescalers(LDD_SDHC1_TDeviceData *DeviceDataPtr, SDHC1_TBusClock Frequency); +static LDD_SDHC_TError GetCommandError(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response); +static void SendCardStatusRequest(LDD_SDHC1_TDeviceData *DeviceDataPtr); +static void EventHandler(LDD_SDHC1_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : SDHC1_Init (component SDHC_LDD) +** +** Description : +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property <"Enable device"> is set to "yes" then the device +** is also enabled (see the description of the method). +** In this case the method is not necessary and need +** not to be generated. This method can be called only once. +** Before the second call of Init the method must be +** called first. +** Parameters : +** NAME - DESCRIPTION +** * UserDataPtr - Pointer to user data +** structure pointer. +** Returns : +** --- - Pointer to the device data structure. +** =================================================================== +*/ +LDD_SDHC1_TDeviceData* SDHC1_Init(LDD_TUserData *UserDataPtr) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv; + uint8_t Id; + /* {FreeRTOS RTOS Adapter} Driver memory allocation: RTOS function call is defined by FreeRTOS RTOS Adapter property */ + //DeviceDataPrv = (LDD_SDHC1_TDeviceData *)pvPortMalloc(sizeof(LDD_SDHC1_TDeviceData)); + DeviceDataPrv = &SDHC1_stDeviceData; + #if FreeRTOS_CHECK_MEMORY_ALLOCATION_ERRORS + if (DeviceDataPrv == NULL) { + return (NULL); + } + #endif + + /* Initialize the device data */ + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the user data pointer */ + DeviceDataPrv->CardId = SDHC1_NO_CARD; /* No card will be selected */ + DeviceDataPrv->State = LDD_SDHC_RESET; /* Cards will be reseted after host initialization */ + DeviceDataPrv->HighVoltage = TRUE; /* Initially set bus voltage to high */ + DeviceDataPrv->LastError = LDD_SDHC_ERR_OK; /* Clear the error code */ + for (Id = 0; Id < SDHC1_MAX_CARD_NUMBER; Id++) { + DeviceDataPrv->Cards[Id].Initialized = FALSE; + } + DeviceDataPrv->TransferTable = (SDHC1_TTransferBufferDesc*) /* Align transfer buffer table memory according to hardware requirements */ + (((uint32_t)DeviceDataPrv->TransferTableMem + SDHC1_TRANSFER_TABLE_ALIGN) & (uint32_t)(~(uint32_t)(SDHC1_TRANSFER_TABLE_ALIGN - 1U))); + DeviceDataPrv->CSDPtr = (uint8_t*) /* Align CSD (card specific data) card register buffer according to hardware requirements */ + (((uint32_t)DeviceDataPrv->CSDMem + SDHC1_TRANSFER_BUFFER_ALIGN) & (uint32_t)(~(uint32_t)(SDHC1_TRANSFER_BUFFER_ALIGN - 1U))); + DeviceDataPrv->BusTestPtr = (uint8_t*) /* Align bus test buffer according to hardware requirements */ + (((uint32_t)DeviceDataPrv->BusTestMem + SDHC1_TRANSFER_BUFFER_ALIGN) & (uint32_t)(~(uint32_t)(SDHC1_TRANSFER_BUFFER_ALIGN - 1U))); + DeviceDataPrv->DataWidth = LDD_SDHC_CARD_DATA_WIDTH_4_BIT; /* Set default data width */ + DeviceDataPrv->Cancel = FALSE; /* Clear the cancel flag */ + DeviceDataPrv->SpeedMode = CPU_CLOCK_CONFIG_0; /* Set initial clock configuration */ + DeviceDataPrv->EventMask = /* Initialize the event mask */ + LDD_SDHC_ON_CARD_INSERTED | + LDD_SDHC_ON_CARD_REMOVED | + LDD_SDHC_ON_FINISHED |0U; + DeviceDataPrv->EnabledMode = TRUE; /* Enable the device clock configuration */ + /* SIM_SCGC3: SDHC=1 */ + SIM_vSetReg32( SIM_SCGC3, SIM_SCGC3_SDHC_MASK ); //SIM_SCGC3 |= (uint32_t)0x00020000UL; + + /* initialise hardware ports */ + SDHC_vHWInit(); + + /* Configure card detection and DMA mode */ + /* SDHC_PROCTL: ??=0,??=0,??=0,??=0,??=0,WECRM=0,WECINS=0,WECINT=0,??=0,??=0,??=0,??=0,IABG=0,RWCTL=0,CREQ=0,SABGREQ=0,??=0,??=0,??=0,??=0,??=0,??=0,DMAS=2,CDSS=0,CDTL=0,EMODE=2,D3CD=0,DTW=0,LCTL=0 */ + SDHC_PROCTL = (uint32_t)0x0220UL; + /* Set DMA watermark levels */ + /* SDHC_WML: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,WRWML=0x10,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,RDWML=0x10 */ + SDHC_WML = (uint32_t)0x00100010UL; + /* SDHC_VENDOR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,INTSTVAL=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,EXBLKNU=0,EXTDMAEN=0 */ + SDHC_VENDOR = (uint32_t)0x00UL; + /* SIM_SOPT2: SDHCSRC=0 */ + SIM_vClrReg32( SIM_SOPT2, SIM_SOPT2_SDHCSRC_MASK ); //SIM_SOPT2 &= (uint32_t)~0x30000000UL; + /* Set bus clock frequency and data timeout */ + /* SDHC_SYSCTL: ??=0,??=0,??=0,??=0,INITA=0,RSTD=0,RSTC=0,RSTA=0,??=0,??=0,??=0,??=0,DTOCV=7,SDCLKFS=0x40,DVS=0,SDCLKEN=0,PEREN=0,HCKEN=0,IPGEN=0 */ + SDHC_SYSCTL = (uint32_t)0x00074000UL; + while (!SDHC_PDD_IsSDClockStable(SDHC_BASE_PTR)) {} /* Wait for clock to stabilize */ + /* Set interrupt priorities */ + /* NVICIP80: PRI80=0x80 */ + IRQ_vEnableIRQ(SDHC_IRQn, IRQ_enPRIO_15, NULL, NULL); //NVICIP80 = (uint8_t)0x80U; + /* NVICISER2: SETENA|=0x00010000 */ + //NVICISER2 |= (uint32_t)0x00010000UL; + + /* Allocate the interrupt vector */ + /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ + INT_SDHC__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; + + /* Enable and clear status flags */ + /* SDHC_IRQSTAT: ??=1,??=1,??=1,DMAE=1,??=1,??=1,??=1,AC12E=1,??=1,DEBE=1,DCE=1,DTOE=1,CIE=1,CEBE=1,CCE=1,CTOE=1,??=1,??=1,??=1,??=1,??=1,??=1,??=1,CINT=1,CRM=1,CINS=1,BRR=1,BWR=1,DINT=1,BGE=1,TC=1,CC=1 */ + SDHC_IRQSTAT = (uint32_t)0xFFFFFFFFUL; + /* SDHC_IRQSIGEN: ??=0,??=0,??=0,DMAEIEN=0,??=0,??=0,??=0,AC12EIEN=0,??=0,DEBEIEN=0,DCEIEN=0,DTOEIEN=0,CIEIEN=0,CEBEIEN=0,CCEIEN=0,CTOEIEN=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CINTIEN=0,CRMIEN=0,CINSIEN=0,BRRIEN=0,BWRIEN=0,DINTIEN=0,BGEIEN=0,TCIEN=1,CCIEN=1 */ + //SDHC_IRQSIGEN = (uint32_t)0x03UL; + /* SDHC_IRQSTATEN: ??=1,??=1,??=1,DMAESEN=1,??=1,??=1,??=1,AC12ESEN=1,??=1,DEBESEN=1,DCESEN=1,DTOESEN=1,CIESEN=1,CEBESEN=1,CCESEN=1,CTOESEN=1,??=1,??=1,??=1,??=1,??=1,??=1,??=1,CINTSEN=1,CRMSEN=0,CINSEN=0,BRRSEN=0,BWRSEN=0,DINTSEN=1,BGESEN=1,TCSEN=1,CCSEN=1 */ + SDHC_IRQSTATEN = (uint32_t)0xFFFFFF0FUL; + /* Power up cards */ + SDHC_PDD_InitCard(SDHC_BASE_PTR); + + /* SDHC_IRQSIGEN: ??=0,??=0,??=0,DMAEIEN=0,??=0,??=0,??=0,AC12EIEN=0,??=0,DEBEIEN=0,DCEIEN=0,DTOEIEN=0,CIEIEN=0,CEBEIEN=0,CCEIEN=0,CTOEIEN=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CINTIEN=0,CRMIEN=0,CINSIEN=0,BRRIEN=0,BWRIEN=0,DINTIEN=0,BGEIEN=0,TCIEN=1,CCIEN=1 */ + SDHC_IRQSIGEN = (uint32_t)0x03UL; + while (!SDHC_PDD_IsCardInitComplete(SDHC_BASE_PTR)) {} + + /* Set transfer timeout to 7 */ + SDHC_SYSCTL |= SDHC_SYSCTL_DTOCV(SDHCHA_nTransferTimeoutExponent); + + /* Reset cards */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, 0U); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD0_GO_IDLE_STATE, SDHC_PDD_NO_RESPONSE); + DeviceDataPrv->Enabled = TRUE; /* Enable the component */ + + //MATTHEW + //DeviceDataPrv->State = LDD_SDHC_IDLE; + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_SDHC1_ID,DeviceDataPrv); + return DeviceDataPrv; +} + +/* +** =================================================================== +** Method : SDHC1_Deinit (component SDHC_LDD) +** +** Description : +** Deinitializes the device. Switches off the device, frees the +** device data structure memory, interrupt vectors, etc. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Returns : Nothing +** =================================================================== +*/ +void SDHC1_Deinit(LDD_SDHC1_TDeviceData *DeviceDataPtr) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + + (void)DeviceDataPrv; /* Suppress unused variable warning if needed */ + /* Disable interrupts */ + SDHC_IRQSIGEN = 0x00; + SDHC_IRQSTATEN = 0x00; + /* {FreeRTOS RTOS Adapter} Restore interrupt vector: IVT is static, no code is generated */ + /* Disable the device clock */ + SDHC_PDD_EnableSDHCClock(SDHC_BASE_PTR, PDD_DISABLE); + /* Reset the device */ + SDHC_PDD_ResetDevice(SDHC_BASE_PTR); + /* Unregistration of the device structure */ + //PE_LDD_UnregisterDeviceStructure(PE_LDD_COMPONENT_SDHC1_ID); + /* Deallocation of the internal device data structure */ + /* {FreeRTOS RTOS Adapter} Driver memory deallocation: RTOS function call is defined by FreeRTOS RTOS Adapter property */ + //vPortFree(DeviceDataPrv); + /* SIM_SCGC3: SDHC=0 */ + SIM_vClrReg32( SIM_SCGC3, SIM_SCGC3_SDHC_MASK ); //SIM_SCGC3 &= (uint32_t)~0x00020000UL; +} + +/* +** =================================================================== +** Method : SDHC1_Enable (component SDHC_LDD) +** +** Description : +** Enables the component. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - OK +** =================================================================== +*/ +LDD_TError SDHC1_Enable(LDD_SDHC1_TDeviceData *DeviceDataPtr) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + + DeviceDataPrv->Enabled = TRUE; /* Enable the component */ + return ERR_OK; +} + +/* +** =================================================================== +** Method : SDHC1_Disable (component SDHC_LDD) +** +** Description : +** Disables the component. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - OK +** =================================================================== +*/ +LDD_TError SDHC1_Disable(LDD_SDHC1_TDeviceData *DeviceDataPtr) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + + DeviceDataPrv->Enabled = FALSE; /* Disable the component */ + return ERR_OK; +} + +/* +** =================================================================== +** Method : SDHC1_SetEventMask (component SDHC_LDD) +** +** Description : +** Sets event mask. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** EventMask - Event mask +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - OK +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_PARAM_MASK - Invalid mask (one or more +** event is unmaskable) +** =================================================================== +*/ +LDD_TError SDHC1_SetEventMask(LDD_SDHC1_TDeviceData *DeviceDataPtr, LDD_TEventMask EventMask) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + + /* Device state test - this test can be disabled by setting the "Ignore enable test" + property to the "yes" value in the "Configuration inspector" */ + if (!DeviceDataPrv->Enabled) { + return ERR_DISABLED; + } + if ((EventMask & (LDD_TEventMask)(~(LDD_TEventMask)( + LDD_SDHC_ON_CARD_INSERTED | LDD_SDHC_ON_CARD_REMOVED | LDD_SDHC_ON_FINISHED))) != 0U) { + return ERR_PARAM_MASK; + } + DeviceDataPrv->EventMask = EventMask; + return ERR_OK; +} + +/* +** =================================================================== +** Method : SDHC1_GetEventMask (component SDHC_LDD) +** +** Description : +** Returns event mask. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Returns : +** --- - Current event mask. +** =================================================================== +*/ +LDD_TEventMask SDHC1_GetEventMask(LDD_SDHC1_TDeviceData *DeviceDataPtr) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + + return DeviceDataPrv->EventMask; +} + +/* +** =================================================================== +** Method : SDHC1_DetectCards (component SDHC_LDD) +** +** Description : +** Detects newly inserted and removed cards. The OnCardInserted +** event will be called for every new card and the +** OnCardRemoved event will be called for every removed card. +** This method should be used when card detection pin is not +** available. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Card detection started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** =================================================================== +*/ +LDD_TError SDHC1_DetectCards(LDD_SDHC1_TDeviceData *DeviceDataPtr) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + LDD_TError Result = ERR_OK; /* Error code storage */ + + /* Device state test - this test can be disabled by setting the "Ignore enable test" + property to the "yes" value in the "Configuration inspector" */ + if (!DeviceDataPrv->Enabled) { + return ERR_DISABLED; + } + if (DeviceDataPrv->State == LDD_SDHC_IDLE) { + DeviceDataPrv->Cancel = FALSE; /* Clear the cancel flag */ + DeviceDataPrv->LastError = LDD_SDHC_ERR_OK; /* Clear the error code */ + DeviceDataPrv->LastErrorAddress = 0U; /* Clear the error address */ + DeviceDataPrv->State = LDD_SDHC_VOLTAGE_VALIDATION; + DeviceDataPrv->Substate = SDHC1_VV_START; + VoltageValidation(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the voltage validation state */ + } else { + Result = ERR_BUSY; /* Another operation is in progress */ + } + return Result; +} + +/* +** =================================================================== +** Method : SDHC1_SelectCard (component SDHC_LDD) +** +** Description : +** Selects a card by its identification number. All further +** operations will apply to this card. Special card +** identification number _NO_CARD will deselect the +** active card. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Id - Card identification number passed by the +** OnCardInserted event parameter. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Card selection started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** ERR_PARAM_ID - Invalid card ID +** =================================================================== +*/ +LDD_TError SDHC1_SelectCard(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint8_t Id) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + LDD_TError Result = ERR_OK; /* Error code storage */ + uint32_t Argument; /* Card command argument */ + + /* Device state test - this test can be disabled by setting the "Ignore enable test" + property to the "yes" value in the "Configuration inspector" */ + if (!DeviceDataPrv->Enabled) { + return ERR_DISABLED; + } + if (Id != SDHC1_NO_CARD) { + if (!DeviceDataPrv->Cards[Id].Initialized) { + return ERR_PARAM_ID; + } + } + if (DeviceDataPrv->State == LDD_SDHC_IDLE) { + DeviceDataPrv->Cancel = FALSE; /* Clear the cancel flag */ + DeviceDataPrv->LastError = LDD_SDHC_ERR_OK; /* Clear the error code */ + DeviceDataPrv->LastErrorAddress = 0U; /* Clear the error address */ + if (Id != DeviceDataPrv->CardId) { /* Reselecting already selected card is an illegal card operation */ + /* Change card selection */ + DeviceDataPrv->CardId = Id; + if (Id != SDHC1_NO_CARD) { /* Select card */ + DeviceDataPrv->CardType = DeviceDataPrv->Cards[Id].Type; /* Store currently selected card's type */ + Argument = SDHC1_CMD_ARG_RCA((uint32_t)DeviceDataPrv->Cards[Id].RCA); /* Select card by its RCA */ + } else { /* Unselect card */ + Argument = 0U; /* Zero is a special RCA (relative card address) for deselecting all cards */ + } + DeviceDataPrv->State = LDD_SDHC_CARD_SELECTION; + /* Send card selection command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, Argument); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD7_SELECT_CARD, SDHC_PDD_RESPONSE_LENGTH_48_BUSY_CHECK); + } + } else { + Result = ERR_BUSY; /* Another operation is in progress */ + } + return Result; +} + +/* +** =================================================================== +** Method : SDHC1_GetCardInfo (component SDHC_LDD) +** +** Description : +** Returns card information about the selected card. Method +** call starts the card information retrieval process. After +** the card information has been received, the OnFinished event +** is called (the component state changes to idle) and the +** information is stored in the specified variable. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** * InfoPtr - Pointer to a variable, where card +** information will be stored. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Card information retrieval started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** =================================================================== +*/ +LDD_TError SDHC1_GetCardInfo(LDD_SDHC1_TDeviceData *DeviceDataPtr, LDD_SDHC_TCardInfo *InfoPtr) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + LDD_TError Result = ERR_OK; /* Error code storage */ + + /* Device state test - this test can be disabled by setting the "Ignore enable test" + property to the "yes" value in the "Configuration inspector" */ + if (!DeviceDataPrv->Enabled) { + return ERR_DISABLED; + } + if (DeviceDataPrv->State == LDD_SDHC_IDLE) { + DeviceDataPrv->Cancel = FALSE; /* Clear the cancel flag */ + DeviceDataPrv->LastError = LDD_SDHC_ERR_OK; /* Clear the error code */ + DeviceDataPrv->LastErrorAddress = 0U; /* Clear the error address */ + DeviceDataPrv->CardInfoPtr = InfoPtr; /* Store a pointer to the card info variable for later card info update */ + /* Start card information retrieval */ + DeviceDataPrv->State = LDD_SDHC_CARD_INFO_RETRIEVAL; + DeviceDataPrv->Substate = SDHC1_CIR_START; + CardInfoRetrieval(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the card info retrieval state */ + } else { + Result = ERR_BUSY; /* Another operation is in progress */ + } + return Result; +} + +/* +** =================================================================== +** Method : SDHC1_TransferBlocks (component SDHC_LDD) +** +** Description : +** Initiates a data block transfer on the selected card. +** Transfer can be a read or write operation depending on the +** transfer operation parameter. Read operation reads data +** blocks from the specified address on a memory card and +** stores their content into buffers specified by the buffer +** descriptor list. Write operation writes data blocks +** specified by the buffer descriptor list to a card memory on +** the specified address. Data blocks should be the same size +** and the block size should be supported by the memory card. +** Buffer addresses should be aligned to a hardware specific +** address boundary. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Operation - Transfer operation +** Address - Card memory address. Byte address +** in case of standard capacity memory cards, +** 512 byte block number in case of high +** capacity memory cards. +** * BufferDescListPtr - Pointer to +** data block buffer descriptor list. +** BufferDescCount - Data block buffer +** descriptor list item count +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Transfer started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** ERR_PARAM_ADDRESS - Invalid buffer address +** (one or more buffer address from the list +** of buffer descriptors is misaligned) +** ERR_PARAM_BUFFER_COUNT - Buffer count +** exceeds the internal buffer table size +** =================================================================== +*/ +LDD_TError SDHC1_TransferBlocks(LDD_SDHC1_TDeviceData *DeviceDataPtr, LDD_SDHC_TTransferOperation Operation, uint32_t Address, LDD_SDHC_TBufferDesc *BufferDescListPtr, uint16_t BufferDescCount) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + LDD_TError Result = ERR_OK; /* Error code storage */ + uint32_t Index; /* Transfer table index */ + bool Finished; /* Indicates whether transfer has finished */ + + /* Device state test - this test can be disabled by setting the "Ignore enable test" + property to the "yes" value in the "Configuration inspector" */ + if (!DeviceDataPrv->Enabled) { + return ERR_DISABLED; + } + if ((BufferDescCount == 0U) || (BufferDescCount > SDHC1_BUFFER_TABLE_SIZE)) { + return ERR_PARAM_BUFFER_COUNT; + } + if (DeviceDataPrv->State == LDD_SDHC_IDLE) { + DeviceDataPrv->Cancel = FALSE; /* Clear the cancel flag */ + DeviceDataPrv->LastError = LDD_SDHC_ERR_OK; /* Clear the error code */ + DeviceDataPrv->LastErrorAddress = 0U; /* Clear the error address */ + DeviceDataPrv->TransferBlockSize = BufferDescListPtr[0].Size; /* Determine block size from first buffer size */ + DeviceDataPrv->TransferBlockCount = BufferDescCount; /* Determine block count from buffer count */ + /* Fill in the transfer descriptors table */ + for (Index = 0U; Index < BufferDescCount; Index++) { + DeviceDataPrv->TransferTable[Index].Attributes = /* Mark each transfer buffer descriptor as ready for transfer */ + SDHC1_ADMA2_VALID | SDHC1_ADMA2_ATTR_ACT_TRAN; + DeviceDataPrv->TransferTable[Index].Length = BufferDescListPtr[Index].Size; /* Copy transfer buffer size */ + DeviceDataPrv->TransferTable[Index].Address = (uint32_t)BufferDescListPtr[Index].DataPtr; /* Copy transfer buffer address */ + } + DeviceDataPrv->TransferTable[BufferDescCount - 1U].Attributes |= SDHC1_ADMA2_END; /* Mark the last descriptor as last */ + DeviceDataPrv->TransferOperation = Operation; /* Store the transfer operation type */ + DeviceDataPrv->Address = Address; /* Store the source/destination address for the read/write operation */ + /* Start data transfer */ + DeviceDataPrv->State = LDD_SDHC_TRANSFER; + DeviceDataPrv->CmdState = SDHC1_CMD_DATA_LEN; + Finished = Transfer(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the transfer state */ + (void)Finished; /* The return value is not used */ + } else { + Result = ERR_BUSY; /* Another operation is in progress */ + } + return Result; +} + +/* +** =================================================================== +** Method : SDHC1_EraseBlocks (component SDHC_LDD) +** +** Description : +** Initiates a memory area erasion on the selected card. Erase +** operation erases a memory area of the specified size from +** the specified address on a memory card. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Address - Address of the beginning of the +** erased area. Byte address in case of +** standard capacity memory card and 512 byte +** block number in case of high capacity +** memory card. +** Size - Size of the erased area. Byte size in +** case of standard capacity memory card and +** 512 byte blocks count in case of high +** capacity memory card. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Erasing started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** =================================================================== +*/ +LDD_TError SDHC1_EraseBlocks(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Address, uint32_t Size) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + LDD_TError Result = ERR_OK; /* Error code storage */ + bool Finished; /* Indicates whether erasion has finished */ + + /* Device state test - this test can be disabled by setting the "Ignore enable test" + property to the "yes" value in the "Configuration inspector" */ + if (!DeviceDataPrv->Enabled) { + return ERR_DISABLED; + } + if (DeviceDataPrv->State == LDD_SDHC_IDLE) { + DeviceDataPrv->Cancel = FALSE; /* Clear the cancel flag */ + DeviceDataPrv->LastError = LDD_SDHC_ERR_OK; /* Clear the error code */ + DeviceDataPrv->LastErrorAddress = 0U; /* Clear the error address */ + DeviceDataPrv->ErasionStart = Address; /* Store the erasion start address */ + DeviceDataPrv->ErasionEnd = (Address + Size) - 1U; /* Count the erasion end address */ + /* Start data erasion */ + DeviceDataPrv->State = LDD_SDHC_ERASION; + DeviceDataPrv->Substate = SDHC1_E_SET_START; + Finished = Erasion(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the erasion state */ + (void)Finished; /* The return value is not used */ + } else { + Result = ERR_BUSY; /* Another operation is in progress */ + } + return Result; +} + +/* +** =================================================================== +** Method : SDHC1_SetDataWidth (component SDHC_LDD) +** +** Description : +** Initiates a data width setup. The card has to support the +** specified data width. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Width - Data bus bit count. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Setup started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** ERR_PARAM_WIDTH - Invalid data width +** =================================================================== +*/ +LDD_TError SDHC1_SetDataWidth(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint8_t Width) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + LDD_TError Result = ERR_OK; /* Error code storage */ + bool Finished; /* Indicates whether bus width selection has finished */ + + /* Device state test - this test can be disabled by setting the "Ignore enable test" + property to the "yes" value in the "Configuration inspector" */ + if (!DeviceDataPrv->Enabled) { + return ERR_DISABLED; + } + /* Check allowed data width values */ + if (DeviceDataPrv->CardType == LDD_SDHC_MMC) { + /* Data widths generaly supported by MMC cards */ + if ((Width != LDD_SDHC_CARD_DATA_WIDTH_1_BIT) && + (Width != LDD_SDHC_CARD_DATA_WIDTH_4_BIT) && + (Width != LDD_SDHC_CARD_DATA_WIDTH_8_BIT)) { + return ERR_PARAM_WIDTH; + } + } else { + /* Data widths generaly supported by SD cards */ + if ((Width != LDD_SDHC_CARD_DATA_WIDTH_1_BIT) && + (Width != LDD_SDHC_CARD_DATA_WIDTH_4_BIT)) { + return ERR_PARAM_WIDTH; + } + } + if (DeviceDataPrv->State == LDD_SDHC_IDLE) { + DeviceDataPrv->Cancel = FALSE; /* Clear the cancel flag */ + DeviceDataPrv->LastError = LDD_SDHC_ERR_OK; /* Clear the error code */ + DeviceDataPrv->LastErrorAddress = 0U; /* Clear the error address */ + DeviceDataPrv->DataWidth = Width; /* Store the new data width */ + /* Start data width selection */ + DeviceDataPrv->State = LDD_SDHC_DATA_WIDTH_SELECTION; + DeviceDataPrv->CmdState = SDHC1_CMD_START; + Finished = DataWidthSelection(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the data width selection state */ + (void)Finished; /* The return value is not used */ + } else { + Result = ERR_BUSY; /* Another operation is in progress */ + } + return Result; +} + +/* +** =================================================================== +** Method : SDHC1_SelectBusClock (component SDHC_LDD) +** +** Description : +** Initiates a SD bus clock frequency change. If the frequency +** is for high speed mode, initiates a high speed mode setup on +** the selected card. The card has to support the specified bus +** clock frequency. This method is enabled only if a list of +** bus clock frequencies is specified. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Frequency - Bus clock frequency identifier. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Setup started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** =================================================================== +*/ +LDD_TError SDHC1_SelectBusClock(LDD_SDHC1_TDeviceData *DeviceDataPtr, SDHC1_TBusClock Frequency) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + LDD_TError Result = ERR_OK; /* Error code storage */ + uint8_t Id = DeviceDataPrv->CardId; /* Card ID storage */ + static const uint32_t BusClockList[] = { /* Selectable bus clock frequencies in hertz specified by the timing dialog property */ + 390625u, + 12500000u, + 25000000u + }; + + /* Device state test - this test can be disabled by setting the "Ignore enable test" + property to the "yes" value in the "Configuration inspector" */ + if (!DeviceDataPrv->Enabled) { + return ERR_DISABLED; + } + if (DeviceDataPrv->State == LDD_SDHC_IDLE) { + DeviceDataPrv->Cancel = FALSE; /* Clear the cancel flag */ + DeviceDataPrv->LastError = LDD_SDHC_ERR_OK; /* Clear the error code */ + DeviceDataPrv->LastErrorAddress = 0U; /* Clear the error address */ + DeviceDataPrv->Frequency = Frequency; /* Store the new bus clock frequency ID */ + /* Start bus clock selection */ + DeviceDataPrv->State = LDD_SDHC_BUS_CLOCK_SELECTION; + if (((DeviceDataPrv->Cards[Id].Type == LDD_SDHC_SD) && (BusClockList[Frequency] >= 25000000U)) || + ((DeviceDataPrv->Cards[Id].Type == LDD_SDHC_MMC) && (BusClockList[Frequency] >= 20000000U))) { + /* Card needs speed mode switch */ + DeviceDataPrv->CmdState = SDHC1_CMD_START; + } else { + /* Card doesn't need speed mode switch */ + DeviceDataPrv->CmdState = SDHC1_CMD_FINISH; + } + if (BusClockSelection(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE)) { + DeviceDataPrv->State = LDD_SDHC_IDLE; + if (DeviceDataPrv->EventMask & LDD_SDHC_ON_FINISHED) { + SDHC1_OnFinished(DeviceDataPrv->UserDataPtr); /* Call the user event */ + } + } + } else { + Result = ERR_BUSY; /* Another operation is in progress */ + } + return Result; +} + +/* +** =================================================================== +** Method : SDHC1_SetVoltage (component SDHC_LDD) +** +** Description : +** Initiates a bus voltage change. The card has to support the +** specified voltage. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Voltage - Voltage identifier. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Setup started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** =================================================================== +*/ +LDD_TError SDHC1_SetVoltage(LDD_SDHC1_TDeviceData *DeviceDataPtr, LDD_SDHC_TVoltage Voltage) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + LDD_TError Result = ERR_OK; /* Error code storage */ + uint8_t Id; /* Card ID storage */ + + /* Device state test - this test can be disabled by setting the "Ignore enable test" + property to the "yes" value in the "Configuration inspector" */ + if (!DeviceDataPrv->Enabled) { + return ERR_DISABLED; + } + if (DeviceDataPrv->State == LDD_SDHC_IDLE) { + DeviceDataPrv->Cancel = FALSE; /* Clear the cancel flag */ + DeviceDataPrv->LastError = LDD_SDHC_ERR_OK; /* Clear the error code */ + DeviceDataPrv->LastErrorAddress = 0U; /* Clear the error address */ + /* Start a new voltage validation */ + DeviceDataPrv->State = LDD_SDHC_VOLTAGE_VALIDATION; + DeviceDataPrv->Substate = SDHC1_VV_START; + DeviceDataPrv->HighVoltage = (Voltage == LDD_SDHC_HIGH_VOLTAGE) ? TRUE : FALSE; /* Store the new voltage configuration */ + /* Remove cards from the device data structure */ + for (Id = 0U; Id < SDHC1_MAX_CARD_NUMBER; Id++) { + if (DeviceDataPrv->Cards[Id].Initialized) { + DeviceDataPrv->Cards[Id].Initialized = FALSE; + if (DeviceDataPrv->EventMask & LDD_SDHC_ON_CARD_REMOVED) { + SDHC1_OnCardRemoved(DeviceDataPrv->UserDataPtr, Id); /* Call the user event */ + } + } + } + DeviceDataPrv->CardId = SDHC1_NO_CARD; /* No card will be selected */ + /* Send reset command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, 0U); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD0_GO_IDLE_STATE, SDHC_PDD_NO_RESPONSE); + } else { + Result = ERR_BUSY; /* Another operation is in progress */ + } + return Result; +} + +/* +** =================================================================== +** Method : SDHC1_SetWriteProtection (component SDHC_LDD) +** +** Description : +** Initiates a write protection setup for the selected card. If +** the write protection type is LDD_SDHC_GROUP, write +** protection will be set for the addressed write protection +** group. Write protection group size is contained within the +** card information structure. If the write protection type is +** LDD_SDHC_CARD, write protection will be set for the whole +** card and the address parameter will be ignored. Only a whole +** card write protection clear can remove this protection. The +** card has to support write protection. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Type - Write protection type. +** Address - Address of the write protection +** group, if the write protection type is +** LDD_SDHC_GROUP. Byte address in case of +** standard capacity memory card and 512 byte +** block number in case of high capacity +** memory card. +** Protected - Indicates whether the +** addressed write protection group or card +** should be write protected or not. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Setup started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** =================================================================== +*/ +LDD_TError SDHC1_SetWriteProtection(LDD_SDHC1_TDeviceData *DeviceDataPtr, LDD_SDHC_TWriteProtectType Type, uint32_t Address, bool Protected) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + LDD_TError Result = ERR_OK; /* Error code storage */ + uint8_t Id = DeviceDataPrv->CardId; /* Card ID storage */ + bool Finished; /* Indicates whether write protection setup has finished */ + + /* Device state test - this test can be disabled by setting the "Ignore enable test" + property to the "yes" value in the "Configuration inspector" */ + if (!DeviceDataPrv->Enabled) { + return ERR_DISABLED; + } + if (DeviceDataPrv->State == LDD_SDHC_IDLE) { + DeviceDataPrv->Cancel = FALSE; /* Clear the cancel flag */ + DeviceDataPrv->LastError = LDD_SDHC_ERR_OK; /* Clear the error code */ + DeviceDataPrv->LastErrorAddress = 0U; /* Clear the error address */ + DeviceDataPrv->WriteProtType = Type; /* Store the write protection type to be set */ + DeviceDataPrv->Address = Address; /* Store the write protection group address */ + DeviceDataPrv->WriteProtFlag = Protected; /* Store whether to clear or set write protection */ + /* Start write protection setup */ + DeviceDataPrv->State = LDD_SDHC_WRITE_PROTECTION_SETUP; + if (Type == LDD_SDHC_GROUP) { /* Change sector group write protection */ + DeviceDataPrv->CmdState = SDHC1_CMD_START; + } else { /* Change the whole card write protection */ + if (Protected) { + DeviceDataPrv->Cards[Id].CSD[0] |= SDHC1_R2_TMP_WRITE_PROTECT_MASK; /* Set the temporary write protection bit in the CSD (card specific data) register */ + } else { + DeviceDataPrv->Cards[Id].CSD[0] &= (uint32_t)(~(uint32_t)SDHC1_R2_TMP_WRITE_PROTECT_MASK); /* Clear the temporary write protection bit in the CSD (card specific data) register */ + } + DeviceDataPrv->CmdState = SDHC1_CMD_START; + } + Finished = WriteProtectionSetup(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the write protection setup state */ + (void)Finished; /* The return value is not used */ + } else { + Result = ERR_BUSY; /* Another operation is in progress */ + } + return Result; +} + +/* +** =================================================================== +** Method : SDHC1_GetWriteProtection (component SDHC_LDD) +** +** Description : +** Initiates a write protection mask retrieval for the selected +** card. After the mask has been received, the OnFinished event +** is called and the mask is stored in the specified variable. +** The returned mask contains a bit mask of write protected +** write protection groups starting at the specified address. +** The least significant bit represents the status of the first +** write protection group. Bits of write protection groups out +** of range are cleared. The card has to support write +** protection. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Address - Address of the write protection +** group. Byte address in case of standard +** capacity memory card and 512 byte block +** number in case of high capacity memory card. +** * MaskPtr - Pointer to a variable, where the +** write protection groups status mask will be +** stored. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Write protection mask retrieval +** started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** =================================================================== +*/ +LDD_TError SDHC1_GetWriteProtection(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Address, uint32_t *MaskPtr) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + LDD_TError Result = ERR_OK; /* Error code storage */ + bool Finished; /* Indicates whether write protection retrieval has finished */ + + /* Device state test - this test can be disabled by setting the "Ignore enable test" + property to the "yes" value in the "Configuration inspector" */ + if (!DeviceDataPrv->Enabled) { + return ERR_DISABLED; + } + if (DeviceDataPrv->State == LDD_SDHC_IDLE) { + DeviceDataPrv->Cancel = FALSE; /* Clear the cancel flag */ + DeviceDataPrv->LastError = LDD_SDHC_ERR_OK; /* Clear the error code */ + DeviceDataPrv->LastErrorAddress = 0U; /* Clear the error address */ + DeviceDataPrv->Address = Address; /* Store the write protection group address */ + DeviceDataPrv->WriteProtMaskPtr = MaskPtr; /* Store a pointer to the write protection mask variable for later update */ + /* Start write protection retrieval */ + DeviceDataPrv->State = LDD_SDHC_WRITE_PROTECTION_RETRIEVAL; + DeviceDataPrv->CmdState = SDHC1_CMD_START; + Finished = WriteProtectionRetrieval(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the write protection retrieval state */ + (void)Finished; /* The return value is not used */ + } else { + Result = ERR_BUSY; /* Another operation is in progress */ + } + return Result; +} + +/* +** =================================================================== +** Method : SDHC1_CancelOperation (component SDHC_LDD) +** +** Description : +** Initiates a cancelation of the ongoing operation. The +** OnFinished event will be called for the stopped operation. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Operation cancelation started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_NOTAVAIL - No operation is in progress +** =================================================================== +*/ +LDD_TError SDHC1_CancelOperation(LDD_SDHC1_TDeviceData *DeviceDataPtr) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + LDD_TError Result = ERR_OK; /* Error code storage */ + + /* Device state test - this test can be disabled by setting the "Ignore enable test" + property to the "yes" value in the "Configuration inspector" */ + if (!DeviceDataPrv->Enabled) { + return ERR_DISABLED; + } + if (DeviceDataPrv->State != LDD_SDHC_IDLE) { + DeviceDataPrv->Cancel = TRUE; /* Set the cancel flag */ + if (DeviceDataPrv->CmdState == SDHC1_CMD_DATA) { + /* Send stop transmission command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, 0U); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD12_STOP_TRANSMISSION, SDHC_PDD_RESPONSE_LENGTH_48_BUSY_CHECK); + } + } else { + Result = ERR_NOTAVAIL; /* No operation is in progress */ + } + return Result; +} + +/* +** =================================================================== +** Method : SDHC1_GetStatus (component SDHC_LDD) +** +** Description : +** Returns the current component status, specifying the ongoing +** operation. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Returns : +** --- - Component status. +** =================================================================== +*/ +LDD_SDHC_TStatus SDHC1_GetStatus(LDD_SDHC1_TDeviceData *DeviceDataPtr) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + + return DeviceDataPrv->State; +} + +/* +** =================================================================== +** Method : SDHC1_GetError (component SDHC_LDD) +** +** Description : +** Returns the last error code and the memory address where the +** error occurred (if applicable). +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** * AddressPtr - Pointer to a variable, where +** the error address will be stored. +** Returns : +** --- - The last error code. +** =================================================================== +*/ +LDD_SDHC_TError SDHC1_GetError(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t *AddressPtr) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + LDD_SDHC_TError Error; /* Error code storage */ + + Error = DeviceDataPrv->LastError; + if (AddressPtr) { + *AddressPtr = DeviceDataPrv->LastErrorAddress; + } + return Error; +} + +/* +** =================================================================== +** Method : SDHC1_ConnectPin (component SDHC_LDD) +** +** Description : +** This method reconnects the requested pins associated with +** the selected peripheral in the component. This method is +** only available for CPU derivatives and peripherals that +** support the runtime pin sharing with other internal on-chip +** peripherals. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to device data +** structure. +** PinMask - Mask for the requested pins. The +** peripheral pins are reconnected according +** to this mask. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - OK +** ERR_PARAM_MASK - Invalid pin mask +** =================================================================== +*/ +LDD_TError SDHC1_ConnectPin(LDD_SDHC1_TDeviceData *DeviceDataPtr, LDD_TPinMask PinMask) +{ +// (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ +// if (PinMask & (LDD_TPinMask)(~(LDD_TPinMask)( +// LDD_SDHC_CLK_PIN | +// LDD_SDHC_CMD_PIN | +// LDD_SDHC_DAT0_PIN | +// LDD_SDHC_DAT1_PIN | +// LDD_SDHC_DAT2_PIN | +// LDD_SDHC_DAT3_PIN |0U))) { +// return ERR_PARAM_MASK; +// } +// if (PinMask & LDD_SDHC_CLK_PIN) { +// clrSetReg32Bits(PORTE_PCR2, 0x01000300U, 0x0400U); /* MUX=0x04U */ +// } +// if (PinMask & LDD_SDHC_CMD_PIN) { +// clrSetReg32Bits(PORTE_PCR3, 0x01000300U, 0x0400U); /* MUX=0x04U */ +// PORT_PDD_SetPinPullSelect(PORTE_BASE_PTR, SDHC1_PIN_CMD_PORT_INDEX, PORT_PDD_PULL_UP); +// PORT_PDD_SetPinPullEnable(PORTE_BASE_PTR, SDHC1_PIN_CMD_PORT_INDEX, PORT_PDD_PULL_ENABLE); +// PORT_PDD_SetPinDriveStrength(PORTE_BASE_PTR, SDHC1_PIN_CMD_PORT_INDEX, PORT_PDD_DRIVE_STRENGTH_HIGH); +// } +// if (PinMask & LDD_SDHC_DAT0_PIN) { +// clrSetReg32Bits(PORTE_PCR1, 0x01000300U, 0x0400U); /* MUX=0x04U */ +// PORT_PDD_SetPinPullSelect(PORTE_BASE_PTR, SDHC1_PIN_DAT0_PORT_INDEX, PORT_PDD_PULL_UP); +// PORT_PDD_SetPinPullEnable(PORTE_BASE_PTR, SDHC1_PIN_DAT0_PORT_INDEX, PORT_PDD_PULL_ENABLE); +// PORT_PDD_SetPinDriveStrength(PORTE_BASE_PTR, SDHC1_PIN_DAT0_PORT_INDEX, PORT_PDD_DRIVE_STRENGTH_HIGH); +// } +// if (PinMask & LDD_SDHC_DAT1_PIN) { +// clrSetReg32Bits(PORTE_PCR0, 0x01000300U, 0x0400U); /* MUX=0x04U */ +// PORT_PDD_SetPinPullSelect(PORTE_BASE_PTR, SDHC1_PIN_DAT1_PORT_INDEX, PORT_PDD_PULL_UP); +// PORT_PDD_SetPinPullEnable(PORTE_BASE_PTR, SDHC1_PIN_DAT1_PORT_INDEX, PORT_PDD_PULL_ENABLE); +// PORT_PDD_SetPinDriveStrength(PORTE_BASE_PTR, SDHC1_PIN_DAT1_PORT_INDEX, PORT_PDD_DRIVE_STRENGTH_HIGH); +// } +// if (PinMask & LDD_SDHC_DAT2_PIN) { +// clrSetReg32Bits(PORTE_PCR5, 0x01000300U, 0x0400U); /* MUX=0x04U */ +// PORT_PDD_SetPinPullSelect(PORTE_BASE_PTR, SDHC1_PIN_DAT2_PORT_INDEX, PORT_PDD_PULL_UP); +// PORT_PDD_SetPinPullEnable(PORTE_BASE_PTR, SDHC1_PIN_DAT2_PORT_INDEX, PORT_PDD_PULL_ENABLE); +// PORT_PDD_SetPinDriveStrength(PORTE_BASE_PTR, SDHC1_PIN_DAT2_PORT_INDEX, PORT_PDD_DRIVE_STRENGTH_HIGH); +// } +// if (PinMask & LDD_SDHC_DAT3_PIN) { +// clrSetReg32Bits(PORTE_PCR4, 0x01000300U, 0x0400U); /* MUX=0x04U */ +// PORT_PDD_SetPinPullSelect(PORTE_BASE_PTR, SDHC1_PIN_DAT3_PORT_INDEX, PORT_PDD_PULL_UP); +// PORT_PDD_SetPinPullEnable(PORTE_BASE_PTR, SDHC1_PIN_DAT3_PORT_INDEX, PORT_PDD_PULL_ENABLE); +// PORT_PDD_SetPinDriveStrength(PORTE_BASE_PTR, SDHC1_PIN_DAT3_PORT_INDEX, PORT_PDD_DRIVE_STRENGTH_HIGH); +// } + return ERR_OK; +} + +/* +** =================================================================== +** Method : SDHC1_SetOperationMode (component SDHC_LDD) +** +** Description : +** This method requests to change the component's operation +** mode. Upon a request to change the operation mode, the +** component will finish a pending job first and then notify a +** caller that an operation mode has been changed. When no job +** is pending (ERR_OK), the component changes an operation mode +** immediately and notify a caller about this change. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Device data structure +** pointer returned by Init method. +** OperationMode - Requested driver +** operation mode. +** ModeChangeCallback - Callback to +** notify the upper layer once a mode has been +** changed. +** * ModeChangeCallbackParamPtr +** - Pointer to callback parameter to notify +** the upper layer once a mode has been +** changed. +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_PARAM_MODE - Invalid operation mode +** ERR_BUSY - A job is pending +** =================================================================== +*/ +LDD_TError SDHC1_SetOperationMode(LDD_SDHC1_TDeviceData *DeviceDataPtr, LDD_TDriverOperationMode OperationMode, LDD_TCallback ModeChangeCallback, LDD_TCallbackParam *ModeChangeCallbackParamPtr) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + + /* Device state test - this test can be disabled by setting the "Ignore enable test" + property to the "yes" value in the "Configuration inspector" */ + if (!DeviceDataPrv->Enabled) { + return ERR_DISABLED; + } + if (DeviceDataPrv->State != LDD_SDHC_IDLE) { + return ERR_BUSY; + } + switch (OperationMode) { + case DOM_RUN: + /* SIM_SCGC3: SDHC=1 */ + SIM_vSetReg32( SIM_SCGC3, SIM_SCGC3_SDHC_MASK ); //SIM_SCGC3 |= (uint32_t)0x00020000UL; + SDHC_PDD_EnableSDHCClock(SDHC_BASE_PTR, PDD_ENABLE); + break; + case DOM_WAIT: + case DOM_SLEEP: + SDHC_PDD_EnableSDHCClock(SDHC_BASE_PTR, PDD_DISABLE); + break; + case DOM_STOP: + SDHC_PDD_EnableSDHCClock(SDHC_BASE_PTR, PDD_DISABLE); + /* SIM_SCGC3: SDHC=0 */ + SIM_vClrReg32( SIM_SCGC3, SIM_SCGC3_SDHC_MASK ); //SIM_SCGC3 &= (uint32_t)~0x00020000UL; + break; + default: + return ERR_PARAM_MODE; /* Invalid operation mode parameter */ + } + if (ModeChangeCallback != NULL) { + ModeChangeCallback(ModeChangeCallbackParamPtr); + } + return ERR_OK; +} + +/* +** =================================================================== +** Method : SDHC1_GetDriverState (component SDHC_LDD) +** +** Description : +** This method returns the current driver status. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Device data structure +** pointer returned by Init method. +** Returns : +** --- - +** The current driver status mask. The +** following status masks defined in PE_LDD.h +** can be used to check the current driver +** status: +** PE_LDD_DRIVER_DISABLED_IN_CLOCK_CONFIGURATION - +** Driver is disabled in the current speed +** mode +** PE_LDD_DRIVER_DISABLED_BY_USER - Driver is +** disabled by the user +** PE_LDD_DRIVER_BUSY - Driver is in the BUSY +** state +** =================================================================== +*/ +LDD_TDriverState SDHC1_GetDriverState(LDD_SDHC1_TDeviceData *DeviceDataPtr) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + LDD_TDriverState DriverState = 0U; /* Driver state storage */ + + if (!DeviceDataPrv->EnabledMode) { + DriverState |= LDD_DRIVER_DISABLED_IN_CLOCK_CONFIGURATION; + } + if (!DeviceDataPrv->Enabled) { + DriverState |= LDD_DRIVER_DISABLED_BY_USER; + } + if (DeviceDataPrv->State != LDD_SDHC_IDLE) { + DriverState |= LDD_DRIVER_BUSY; + } + return DriverState; +} + +/* +** =================================================================== +** Method : SDHC1_VoltageValidation (component SDHC_LDD) +** +** Description : +** Voltage validation state handler. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void VoltageValidation(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + LDD_SDHC_TError Error = LDD_SDHC_ERR_OK; /* Error code storage */ + + switch (DeviceDataPrv->Substate) { + case SDHC1_VV_START: + DeviceDataPrv->CardsVoltages = 0; + /* Start with SD card version 2.0 or later interface conditions check */ + DeviceDataPrv->Substate = SDHC1_VV_SDHC_CHECK; + DeviceDataPrv->CmdState = SDHC1_CMD_START; + VoltageValidation(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the voltage validation state */ + break; + case SDHC1_VV_SDHC_CHECK: + switch (DeviceDataPrv->CmdState) { + case SDHC1_CMD_START: + DeviceDataPrv->CmdState = SDHC1_CMD_FINISH; + /* Send interface conditions request command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, + ((DeviceDataPrv->HighVoltage == TRUE) ? /* Propose bus voltage configuration */ + SDHC1_IF_COND_HIGH_VOLTAGE_MASK : + SDHC1_IF_COND_LOW_VOLTAGE_MASK) | + SDHC1_IF_COND_CHECK_PATTERN); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD8_SEND_EXT_CSD, SDHC_PDD_RESPONSE_LENGTH_48); + break; + case SDHC1_CMD_FINISH: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if (Error == LDD_SDHC_ERR_OK) { + DeviceDataPrv->HighCapacity = TRUE; /* Card is an SD card version 2.0 or later (possibly high capacity) */ + } else if (Error == LDD_SDHC_ERR_TIMEOUT) { + DeviceDataPrv->HighCapacity = FALSE; /* Card is a normal SD or other type of card */ + } else { + DeviceDataPrv->LastError = Error; + } + /* Continue with SD card interface conditions check */ + DeviceDataPrv->Substate = SDHC1_VV_SD_CHECK; + DeviceDataPrv->CmdState = SDHC1_CMD_START; + DeviceDataPrv->RetryCounter = SDHC1_VOLT_VALID_RETRY_COUNT; /* Limit the interface conditions request number */ + VoltageValidation(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the voltage validation state */ + break; + default: + break; + } + break; + case SDHC1_VV_SD_CHECK: + switch (DeviceDataPrv->CmdState) { + case SDHC1_CMD_START: + DeviceDataPrv->CmdState = SDHC1_CMD_ACMD; + /* Start application specific command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, 0U); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD55_APP_CMD, SDHC_PDD_RESPONSE_LENGTH_48); + break; + case SDHC1_CMD_ACMD: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if ((Error == LDD_SDHC_ERR_OK) || (Error == LDD_SDHC_ERR_INTERNAL_FAILURE)) { + DeviceDataPrv->CmdState = SDHC1_CMD_FINISH; + /* Send OCR (operation conditions register) request */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, + ((DeviceDataPrv->HighCapacity == TRUE) ? SDHC1_OCR_HIGH_CAPACITY_MASK : 0U) | + ((DeviceDataPrv->HighVoltage == TRUE) ? /* Propose bus voltage configuration */ + SDHC1_OCR_HIGH_VOLTAGE_MASK : + SDHC1_OCR_LOW_VOLTAGE_MASK)); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_ACMD41_SD_APP_OP_COND, SDHC_PDD_RESPONSE_LENGTH_48); + } else { + if (Error == LDD_SDHC_ERR_COMMAND_CRC) { + DeviceDataPrv->LastError = Error; + } + /* No more SD card, check MMC cards */ + DeviceDataPrv->Substate = SDHC1_VV_MMC_CHECK; + DeviceDataPrv->CmdState = SDHC1_CMD_START; + DeviceDataPrv->RetryCounter = SDHC1_VOLT_VALID_RETRY_COUNT; /* Limit the interface conditions request number */ + VoltageValidation(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the voltage validation state */ + } + break; + case SDHC1_CMD_FINISH: + Error = GetCommandError(DeviceDataPrv, Flags, SDHC1_NO_RESPONSE); /* Check host error flags */ + if ((Error == LDD_SDHC_ERR_OK) && Response) { + if (SDHC1_R3_OCR_IS_CARD_POWER_UP(Response)) { + /* Card is powered up, start the registration */ + DeviceDataPrv->CardType = LDD_SDHC_SD; + DeviceDataPrv->CardsVoltages |= *Response & /* Save card voltage capabilities */ + (SDHC1_OCR_HIGH_VOLTAGE_MASK | SDHC1_OCR_LOW_VOLTAGE_MASK); + DeviceDataPrv->HighCapacity = (SDHC1_R3_OCR_IS_CARD_HIGH_CAPACITY(Response)) ? TRUE : FALSE; + DeviceDataPrv->State = LDD_SDHC_CARD_REGISTRATION; + DeviceDataPrv->Substate = SDHC1_CR_START; + CardRegistration(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the card registration state */ + } else if (DeviceDataPrv->RetryCounter--) { + /* Card is not powered up yet, resend request */ + DeviceDataPrv->CmdState = SDHC1_CMD_START; + VoltageValidation(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the voltage validation state */ + } else { + /* Power up reached timeout, check MMC cards */ + DeviceDataPrv->LastError = LDD_SDHC_ERR_TIMEOUT; + DeviceDataPrv->Substate = SDHC1_VV_MMC_CHECK; + DeviceDataPrv->CmdState = SDHC1_CMD_START; + } + } else { + if (Error == LDD_SDHC_ERR_COMMAND_CRC) { + DeviceDataPrv->LastError = Error; + } + /* No response for ACMD41, check MMC cards */ + DeviceDataPrv->Substate = SDHC1_VV_MMC_CHECK; + DeviceDataPrv->CmdState = SDHC1_CMD_START; + } + if (DeviceDataPrv->Substate == SDHC1_VV_MMC_CHECK) { + DeviceDataPrv->RetryCounter = SDHC1_VOLT_VALID_RETRY_COUNT; /* Limit the interface conditions request number */ + /* Send reset command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, 0U); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD0_GO_IDLE_STATE, SDHC_PDD_NO_RESPONSE); + } + break; + default: + break; + } + break; + case SDHC1_VV_MMC_CHECK: + switch (DeviceDataPrv->CmdState) { + case SDHC1_CMD_START: + DeviceDataPrv->CmdState = SDHC1_CMD_FINISH; + /* Send OCR (operation conditions register) request */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, + ((DeviceDataPrv->HighVoltage == TRUE) ? /* Propose bus voltage configuration */ + SDHC1_OCR_HIGH_VOLTAGE_MASK : + SDHC1_OCR_LOW_VOLTAGE_MASK) | + SDHC1_OCR_HIGH_CAPACITY_MASK); /* Indicate high capacity card support by the host */ + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD1_SEND_OP_COND, SDHC_PDD_RESPONSE_LENGTH_48); + break; + case SDHC1_CMD_FINISH: + Error = GetCommandError(DeviceDataPrv, Flags, SDHC1_NO_RESPONSE); /* Check host error flags */ + if ((Error == LDD_SDHC_ERR_OK) && Response) { + if (SDHC1_R3_OCR_IS_CARD_POWER_UP(Response)) { + /* Card is powered up, start the registration */ + DeviceDataPrv->CardType = LDD_SDHC_MMC; + DeviceDataPrv->CardsVoltages |= *Response & /* Save card voltage capabilities */ + (SDHC1_OCR_HIGH_VOLTAGE_MASK | SDHC1_OCR_LOW_VOLTAGE_MASK); + DeviceDataPrv->HighCapacity = (SDHC1_R3_OCR_IS_CARD_HIGH_CAPACITY(Response)) ? TRUE : FALSE; + DeviceDataPrv->State = LDD_SDHC_CARD_REGISTRATION; + DeviceDataPrv->Substate = SDHC1_CR_START; + CardRegistration(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the card registration state */ + } else if (DeviceDataPrv->RetryCounter--) { + /* Card is not powered up yet, resend request */ + DeviceDataPrv->CmdState = SDHC1_CMD_START; + VoltageValidation(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the voltage validation state */ + } else { + /* Power up reached timeout, finish */ + DeviceDataPrv->LastError = LDD_SDHC_ERR_TIMEOUT; + DeviceDataPrv->Substate = SDHC1_VV_FINISH; + VoltageValidation(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the voltage validation state */ + } + } else { + if (Error == LDD_SDHC_ERR_COMMAND_CRC) { + DeviceDataPrv->LastError = Error; + } + /* No more MMC card, finish */ + DeviceDataPrv->Substate = SDHC1_VV_FINISH; + VoltageValidation(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the voltage validation state */ + } + break; + default: + break; + } + break; + case SDHC1_VV_FINISH: + DeviceDataPrv->State = LDD_SDHC_IDLE; + if (DeviceDataPrv->EventMask & LDD_SDHC_ON_FINISHED) { + SDHC1_OnFinished(DeviceDataPrv->UserDataPtr); /* Call the user event */ + } + break; + default: + break; + } +} + +/* +** =================================================================== +** Method : CardRegistration (component SDHC_LDD) +** +** Description : +** Card registration state handler. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void CardRegistration(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + LDD_SDHC_TError Error = LDD_SDHC_ERR_OK; /* Error code storage */ + uint8_t Id; /* Card ID storage */ + uint32_t Index; /* Array index */ + + switch (DeviceDataPrv->Substate) { + case SDHC1_CR_START: + switch (DeviceDataPrv->CardType) { + case LDD_SDHC_SD: + case LDD_SDHC_MMC: + /* Send CID register request */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, 0U); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD2_ALL_SEND_CID, SDHC_PDD_RESPONSE_LENGTH_136); + DeviceDataPrv->Substate = SDHC1_CR_GET_CID; + break; + default: + break; + } + break; + case SDHC1_CR_GET_CID: + switch (DeviceDataPrv->CardType) { + case LDD_SDHC_SD: + case LDD_SDHC_MMC: + Error = GetCommandError(DeviceDataPrv, Flags, SDHC1_NO_RESPONSE); /* Check host error flags */ + if ((Error == LDD_SDHC_ERR_OK) && Response) { + /* Assign a free data structure to the card */ + for (Id = 0U; Id < SDHC1_MAX_CARD_NUMBER; Id++) { + if (!DeviceDataPrv->Cards[Id].Initialized) { + /* Initialize the data structure */ + DeviceDataPrv->NewCardId = Id; /* Assign a component related ID to the card */ + DeviceDataPrv->Cards[Id].Initialized = TRUE; /* Mark the data structure as used */ + DeviceDataPrv->Cards[Id].Type = DeviceDataPrv->CardType; + DeviceDataPrv->Cards[Id].CID[0] = Response[0]; /* Store the received card ID */ + DeviceDataPrv->Cards[Id].CID[1] = Response[1]; + DeviceDataPrv->Cards[Id].CID[2] = Response[2]; + DeviceDataPrv->Cards[Id].CID[3] = Response[3]; + for (Index = 0U; Index < sizeof(DeviceDataPrv->Cards[Id].Block); Index++) { + DeviceDataPrv->Cards[Id].Block[Index] = 0U; /* Clear the card info block */ + } + DeviceDataPrv->Cards[Id].HighCapacity = DeviceDataPrv->HighCapacity; + DeviceDataPrv->Cards[Id].DataWidths = LDD_SDHC_CARD_DATA_WIDTH_1_BIT; /* Initialize supported data widths */ + if (DeviceDataPrv->CardType == LDD_SDHC_SD) { + /* Request an RCA (relative card address) from the card */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, 0U); + } else { + /* Create a new RCA (relative card address) */ + DeviceDataPrv->Cards[Id].RCA = (uint16_t)((uint16_t)Id + 2U); /* MMC RCAs must start from 2 */ + /* Send the RCA (relative card address) to the card */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, (uint32_t)((uint32_t)Id + 2U) << 16); + } + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD3_SET_RELATIVE_ADDR, SDHC_PDD_RESPONSE_LENGTH_48); + DeviceDataPrv->Substate = SDHC1_CR_GET_RCA; + } + } + } else { + if (Error != LDD_SDHC_ERR_TIMEOUT) { + DeviceDataPrv->LastError = Error; + } + /* No more card for registration */ + DeviceDataPrv->Substate = SDHC1_CR_FINISH; + CardRegistration(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the card registration state */ + } + break; + default: + break; + } + break; + case SDHC1_CR_GET_RCA: + switch (DeviceDataPrv->CardType) { + case LDD_SDHC_SD: + case LDD_SDHC_MMC: + Error = GetCommandError(DeviceDataPrv, Flags, SDHC1_NO_RESPONSE); /* Check host error flags */ + if ((Error == LDD_SDHC_ERR_OK) && Response) { + Id = DeviceDataPrv->NewCardId; + if (DeviceDataPrv->CardType == LDD_SDHC_SD) { + DeviceDataPrv->Cards[Id].RCA = SDHC1_R6_GET_RCA(Response); /* Store the received RCA (relative card address) */ + } + if (DeviceDataPrv->EventMask & LDD_SDHC_ON_CARD_INSERTED) { + SDHC1_OnCardInserted(DeviceDataPrv->UserDataPtr, Id); /* Call the user event */ + } + } else { + DeviceDataPrv->LastError = Error; + } + DeviceDataPrv->State = LDD_SDHC_CARD_REGISTRATION; + DeviceDataPrv->Substate = SDHC1_CR_FINISH; + CardRegistration(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the card registration state */ + break; + default: + break; + } + break; + case SDHC1_CR_FINISH: + switch (DeviceDataPrv->CardType) { + case LDD_SDHC_SD: + /* An SD card is registered, finish the voltage validation */ + case LDD_SDHC_MMC: + /* MMC cards are checked as the last, finish the voltage validation */ + DeviceDataPrv->State = LDD_SDHC_VOLTAGE_VALIDATION; + DeviceDataPrv->Substate = SDHC1_VV_FINISH; + VoltageValidation(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the voltage validation state */ + break; + default: + break; + } + break; + default: + break; + } +} + +/* +** =================================================================== +** Method : CardInfoRetrieval (component SDHC_LDD) +** +** Description : +** Card info retrieval state handler. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void CardInfoRetrieval(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + bool Finished = FALSE; /* Indicates card info retrieval end */ + LDD_SDHC_TError Error = LDD_SDHC_ERR_OK; /* Error code storage */ + LDD_SDHC_TCardInfo *InfoPtr; /* Card info pointer storage */ + uint8_t Id = DeviceDataPrv->CardId; /* Card ID storage */ + uint8_t BusWidths; /* Supported bus widths storage */ + uint32_t Index; /* Array index */ + + switch (DeviceDataPrv->Substate) { + case SDHC1_CIR_START: + if (DeviceDataPrv->CardState != SDHC1_STAND_BY) { + /* Change card state to stand-by */ + DeviceDataPrv->Substate = SDHC1_CIR_STAND_BY_STATE; + /* Send unselect card command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, 0U); /* Set 0 as command argument to unselect card */ + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD7_SELECT_CARD, SDHC_PDD_RESPONSE_LENGTH_48); + } else { + DeviceDataPrv->Substate = SDHC1_CIR_GET_CSD; + CardInfoRetrieval(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the card info retrieval state */ + } + break; + case SDHC1_CIR_STAND_BY_STATE: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if (Error != LDD_SDHC_ERR_TIMEOUT) { + DeviceDataPrv->LastError = Error; + } + DeviceDataPrv->CardState = SDHC1_STAND_BY; + DeviceDataPrv->Substate = SDHC1_CIR_GET_CSD; + /* Send CSD (card specific data) request command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, + SDHC1_CMD_ARG_RCA((uint32_t)DeviceDataPrv->Cards[Id].RCA)); /* Set the card RCA (relative card address) as command argument */ + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD9_SEND_CSD, SDHC_PDD_RESPONSE_LENGTH_136); + break; + case SDHC1_CIR_GET_CSD: + Error = GetCommandError(DeviceDataPrv, Flags, SDHC1_NO_RESPONSE); /* Check host error flags */ + if ((Error == LDD_SDHC_ERR_OK) && Response) { + /* Store the CSD (card specific data) register contained in the response */ + DeviceDataPrv->Cards[Id].CSD[0] = Response[0]; + DeviceDataPrv->Cards[Id].CSD[1] = Response[1]; + DeviceDataPrv->Cards[Id].CSD[2] = Response[2]; + DeviceDataPrv->Cards[Id].CSD[3] = Response[3]; + /* Change card state to transfer */ + DeviceDataPrv->Substate = SDHC1_CIR_TRANSFER_STATE; + /* Send card selection command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, + SDHC1_CMD_ARG_RCA((uint32_t)DeviceDataPrv->Cards[Id].RCA)); /* Set the card RCA (relative card address) as command argument */ + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD7_SELECT_CARD, SDHC_PDD_RESPONSE_LENGTH_48_BUSY_CHECK); + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + case SDHC1_CIR_TRANSFER_STATE: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if ((Error == LDD_SDHC_ERR_OK) && Response) { + if (SDHC1_R1_IS_READY_FOR_DATA(Response)) { + DeviceDataPrv->CardState = SDHC1_TRANSFER; + if (DeviceDataPrv->CardType == LDD_SDHC_MMC) { + if (SDHC1_R2_MMC_GET_SPEC_VERS(Response) >= SDHC1_MMC_CSD_SPEC_VERS_4_X) { + DeviceDataPrv->Substate = SDHC1_CIR_GET_EXT_CSD; + DeviceDataPrv->CmdState = SDHC1_CMD_START; + } else { + DeviceDataPrv->Substate = SDHC1_CIR_FINISH; + } + //CardInfoRetrieval(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the card info retrieval state */ + } else { + DeviceDataPrv->Substate = SDHC1_CIR_GET_SCR; + DeviceDataPrv->CmdState = SDHC1_CMD_START; + CardInfoRetrieval(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the card info retrieval state */ + } + } else { + /* Send status request command */ + SendCardStatusRequest(DeviceDataPrv); + } + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + case SDHC1_CIR_GET_EXT_CSD: + switch (DeviceDataPrv->CmdState) { + case SDHC1_CMD_START: + DeviceDataPrv->CmdState = SDHC1_CMD_FINISH; + /* Set data transfer size */ + SDHC_PDD_SetBlockSize(SDHC_BASE_PTR, SDHC1_EXT_CSD_SIZE); + SDHC_PDD_SetBlockCount(SDHC_BASE_PTR, 1U); + /* Set DMA transfer properties */ + DeviceDataPrv->TransferTable[0].Attributes = SDHC1_SINGLE_BLOCK_TRANS_ATTRS; + DeviceDataPrv->TransferTable[0].Length = SDHC1_EXT_CSD_SIZE; + DeviceDataPrv->TransferTable[0].Address = (uint32_t)DeviceDataPrv->Cards[Id].Block; + SDHC_PDD_SetADMAAddress(SDHC_BASE_PTR, DeviceDataPrv->TransferTable); + /* Send extended CSD (card specific data) request command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, 0U); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, SDHC_PDD_CMD8_SEND_EXT_CSD, + SDHC_PDD_ENABLE_DMA | SDHC_PDD_DATA_PRESENT | SDHC_PDD_DATA_READ | SDHC_PDD_RESPONSE_LENGTH_48); + break; + case SDHC1_CMD_FINISH: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if (Error == LDD_SDHC_ERR_OK) { + DeviceDataPrv->CmdState = SDHC1_CMD_DATA; + CardInfoRetrieval(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the card info retrieval state */ + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + case SDHC1_CMD_DATA: + Error = GetCommandError(DeviceDataPrv, Flags, SDHC1_NO_RESPONSE); /* Check host error flags */ + if (Error == LDD_SDHC_ERR_OK) { + /* Start the bus testing procedure */ + DeviceDataPrv->Substate = SDHC1_CIR_BUS_TEST_4_BIT_WRITE; + DeviceDataPrv->CmdState = SDHC1_CMD_START; + CardInfoRetrieval(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the card info retrieval state */ + } else { + DeviceDataPrv->LastError = Error; + DeviceDataPrv->LastErrorAddress = SDHC_PDD_GetDMAAddress(SDHC_BASE_PTR); + Finished = TRUE; + } + break; + default: + break; + } + break; + case SDHC1_CIR_BUS_TEST_4_BIT_WRITE: + case SDHC1_CIR_BUS_TEST_8_BIT_WRITE: + switch (DeviceDataPrv->CmdState) { + case SDHC1_CMD_START: + DeviceDataPrv->CmdState = SDHC1_CMD_FINISH; + /* Clear the bus test buffer */ + for (Index = 0U; Index < 8U; Index++) { + DeviceDataPrv->BusTestPtr[Index] = 0U; + } + /* Create the bus test pattern */ + if (DeviceDataPrv->Substate == SDHC1_CIR_BUS_TEST_4_BIT_WRITE) { + DeviceDataPrv->BusTestPtr[0] = 0x5AU; + } else { + DeviceDataPrv->BusTestPtr[0] = 0x55U; + DeviceDataPrv->BusTestPtr[1] = 0xAAU; + } + SDHC_PDD_SetDataTransferWidth(SDHC_BASE_PTR, + (DeviceDataPrv->Substate == SDHC1_CIR_BUS_TEST_4_BIT_WRITE) ? + SDHC_PDD_4_BIT_MODE : SDHC_PDD_8_BIT_MODE); + /* Set data transfer size */ + SDHC_PDD_SetBlockSize(SDHC_BASE_PTR, + (DeviceDataPrv->Substate == SDHC1_CIR_BUS_TEST_4_BIT_WRITE) ? 4U : 8U); + SDHC_PDD_SetBlockCount(SDHC_BASE_PTR, 1U); + /* Set DMA transfer properties */ + DeviceDataPrv->TransferTable[0].Attributes = SDHC1_SINGLE_BLOCK_TRANS_ATTRS; + DeviceDataPrv->TransferTable[0].Length = + (DeviceDataPrv->Substate == SDHC1_CIR_BUS_TEST_4_BIT_WRITE) ? 4U : 8U; + DeviceDataPrv->TransferTable[0].Address = (uint32_t)DeviceDataPrv->BusTestPtr; + SDHC_PDD_SetADMAAddress(SDHC_BASE_PTR, DeviceDataPrv->TransferTable); + /* Send bus testing pattern write command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, 0U); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, SDHC_PDD_CMD19_BUS_TEST_WRITE, + SDHC_PDD_ENABLE_DMA | SDHC_PDD_DATA_PRESENT | SDHC_PDD_DATA_WRITE | SDHC_PDD_RESPONSE_LENGTH_48); + break; + case SDHC1_CMD_FINISH: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if (Error == LDD_SDHC_ERR_OK) { + DeviceDataPrv->CmdState = SDHC1_CMD_DATA; + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + case SDHC1_CMD_DATA: + Error = GetCommandError(DeviceDataPrv, Flags, SDHC1_NO_RESPONSE); /* Check host error flags */ + if ((Error == LDD_SDHC_ERR_OK) || (Error == LDD_SDHC_ERR_DATA_CRC)) { + DeviceDataPrv->Substate = + (DeviceDataPrv->Substate == SDHC1_CIR_BUS_TEST_4_BIT_WRITE) ? + SDHC1_CIR_BUS_TEST_4_BIT_READ : SDHC1_CIR_BUS_TEST_8_BIT_READ; + DeviceDataPrv->CmdState = SDHC1_CMD_START; + CardInfoRetrieval(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the card info retrieval state */ + } else { + DeviceDataPrv->LastError = Error; + DeviceDataPrv->LastErrorAddress = SDHC_PDD_GetDMAAddress(SDHC_BASE_PTR); + Finished = TRUE; + } + break; + default: + break; + } + break; + case SDHC1_CIR_BUS_TEST_4_BIT_READ: + case SDHC1_CIR_BUS_TEST_8_BIT_READ: + switch (DeviceDataPrv->CmdState) { + case SDHC1_CMD_START: + DeviceDataPrv->CmdState = SDHC1_CMD_FINISH; + /* Set data transfer size */ + SDHC_PDD_SetBlockSize(SDHC_BASE_PTR, + (DeviceDataPrv->Substate == SDHC1_CIR_BUS_TEST_4_BIT_READ) ? 4U : 8U); + SDHC_PDD_SetBlockCount(SDHC_BASE_PTR, 1U); + /* Set DMA transfer properties */ + DeviceDataPrv->TransferTable[0].Attributes = SDHC1_SINGLE_BLOCK_TRANS_ATTRS; + DeviceDataPrv->TransferTable[0].Length = + (DeviceDataPrv->Substate == SDHC1_CIR_BUS_TEST_4_BIT_READ) ? 4U : 8U; + DeviceDataPrv->TransferTable[0].Address = (uint32_t)DeviceDataPrv->BusTestPtr; + SDHC_PDD_SetADMAAddress(SDHC_BASE_PTR, DeviceDataPrv->TransferTable); + /* Send bus testing pattern write command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, 0U); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, SDHC_PDD_CMD14_BUS_TEST_READ, + SDHC_PDD_ENABLE_DMA | SDHC_PDD_DATA_PRESENT | SDHC_PDD_DATA_READ | SDHC_PDD_RESPONSE_LENGTH_48); + break; + case SDHC1_CMD_FINISH: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if (Error == LDD_SDHC_ERR_OK) { + DeviceDataPrv->CmdState = SDHC1_CMD_DATA; + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + case SDHC1_CMD_DATA: + Error = GetCommandError(DeviceDataPrv, Flags, SDHC1_NO_RESPONSE); /* Check host error flags */ + if ((Error == LDD_SDHC_ERR_OK) || (Error == LDD_SDHC_ERR_DATA_CRC)) { + if (DeviceDataPrv->Substate == SDHC1_CIR_BUS_TEST_4_BIT_READ) { + /* XNOR the written bus test pattern with the read bus test result */ + DeviceDataPrv->BusTestPtr[0] = (DeviceDataPrv->BusTestPtr[0] & 0x5AU) | + ((uint8_t)(~DeviceDataPrv->BusTestPtr[0]) & (uint8_t)(~0x5AU)); + if (DeviceDataPrv->BusTestPtr[0] == 0U) { + /* 4-bit data bus test succeeded */ + DeviceDataPrv->Substate = SDHC1_CIR_BUS_TEST_8_BIT_WRITE; + DeviceDataPrv->CmdState = SDHC1_CMD_START; + DeviceDataPrv->Cards[Id].DataWidths |= LDD_SDHC_CARD_DATA_WIDTH_4_BIT; + } else { + DeviceDataPrv->Substate = SDHC1_CIR_FINISH; + } + } else { + /* XNOR the written bus test pattern with the read bus test result */ + DeviceDataPrv->BusTestPtr[0] = (DeviceDataPrv->BusTestPtr[0] & 0x55U) | + ((uint8_t)(~DeviceDataPrv->BusTestPtr[0]) & (uint8_t)(~0x55U)); + DeviceDataPrv->BusTestPtr[1] = (DeviceDataPrv->BusTestPtr[1] & 0xAAU) | + ((uint8_t)(~DeviceDataPrv->BusTestPtr[1]) & (uint8_t)(~0xAAU)); + if ((DeviceDataPrv->BusTestPtr[0] == 0U) && (DeviceDataPrv->BusTestPtr[1] == 0U)) { + /* 8-bit data bus test succeeded */ + DeviceDataPrv->Cards[Id].DataWidths |= LDD_SDHC_CARD_DATA_WIDTH_8_BIT; + } + DeviceDataPrv->Substate = SDHC1_CIR_FINISH; + } + } else { + DeviceDataPrv->LastError = Error; + DeviceDataPrv->LastErrorAddress = SDHC_PDD_GetDMAAddress(SDHC_BASE_PTR); + Finished = TRUE; + } + if ((DeviceDataPrv->Substate == SDHC1_CIR_FINISH) || Finished) { + /* Restore the data width */ + switch (DeviceDataPrv->DataWidth) { + case LDD_SDHC_CARD_DATA_WIDTH_1_BIT: + SDHC_PDD_SetDataTransferWidth(SDHC_BASE_PTR, SDHC_PDD_1_BIT_MODE); + break; + case LDD_SDHC_CARD_DATA_WIDTH_4_BIT: + SDHC_PDD_SetDataTransferWidth(SDHC_BASE_PTR, SDHC_PDD_4_BIT_MODE); + break; + case LDD_SDHC_CARD_DATA_WIDTH_8_BIT: + SDHC_PDD_SetDataTransferWidth(SDHC_BASE_PTR, SDHC_PDD_8_BIT_MODE); + break; + default: + break; + } + } + if (!Finished) { + CardInfoRetrieval(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the card info retrieval state */ + } + break; + default: + break; + } + break; + case SDHC1_CIR_GET_SCR: + switch (DeviceDataPrv->CmdState) { + case SDHC1_CMD_START: + DeviceDataPrv->CmdState = SDHC1_CMD_ACMD; + /* Start application specific command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, + SDHC1_CMD_ARG_RCA((uint32_t)DeviceDataPrv->Cards[Id].RCA)); /* Set the card RCA (relative card address) as command argument */ + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD55_APP_CMD, SDHC_PDD_RESPONSE_LENGTH_48); + break; + case SDHC1_CMD_ACMD: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if (Error == LDD_SDHC_ERR_OK) { + DeviceDataPrv->CmdState = SDHC1_CMD_FINISH; + /* Set data transfer size */ + SDHC_PDD_SetBlockSize(SDHC_BASE_PTR, SDHC1_SCR_SIZE); + SDHC_PDD_SetBlockCount(SDHC_BASE_PTR, 1U); + /* Set DMA transfer properties */ + /* Configure card detection and DMA mode */ + /* SDHC_PROCTL: ??=0,??=0,??=0,??=0,??=0,WECRM=0,WECINS=0,WECINT=0,??=0,??=0,??=0,??=0,IABG=0,RWCTL=0,CREQ=0,SABGREQ=0,??=0,??=0,??=0,??=0,??=0,??=0,DMAS=2,CDSS=0,CDTL=0,EMODE=2,D3CD=0,DTW=0,LCTL=0 */ + SDHC_PROCTL = (uint32_t)0x0220UL; + + DeviceDataPrv->TransferTable[0].Attributes = SDHC1_SINGLE_BLOCK_TRANS_ATTRS; + DeviceDataPrv->TransferTable[0].Length = SDHC1_SCR_SIZE; + DeviceDataPrv->TransferTable[0].Address = (uint32_t)DeviceDataPrv->Cards[Id].Block; + SDHC_PDD_SetADMAAddress(SDHC_BASE_PTR, DeviceDataPrv->TransferTable); + /* Send SCR (SD card configuration register) request command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, 0U); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, SDHC_PDD_ACMD51_SEND_SCR, + SDHC_PDD_ENABLE_DMA | SDHC_PDD_DATA_PRESENT | SDHC_PDD_DATA_READ | SDHC_PDD_RESPONSE_LENGTH_48); + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + case SDHC1_CMD_FINISH: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if (Error == LDD_SDHC_ERR_OK) { + DeviceDataPrv->CmdState = SDHC1_CMD_DATA; + //CardInfoRetrieval(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the card info retrieval state */ + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + case SDHC1_CMD_DATA: + Error = GetCommandError(DeviceDataPrv, Flags, SDHC1_NO_RESPONSE); /* Check host error flags */ + if (Error == LDD_SDHC_ERR_OK) { + if (SDHC1_SCR_GET_SD_SPEC((uint32_t)DeviceDataPrv->Cards[Id].Block) != SDHC1_SCR_SD_SPEC_VERS_1_0X) { + /* Check high speed support */ + DeviceDataPrv->Substate = SDHC1_CIR_GET_FUNC_STATUS; + DeviceDataPrv->CmdState = SDHC1_CMD_START; + } else { + DeviceDataPrv->Substate = SDHC1_CIR_FINISH; + } + CardInfoRetrieval(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the card info retrieval state */ + } else { + DeviceDataPrv->LastError = Error; + DeviceDataPrv->LastErrorAddress = SDHC_PDD_GetDMAAddress(SDHC_BASE_PTR); + Finished = TRUE; + } + break; + default: + break; + } + break; + case SDHC1_CIR_GET_FUNC_STATUS: + switch (DeviceDataPrv->CmdState) { + case SDHC1_CMD_START: + DeviceDataPrv->CmdState = SDHC1_CMD_FINISH; + /* Set data transfer size */ + SDHC_PDD_SetBlockSize(SDHC_BASE_PTR, SDHC1_SFS_SIZE); + SDHC_PDD_SetBlockCount(SDHC_BASE_PTR, 1U); + /* Set DMA transfer properties */ + DeviceDataPrv->TransferTable[0].Attributes = SDHC1_SINGLE_BLOCK_TRANS_ATTRS; + DeviceDataPrv->TransferTable[0].Length = SDHC1_SFS_SIZE; + DeviceDataPrv->TransferTable[0].Address = (uint32_t)&DeviceDataPrv->Cards[Id].Block[SDHC1_SFS_BLOCK_START]; + SDHC_PDD_SetADMAAddress(SDHC_BASE_PTR, DeviceDataPrv->TransferTable); + /* Send function check command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, + SDHC1_SD_CMD6_ARG_MODE(SDHC1_SD_CMD6_CHECK_FUNC) | + SDHC1_SD_CMD6_ARG_GROUP_1(SDHC1_SD_CMD6_GROUP_1_HIGH_SPEED)); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, SDHC_PDD_CMD6_SWITCH, + SDHC_PDD_ENABLE_DMA | SDHC_PDD_DATA_PRESENT | SDHC_PDD_DATA_READ | SDHC_PDD_RESPONSE_LENGTH_48); + break; + case SDHC1_CMD_FINISH: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if (Error == LDD_SDHC_ERR_OK) { + DeviceDataPrv->CmdState = SDHC1_CMD_DATA; + //CardInfoRetrieval(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the card info retrieval state */ + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + case SDHC1_CMD_DATA: + Error = GetCommandError(DeviceDataPrv, Flags, SDHC1_NO_RESPONSE); /* Check host error flags */ + if (Error == LDD_SDHC_ERR_OK) { + DeviceDataPrv->Substate = SDHC1_CIR_FINISH; + CardInfoRetrieval(DeviceDataPrv, 0U, SDHC1_NO_RESPONSE); /* Handle the card info retrieval state */ + } else { + DeviceDataPrv->LastError = Error; + DeviceDataPrv->LastErrorAddress = SDHC_PDD_GetDMAAddress(SDHC_BASE_PTR); + Finished = TRUE; + } + break; + default: + break; + } + break; + case SDHC1_CIR_FINISH: + Response = DeviceDataPrv->Cards[Id].CSD; /* Get a pointer to card specific data */ + InfoPtr = DeviceDataPrv->CardInfoPtr; /* Get a pointer to the user card info variable */ + InfoPtr->Type = DeviceDataPrv->CardType; /* Get card type from selected card type */ + /* Extract card information from card registers */ + InfoPtr->BlockLength = (uint16_t)((uint16_t)1U << SDHC1_R2_GET_READ_BL_LEN(Response)); /* Block length = 2^READ_BL_LEN */ + if ((DeviceDataPrv->CardType != LDD_SDHC_SD) || (SDHC1_R2_GET_CSD_STRUCTURE(Response) == SDHC1_SD_CSD_VERS_1_0)) { + /* CSD (card specific data) version 1.0 */ + /* Block count = (C_SIZE + 1) * (2^(C_SIZE_MULT + 2)) */ + InfoPtr->BlockCount = (uint16_t)(SDHC1_R2_CSD_V1_GET_C_SIZE(Response) + 1U) * + (uint16_t)((uint16_t)1U << (SDHC1_R2_CSD_V1_GET_C_SIZE_MULT(Response) + 2U)); + } else { + /* CSD (card specific data) version 2.0 */ + /* Block count = (C_SIZE + 1) * 1k */ + InfoPtr->BlockCount = (SDHC1_R2_CSD_V2_GET_C_SIZE(Response) + 1U) * 1024U; + } + InfoPtr->Caps.Operations = (uint8_t)(SDHC1_R2_GET_CCC(Response) >> 2); /* Shift card command classes to fit into a byte (omitting mandatory classes) */ + InfoPtr->Caps.HighCapacity = DeviceDataPrv->Cards[Id].HighCapacity; /* Get high capacity flag acquired during voltage validation */ + InfoPtr->Caps.LowVoltage = (DeviceDataPrv->CardsVoltages & SDHC1_OCR_LOW_VOLTAGE_MASK) ? TRUE : FALSE; /* Get low voltage support flag acquired during voltage validation */ + InfoPtr->Caps.Read.MaxBlockLength = (uint16_t)((uint16_t)1U << SDHC1_R2_GET_READ_BL_LEN(Response)); /* Max. read block length = 2^READ_BL_LEN */ + InfoPtr->Caps.Read.MisalignBlock = (SDHC1_R2_GET_READ_BLK_MISALIGN(Response)) ? TRUE : FALSE; + InfoPtr->Caps.Read.PartialBlock = (SDHC1_R2_GET_READ_BL_PARTIAL(Response)) ? TRUE : FALSE; + InfoPtr->Caps.Write.MaxBlockLength = (uint16_t)((uint16_t)1U << SDHC1_R2_GET_WRITE_BL_LEN(Response)); /* Max. write block length = 2^WRITE_BL_LEN */ + InfoPtr->Caps.Write.MisalignBlock = (SDHC1_R2_GET_WRITE_BLK_MISALIGN(Response)) ? TRUE : FALSE; + InfoPtr->Caps.Write.PartialBlock = (SDHC1_R2_GET_WRITE_BL_PARTIAL(Response)) ? TRUE : FALSE; + InfoPtr->Caps.WriteProtect.Permanent = (SDHC1_R2_GET_PERM_WRITE_PROTECT(Response)) ? TRUE : FALSE; + if (DeviceDataPrv->CardType == LDD_SDHC_MMC) { + InfoPtr->Caps.DataWidths = DeviceDataPrv->Cards[Id].DataWidths; /* Get data widths acquired during bus testing procedure */ + InfoPtr->Caps.HighSpeed = (SDHC1_R2_MMC_GET_SPEC_VERS(Response) == SDHC1_MMC_CSD_SPEC_VERS_4_X) ? TRUE : FALSE; /* High speed supported by MMC cards from version 4.0 */ + /* Erase sector size = (ERASE_GRP_SIZE + 1) * (ERASE_GRP_MULT + 1) */ + InfoPtr->Caps.Erase.SectorSize = (uint16_t)((SDHC1_R2_MMC_GET_ERASE_GRP_SIZE(Response) + 1U) * + (SDHC1_R2_MMC_GET_ERASE_GRP_MULT(Response) + 1U)); + /* Get erased memory byte content from the extended CSD (card specific data) register */ + InfoPtr->Caps.Erase.Pattern = DeviceDataPrv->Cards[Id].Block[SDHC1_EXT_CSD_ERASED_MEM_CONT_INDEX]; + /* Write protection group size = WP_GRP_SIZE + 1 */ + InfoPtr->Caps.WriteProtect.GroupSize = (uint16_t)((SDHC1_R2_GET_WP_GRP_ENABLE(Response)) ? + (SDHC1_R2_MMC_GET_WP_GRP_SIZE(Response) + 1U) : 0U); + } else { + BusWidths = (uint8_t)SDHC1_SCR_GET_SD_BUS_WIDTHS((uint32_t)DeviceDataPrv->Cards[Id].Block); + InfoPtr->Caps.DataWidths = (uint8_t) /* Map SCR (SD card configuration register) values to component constants */ + (((BusWidths & SDHC1_SCR_SD_BUS_WIDTH_1_BIT_MASK) ? LDD_SDHC_CARD_DATA_WIDTH_1_BIT : 0U) | + ((BusWidths & SDHC1_SCR_SD_BUS_WIDTH_4_BIT_MASK) ? LDD_SDHC_CARD_DATA_WIDTH_4_BIT : 0U)); + if (SDHC1_SCR_GET_SD_SPEC((uint32_t)DeviceDataPrv->Cards[Id].Block) == SDHC1_SCR_SD_SPEC_VERS_1_0X) { + /* High speed is not supported in this version of SD card specification */ + InfoPtr->Caps.HighSpeed = FALSE; + } else { + /* Get high speed support flag acquired during high speed function check */ + InfoPtr->Caps.HighSpeed = (SDHC1_SFS_IS_FUNC_SUPPORTED( + (uint32_t)&DeviceDataPrv->Cards[Id].Block[SDHC1_SFS_BLOCK_START], + SDHC1_SFS_HIGH_SPEED_FUNC_GROUP, SDHC1_SFS_HIGH_SPEED_FUNC_INDEX)) ? TRUE : FALSE; + } + InfoPtr->Caps.Erase.SectorSize = (uint16_t)(SDHC1_R2_SD_GET_SECTOR_SIZE(Response) + 1U); + InfoPtr->Caps.Erase.Pattern = (uint8_t) /* Erase memory byte content is defined by a data status flag */ + ((SDHC1_SCR_GET_DATA_STAT_AFTER_ERASE((uint32_t)DeviceDataPrv->Cards[Id].Block)) ? 0xFFU : 0x00U); + if (SDHC1_R2_GET_CSD_STRUCTURE(Response) == SDHC1_SD_CSD_VERS_2_0) { + /* CSD (card specific data) structure version 2.0 */ + InfoPtr->Caps.WriteProtect.GroupSize = (uint16_t)0U; + } else { + /* CSD (card specific data) structure version 1.0 */ + InfoPtr->Caps.WriteProtect.GroupSize = (uint16_t)((SDHC1_R2_GET_WP_GRP_ENABLE(Response)) ? + (SDHC1_R2_SD_GET_WP_GRP_SIZE(Response) + 1U) : 0U); + } + } + Finished = TRUE; + break; + default: + break; + } + if (Finished) { + DeviceDataPrv->State = LDD_SDHC_IDLE; + if (DeviceDataPrv->EventMask & LDD_SDHC_ON_FINISHED) { + SDHC1_OnFinished(DeviceDataPrv->UserDataPtr); /* Call the user event */ + } + } +} + +/* +** =================================================================== +** Method : CardSelection (component SDHC_LDD) +** +** Description : +** Card selection state handler. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static bool CardSelection(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + bool Finished = FALSE; /* Indicates card selection end */ + LDD_SDHC_TError Error = LDD_SDHC_ERR_OK; /* Error code storage */ + uint8_t Id = DeviceDataPrv->CardId; /* Card ID storage */ + + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if ((Error == LDD_SDHC_ERR_OK) && Response) { + if (SDHC1_R1_IS_READY_FOR_DATA(Response)) { + /* By card selection card has changed its state to transfer */ + DeviceDataPrv->CardState = SDHC1_TRANSFER; + Finished = TRUE; + } else { + /* Send status request command again */ + SendCardStatusRequest(DeviceDataPrv); + } + } else { + if (Id != SDHC1_NO_CARD) { + DeviceDataPrv->LastError = Error; + DeviceDataPrv->Cards[Id].Initialized = FALSE; + DeviceDataPrv->CardId = SDHC1_NO_CARD; /* Card has been removed */ + if (DeviceDataPrv->EventMask & LDD_SDHC_ON_CARD_REMOVED) { + SDHC1_OnCardRemoved(DeviceDataPrv->UserDataPtr, Id); /* Call the user event */ + } + } else { + if (Error != LDD_SDHC_ERR_TIMEOUT) { + DeviceDataPrv->LastError = Error; + } + } + Finished = TRUE; + } + return Finished; +} + +/* +** =================================================================== +** Method : Transfer (component SDHC_LDD) +** +** Description : +** Transfer state handler. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static bool Transfer(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + bool Finished = FALSE; /* Indicates transfer end */ + LDD_SDHC_TError Error = LDD_SDHC_ERR_OK; /* Error code storage */ + + switch (DeviceDataPrv->CmdState) { + case SDHC1_CMD_DATA_LEN: + DeviceDataPrv->CmdState = SDHC1_CMD_START; + /* Send block length */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, DeviceDataPrv->TransferBlockSize); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD16_SET_BLOCKLEN, SDHC_PDD_RESPONSE_LENGTH_48); + break; + case SDHC1_CMD_START: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if (Error == LDD_SDHC_ERR_OK) { + if (DeviceDataPrv->Cancel) { + Finished = TRUE; + } else { + DeviceDataPrv->CmdState = SDHC1_CMD_FINISH; + SDHC_PDD_SetADMAAddress(SDHC_BASE_PTR, DeviceDataPrv->TransferTable); + /* Set block attributes */ + SDHC_PDD_SetBlockSize(SDHC_BASE_PTR, DeviceDataPrv->TransferBlockSize); + SDHC_PDD_SetBlockCount(SDHC_BASE_PTR, DeviceDataPrv->TransferBlockCount); + /* Send transfer command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, DeviceDataPrv->Address); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + ((DeviceDataPrv->TransferOperation == LDD_SDHC_READ) ? + (uint32_t)((DeviceDataPrv->TransferBlockCount > 1U) ? + SDHC_PDD_CMD18_READ_MULTIPLE_BLOCK : SDHC_PDD_CMD17_READ_SINGLE_BLOCK) : + (uint32_t)((DeviceDataPrv->TransferBlockCount > 1U) ? + SDHC_PDD_CMD25_WRITE_MULTIPLE_BLOCK : SDHC_PDD_CMD24_WRITE_BLOCK)), + ((DeviceDataPrv->TransferBlockCount > 1U) ? + (SDHC_PDD_ENABLE_BLOCK_COUNT | SDHC_PDD_ENABLE_AUTO_CMD12 | SDHC_PDD_MULTIPLE_BLOCK) : 0U) | + SDHC_PDD_ENABLE_DMA | SDHC_PDD_DATA_PRESENT | SDHC_PDD_RESPONSE_LENGTH_48 | + ((DeviceDataPrv->TransferOperation == LDD_SDHC_READ) ? + SDHC_PDD_DATA_READ : SDHC_PDD_DATA_WRITE)); + } + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + case SDHC1_CMD_FINISH: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if (Error == LDD_SDHC_ERR_OK) { + DeviceDataPrv->CmdState = SDHC1_CMD_DATA; + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + case SDHC1_CMD_DATA: + Error = GetCommandError(DeviceDataPrv, Flags, SDHC1_NO_RESPONSE); /* Check host error flags */ + if (Error == LDD_SDHC_ERR_OK) { + DeviceDataPrv->CmdState = SDHC1_CMD_ERROR; + SendCardStatusRequest(DeviceDataPrv); + } else { + DeviceDataPrv->LastError = Error; + DeviceDataPrv->LastErrorAddress = SDHC_PDD_GetDMAAddress(SDHC_BASE_PTR); + Finished = TRUE; + } + break; + case SDHC1_CMD_ERROR: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if ((Error == LDD_SDHC_ERR_OK) && Response) { + if (SDHC1_R1_IS_READY_FOR_DATA(Response)) { + Finished = TRUE; + } else { + /* Send status request command again */ + SendCardStatusRequest(DeviceDataPrv); + } + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + default: + break; + } + return Finished; +} + +/* +** =================================================================== +** Method : Erasion (component SDHC_LDD) +** +** Description : +** Erasion state handler. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static bool Erasion(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + bool Finished = FALSE; /* Indicates erasion end */ + LDD_SDHC_TError Error = LDD_SDHC_ERR_OK; /* Error code storage */ + + switch (DeviceDataPrv->Substate) { + case SDHC1_E_SET_START: + DeviceDataPrv->Substate = SDHC1_E_SET_END; + /* Send tag erase start command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, DeviceDataPrv->ErasionStart); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + ((DeviceDataPrv->CardType == LDD_SDHC_MMC) ? /* Handle different command indices for different card types */ + SDHC_PDD_CMD35_TAG_ERASE_GROUP_START : SDHC_PDD_CMD32_TAG_SECTOR_START), + SDHC_PDD_RESPONSE_LENGTH_48); + break; + case SDHC1_E_SET_END: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if (Error == LDD_SDHC_ERR_OK) { + DeviceDataPrv->Substate = SDHC1_E_EXECUTE; + /* Send tag erase end command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, DeviceDataPrv->ErasionEnd); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + ((DeviceDataPrv->CardType == LDD_SDHC_MMC) ? /* Handle different command indices for different card types */ + SDHC_PDD_CMD36_TAG_ERASE_GROUP_END : SDHC_PDD_CMD33_TAG_SECTOR_END), + SDHC_PDD_RESPONSE_LENGTH_48); + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + case SDHC1_E_EXECUTE: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if (Error == LDD_SDHC_ERR_OK) { + DeviceDataPrv->Substate = SDHC1_E_FINISH; + /* Send erase command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, 0U); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD38_ERASE, SDHC_PDD_RESPONSE_LENGTH_48_BUSY_CHECK); + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + case SDHC1_E_FINISH: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if ((Error == LDD_SDHC_ERR_OK) && Response) { + /* Check whether erasion has finished */ + if (SDHC1_R1_IS_READY_FOR_DATA(Response)) { + Finished = TRUE; + } else { + /* Send status request command again */ + SendCardStatusRequest(DeviceDataPrv); + } + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + default: + break; + } + return Finished; +} + +/* +** =================================================================== +** Method : DataWidthSelection (component SDHC_LDD) +** +** Description : +** Data width selection state handler. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static bool DataWidthSelection(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + bool Finished = FALSE; /* Indicates data width selection end */ + LDD_SDHC_TError Error = LDD_SDHC_ERR_OK; /* Error code storage */ + uint8_t Id = DeviceDataPrv->CardId; /* Card ID storage */ + uint8_t Argument = 0U; /* Command argument */ + + if (DeviceDataPrv->CardType == LDD_SDHC_MMC) { + switch (DeviceDataPrv->CmdState) { + case SDHC1_CMD_START: + DeviceDataPrv->CmdState = SDHC1_CMD_FINISH; + /* Map data width to an extended CSD (card specific data) register field value */ + switch (DeviceDataPrv->DataWidth) { + case LDD_SDHC_CARD_DATA_WIDTH_1_BIT: + Argument = 0U; + break; + case LDD_SDHC_CARD_DATA_WIDTH_4_BIT: + Argument = 1U; + break; + case LDD_SDHC_CARD_DATA_WIDTH_8_BIT: + Argument = 2U; + break; + default: + break; + } + /* Send switch command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, + SDHC1_MMC_CMD6_ARG_ACCESS(SDHC1_MMC_CMD6_WRITE_BYTES) | + SDHC1_MMC_CMD6_ARG_INDEX(SDHC1_EXT_CSD_BUS_WIDTH_INDEX) | + SDHC1_MMC_CMD6_ARG_VALUE(Argument)); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD6_SWITCH, SDHC_PDD_RESPONSE_LENGTH_48); + break; + case SDHC1_CMD_FINISH: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if ((Error == LDD_SDHC_ERR_OK) && Response) { + if (SDHC1_R1_IS_READY_FOR_DATA(Response)) { + /* Map data widths to host register field values */ + switch (DeviceDataPrv->DataWidth) { + case LDD_SDHC_CARD_DATA_WIDTH_1_BIT: + SDHC_PDD_SetDataTransferWidth(SDHC_BASE_PTR, SDHC_PDD_1_BIT_MODE); + break; + case LDD_SDHC_CARD_DATA_WIDTH_4_BIT: + SDHC_PDD_SetDataTransferWidth(SDHC_BASE_PTR, SDHC_PDD_4_BIT_MODE); + break; + case LDD_SDHC_CARD_DATA_WIDTH_8_BIT: + SDHC_PDD_SetDataTransferWidth(SDHC_BASE_PTR, SDHC_PDD_8_BIT_MODE); + break; + default: + break; + } + Finished = TRUE; + } else { + /* Send status request command again */ + SendCardStatusRequest(DeviceDataPrv); + } + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + default: + break; + } + } else { + switch (DeviceDataPrv->CmdState) { + case SDHC1_CMD_START: + DeviceDataPrv->CmdState = SDHC1_CMD_ACMD; + /* Start application specific command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, + SDHC1_CMD_ARG_RCA(DeviceDataPrv->Cards[Id].RCA)); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD55_APP_CMD, SDHC_PDD_RESPONSE_LENGTH_48); + break; + case SDHC1_CMD_ACMD: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if (Error == LDD_SDHC_ERR_OK) { + DeviceDataPrv->CmdState = SDHC1_CMD_FINISH; + /* Map data widths to card register field values */ + switch (DeviceDataPrv->DataWidth) { + case LDD_SDHC_CARD_DATA_WIDTH_1_BIT: + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, 0U); + break; + case LDD_SDHC_CARD_DATA_WIDTH_4_BIT: + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, 2U); + break; + default: + break; + } + /* Send bus width set command */ + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_ACMD6_SET_BUS_WIDTH, SDHC_PDD_RESPONSE_LENGTH_48); + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + case SDHC1_CMD_FINISH: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if (Error == LDD_SDHC_ERR_OK) { + /* Map data widths to host register field values */ + switch (DeviceDataPrv->DataWidth) { + case LDD_SDHC_CARD_DATA_WIDTH_1_BIT: + SDHC_PDD_SetDataTransferWidth(SDHC_BASE_PTR, SDHC_PDD_1_BIT_MODE); + break; + case LDD_SDHC_CARD_DATA_WIDTH_4_BIT: + SDHC_PDD_SetDataTransferWidth(SDHC_BASE_PTR, SDHC_PDD_4_BIT_MODE); + break; + default: + break; + } + } else { + DeviceDataPrv->LastError = Error; + } + Finished = TRUE; + break; + default: + break; + } + } + return Finished; +} + +/* +** =================================================================== +** Method : BusClockSelection (component SDHC_LDD) +** +** Description : +** Bus clock selection state handler. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static bool BusClockSelection(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + bool Finished = FALSE; /* Indicates bus clock selection end */ + LDD_SDHC_TError Error = LDD_SDHC_ERR_OK; /* Error code storage */ + uint8_t Id = DeviceDataPrv->CardId; /* Card ID storage */ + + switch (DeviceDataPrv->CmdState) { + case SDHC1_CMD_START: + DeviceDataPrv->CmdState = SDHC1_CMD_FINISH; + if (DeviceDataPrv->Cards[Id].Type == LDD_SDHC_MMC) { + /* Send switch command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, + SDHC1_MMC_CMD6_ARG_ACCESS(SDHC1_MMC_CMD6_WRITE_BYTES) | + SDHC1_MMC_CMD6_ARG_INDEX(SDHC1_EXT_CSD_HS_TIMING_INDEX) | + SDHC1_MMC_CMD6_ARG_VALUE(1)); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD6_SWITCH, SDHC_PDD_RESPONSE_LENGTH_48); + } else { + /* Send function switch command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, + SDHC1_SD_CMD6_ARG_MODE(SDHC1_SD_CMD6_SWITCH_FUNC) | + SDHC1_SD_CMD6_ARG_GROUP_1(SDHC1_SD_CMD6_GROUP_1_HIGH_SPEED)); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD6_SWITCH, SDHC_PDD_RESPONSE_LENGTH_48_BUSY_CHECK); + } + break; + case SDHC1_CMD_FINISH: + Finished = TRUE; + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if ((Error == LDD_SDHC_ERR_OK) && Response) { + if (DeviceDataPrv->CardType == LDD_SDHC_MMC) { + if (!SDHC1_R1_IS_READY_FOR_DATA(Response)) { + /* Send status request command again */ + SendCardStatusRequest(DeviceDataPrv); + Finished = FALSE; + } + } + } + if (Finished) { + SetBusClockPrescalers(DeviceDataPrv, DeviceDataPrv->Frequency); + } + break; + default: + break; + } + return Finished; +} + +/* +** =================================================================== +** Method : WriteProtectionSetup (component SDHC_LDD) +** +** Description : +** Write protection setup state handler. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static bool WriteProtectionSetup(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + bool Finished = FALSE; /* Indicates write protection setup end */ + LDD_SDHC_TError Error = LDD_SDHC_ERR_OK; /* Error code storage */ + uint8_t Id = DeviceDataPrv->CardId; /* Card ID storage */ + uint32_t Index; /* Array index */ + + if (DeviceDataPrv->WriteProtType == LDD_SDHC_GROUP) { + switch (DeviceDataPrv->CmdState) { + case SDHC1_CMD_START: + DeviceDataPrv->CmdState = SDHC1_CMD_FINISH; + /* Send write protection set/clear command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, DeviceDataPrv->Address); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + (DeviceDataPrv->WriteProtFlag ? /* Choose write protection set or clear command */ + SDHC_PDD_CMD28_SET_WRITE_PROT : SDHC_PDD_CMD29_CLR_WRITE_PROT), + SDHC_PDD_RESPONSE_LENGTH_48_BUSY_CHECK); + break; + case SDHC1_CMD_FINISH: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if ((Error == LDD_SDHC_ERR_OK) && Response) { + if (SDHC1_R1_IS_READY_FOR_DATA(Response)) { + Finished = TRUE; + } else { + /* Send status request command again */ + SendCardStatusRequest(DeviceDataPrv); + } + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + default: + break; + } + } else { + switch (DeviceDataPrv->CmdState) { + case SDHC1_CMD_START: + DeviceDataPrv->CmdState = SDHC1_CMD_FINISH; + /* Order CSD (card specific data) register bytes from MSB to LSB */ + for (Index = 0U; Index < (SDHC1_CSD_SIZE - 1U); Index++) { + DeviceDataPrv->CSDPtr[(SDHC1_CSD_SIZE - 1U) - (Index + 1U)] = + (uint8_t)((uint32_t)DeviceDataPrv->Cards[Id].CSD[Index / 4U] >> (8 * ((int32_t)Index % 4))) & 0xFFU; + } + /* Set block attributes */ + SDHC_PDD_SetBlockSize(SDHC_BASE_PTR, SDHC1_CSD_SIZE); + SDHC_PDD_SetBlockCount(SDHC_BASE_PTR, 1U); + /* Set DMA transfer properties */ + DeviceDataPrv->TransferTable[0].Attributes = SDHC1_SINGLE_BLOCK_TRANS_ATTRS; + DeviceDataPrv->TransferTable[0].Length = SDHC1_CSD_SIZE; + DeviceDataPrv->TransferTable[0].Address = (uint32_t)DeviceDataPrv->CSDPtr; + SDHC_PDD_SetADMAAddress(SDHC_BASE_PTR, DeviceDataPrv->TransferTable); + /* Program CSD (card specific data) register */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, 0U); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, SDHC_PDD_CMD27_PROGRAM_CSD, + SDHC_PDD_ENABLE_DMA | SDHC_PDD_DATA_PRESENT | SDHC_PDD_DATA_WRITE | SDHC_PDD_RESPONSE_LENGTH_48); + break; + case SDHC1_CMD_FINISH: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if (Error == LDD_SDHC_ERR_OK) { + DeviceDataPrv->CmdState = SDHC1_CMD_DATA; + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + case SDHC1_CMD_DATA: + Error = GetCommandError(DeviceDataPrv, Flags, SDHC1_NO_RESPONSE); /* Check host error flags */ + if (Error != LDD_SDHC_ERR_OK) { + DeviceDataPrv->LastError = Error; + DeviceDataPrv->LastErrorAddress = SDHC_PDD_GetDMAAddress(SDHC_BASE_PTR); + } + Finished = TRUE; + break; + default: + break; + } + } + return Finished; +} + +/* +** =================================================================== +** Method : WriteProtectionRetrieval (component SDHC_LDD) +** +** Description : +** Write protection retrieval state handler. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static bool WriteProtectionRetrieval(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + bool Finished = FALSE; /* Indicates write protection retrieval end */ + LDD_SDHC_TError Error = LDD_SDHC_ERR_OK; /* Error code storage */ + + switch (DeviceDataPrv->CmdState) { + case SDHC1_CMD_START: + DeviceDataPrv->CmdState = SDHC1_CMD_FINISH; + /* Set block attributes */ + SDHC_PDD_SetBlockSize(SDHC_BASE_PTR, SDHC1_WRITE_PROTECT_MASK_SIZE); + SDHC_PDD_SetBlockCount(SDHC_BASE_PTR, 1U); + /* Set DMA transfer properties */ + DeviceDataPrv->TransferTable[0].Attributes = SDHC1_SINGLE_BLOCK_TRANS_ATTRS; + DeviceDataPrv->TransferTable[0].Length = SDHC1_WRITE_PROTECT_MASK_SIZE; + DeviceDataPrv->TransferTable[0].Address = (uint32_t)DeviceDataPrv->WriteProtMaskPtr; + SDHC_PDD_SetADMAAddress(SDHC_BASE_PTR, DeviceDataPrv->TransferTable); + /* Send write protection mask request command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, DeviceDataPrv->Address); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, SDHC_PDD_CMD30_SEND_WRITE_PROT, + SDHC_PDD_ENABLE_DMA | SDHC_PDD_DATA_PRESENT | SDHC_PDD_DATA_READ | SDHC_PDD_RESPONSE_LENGTH_48); + break; + case SDHC1_CMD_FINISH: + Error = GetCommandError(DeviceDataPrv, Flags, Response); /* Check host and card error flags */ + if (Error == LDD_SDHC_ERR_OK) { + DeviceDataPrv->CmdState = SDHC1_CMD_DATA; + } else { + DeviceDataPrv->LastError = Error; + Finished = TRUE; + } + break; + case SDHC1_CMD_DATA: + Error = GetCommandError(DeviceDataPrv, Flags, SDHC1_NO_RESPONSE); /* Check host error flags */ + if (Error != LDD_SDHC_ERR_OK) { + DeviceDataPrv->LastError = Error; + DeviceDataPrv->LastErrorAddress = SDHC_PDD_GetDMAAddress(SDHC_BASE_PTR); + } + Finished = TRUE; + break; + default: + break; + } + return Finished; +} + +/* +** =================================================================== +** Method : SetBusClockPrescalers (component SDHC_LDD) +** +** Description : +** Bus clock prescalers setup. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void SetBusClockPrescalers(LDD_SDHC1_TDeviceData *DeviceDataPtr, SDHC1_TBusClock Frequency) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + static const uint8_t PrescalerValues[][1][2] = { /* Frequency select and divisor values for bus clock frequencies selected by property */ + {{ 64u, 0u }}, + {{ 2u, 0u }}, + {{ 1u, 0u }} + }; + + SDHC_PDD_EnableSDHCClock(SDHC_BASE_PTR, FALSE); + SDHC_PDD_SetSDHCClockFrequency(SDHC_BASE_PTR, + PrescalerValues[Frequency][DeviceDataPrv->SpeedMode][0]); + SDHC_PDD_SetSDHCClockDivisor(SDHC_BASE_PTR, + PrescalerValues[Frequency][DeviceDataPrv->SpeedMode][1]); + while (!SDHC_PDD_IsSDClockStable(SDHC_BASE_PTR)) {} /* Wait for clock to stabilize */ + SDHC_PDD_EnableSDHCClock(SDHC_BASE_PTR, TRUE); +} + +/* +** =================================================================== +** Method : GetCommandError (component SDHC_LDD) +** +** Description : +** Extracts error code from the device error flags and the card +** status response. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static LDD_SDHC_TError GetCommandError(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Flags, uint32_t *Response) +{ + LDD_SDHC_TError Error = LDD_SDHC_ERR_OK; /* Error code storage */ + uint32_t AutoCMD12ErrorFlags = SDHC_PDD_GetAutoCMD12ErrorFlags(SDHC_BASE_PTR); /* Auto CMD12 error flags */ + + (void)DeviceDataPtr; /* Suppress unused parameter warning */ + /* Map host error flags to component error codes */ + if ((Flags & (SDHC_PDD_COMMAND_TIMEOUT_ERROR_INT | SDHC_PDD_DATA_TIMEOUT_ERROR_INT)) || + ((Flags & SDHC_PDD_AUTO_CMD12_ERROR_INT) && (AutoCMD12ErrorFlags & SDHC_PDD_AUTO_CMD12_TIMEOUT_ERROR))) { + Error = LDD_SDHC_ERR_TIMEOUT; + } else if ((Flags & (SDHC_PDD_COMMAND_CRC_ERROR_INT | SDHC_PDD_COMMAND_END_BIT_ERROR_INT | + SDHC_PDD_COMMAND_INDEX_ERROR_INT)) || ((Flags & SDHC_PDD_AUTO_CMD12_ERROR_INT) && + (AutoCMD12ErrorFlags & (SDHC_PDD_AUTO_CMD12_CRC_ERROR | SDHC_PDD_AUTO_CMD12_END_BIT_ERROR | SDHC_PDD_AUTO_CMD12_INDEX_ERROR)))) { + Error = LDD_SDHC_ERR_COMMAND_CRC; + } else if (Flags & (SDHC_PDD_DATA_CRC_ERROR_INT | SDHC_PDD_DATA_END_BIT_ERROR_INT)) { + Error = LDD_SDHC_ERR_DATA_CRC; + } else if (Flags & SDHC_PDD_DMA_ERROR_INT) { + Error = LDD_SDHC_ERR_DMA; + } else { + Error = LDD_SDHC_ERR_OK; + } + if ((Error == LDD_SDHC_ERR_OK) && Response) { + /* Map card error flags to component error codes */ + if (SDHC1_R1_IS_ERASE_RESET(Response) || + SDHC1_R1_IS_CSD_OVERWRITE(Response) || + SDHC1_R1_IS_ERASE_SEQ_ERROR(Response) || + SDHC1_R1_IS_ILLEGAL_COMMAND(Response)) { + Error = LDD_SDHC_ERR_INTERNAL_FAILURE; + } else if (SDHC1_R1_IS_WP_ERASE_SKIP(Response)) { + Error = LDD_SDHC_ERR_WP_ERASE_SKIP; + } else if (SDHC1_R1_MMC_IS_OVERRUN(Response) || + SDHC1_R1_MMC_IS_UNDERRUN(Response) || + SDHC1_R1_IS_ERROR(Response) || + SDHC1_R1_IS_CC_ERROR(Response) || + SDHC1_R1_IS_CARD_ECC_FAILED(Response)) { + Error = LDD_SDHC_ERR_CARD_FAILURE; + } else if (SDHC1_R1_IS_COM_CRC_ERROR(Response)) { + Error = LDD_SDHC_ERR_COMMAND_CRC; + } else if (SDHC1_R1_IS_CARD_IS_LOCKED(Response)) { + Error = LDD_SDHC_ERR_CARD_IS_LOCKED; + } else if (SDHC1_R1_IS_WP_VIOLATION(Response)) { + Error = LDD_SDHC_ERR_WP_VIOLATION; + } else if (SDHC1_R1_IS_ERASE_PARAM(Response) || + SDHC1_R1_IS_ADDRESS_MISALIGN(Response)) { + Error = LDD_SDHC_ERR_ADDRESS_MISALIGN; + } else if (SDHC1_R1_IS_BLOCK_LEN_ERROR(Response)) { + Error = LDD_SDHC_ERR_BLOCK_LEN_ERROR; + } else if (SDHC1_R1_IS_ADDRESS_OUT_OF_RANGE(Response)) { + Error = LDD_SDHC_ERR_ADDRESS_OUT_OF_RANGE; + } else { + Error = LDD_SDHC_ERR_OK; + } + } + return Error; +} + +/* +** =================================================================== +** Method : SendCardStatusRequest (component SDHC_LDD) +** +** Description : +** Sends a card status request. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void SendCardStatusRequest(LDD_SDHC1_TDeviceData *DeviceDataPtr) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + uint8_t Id = DeviceDataPrv->CardId; /* Card ID storage */ + + /* Send status request command */ + SDHC_PDD_SetCommandArgument(SDHC_BASE_PTR, + SDHC1_CMD_ARG_RCA(DeviceDataPrv->Cards[Id].RCA)); + SDHC_PDD_SendCommand(SDHC_BASE_PTR, + SDHC_PDD_CMD13_SEND_STATUS, SDHC_PDD_RESPONSE_LENGTH_48); +} + +/* +** =================================================================== +** Method : SDHC1_Interrupt (component SDHC_LDD) +** +** Description : +** The method services the interrupt of the selected peripheral(s) +** and eventually invokes event(s) of the component. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +//PE_ISR(SDHC1_Interrupt) +void SDHC1_Interrupt( void ) +{ + /* {FreeRTOS RTOS Adapter} ISR parameter is passed through the global variable */ + LDD_SDHC1_TDeviceData* DeviceDataPrv = INT_SDHC__BAREBOARD_RTOS_ISRPARAM; + + EventHandler(DeviceDataPrv); +} + +/* +** =================================================================== +** Method : EventHandler (component SDHC_LDD) +** +** Description : +** Hardware event handler. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void EventHandler(LDD_SDHC1_TDeviceData *DeviceDataPtr) +{ + LDD_SDHC1_TDeviceData *DeviceDataPrv = (LDD_SDHC1_TDeviceData*)DeviceDataPtr; + uint32_t IntFlags = SDHC_PDD_GetInterruptFlags(SDHC_BASE_PTR); /* Store interrupt flags */ + const uint32_t CompletionFlags = SDHC_PDD_COMMAND_COMPLETE_INT | + SDHC_PDD_TRANSFER_COMPLETE_INT | SDHC_PDD_BUFFER_READ_READY_INT | + SDHC_PDD_BUFFER_WRITE_READY_INT; + const uint32_t CommandErrorFlags = SDHC_PDD_COMMAND_TIMEOUT_ERROR_INT | /* Command error interrupt flags mask */ + SDHC_PDD_COMMAND_CRC_ERROR_INT | SDHC_PDD_COMMAND_INDEX_ERROR_INT | + //MATTHEW + 0; + //SDHC_PDD_AUTO_CMD12_ERROR_INT; + const uint32_t DataErrorFlags = SDHC_PDD_DATA_TIMEOUT_ERROR_INT | /* Data transfer error interrupt flags mask */ + SDHC_PDD_DATA_CRC_ERROR_INT | SDHC_PDD_DATA_END_BIT_ERROR_INT | + SDHC_PDD_DMA_ERROR_INT; + const uint32_t ErrorFlags = CommandErrorFlags | DataErrorFlags; /* Error interrupt flags mask */ + bool Finished = FALSE; /* Indicates operation end */ + uint32_t Buffer[4]; /* Response buffer */ + uint32_t *Response = SDHC1_NO_RESPONSE; /* Response buffer pointer */ + + if (IntFlags & (CompletionFlags | ErrorFlags)) { + if (IntFlags & SDHC_PDD_COMMAND_COMPLETE_INT) { + SDHC_PDD_ClearInterruptFlags(SDHC_BASE_PTR, SDHC_PDD_COMMAND_COMPLETE_INT); + /* Check command completion errors */ + if (IntFlags & CommandErrorFlags) { + SDHC_PDD_ClearInterruptFlags(SDHC_BASE_PTR, CommandErrorFlags); + Response = SDHC1_NO_RESPONSE; /* No valid response has been received */ + } else { + SDHC_PDD_GetCommandResponse(SDHC_BASE_PTR, Buffer); + Response = Buffer; /* Assign the response pointer */ + } + } else { + if (IntFlags & SDHC_PDD_TRANSFER_COMPLETE_INT) { + SDHC_PDD_ClearInterruptFlags(SDHC_BASE_PTR, SDHC_PDD_TRANSFER_COMPLETE_INT | DataErrorFlags); + } + } + switch (DeviceDataPrv->State) { + case LDD_SDHC_RESET: + Finished = TRUE; + break; + case LDD_SDHC_VOLTAGE_VALIDATION: + VoltageValidation(DeviceDataPrv, IntFlags, Response); /* Handle the voltage validation state */ + break; + case LDD_SDHC_CARD_REGISTRATION: + CardRegistration(DeviceDataPrv, IntFlags, Response); /* Handle the card registration state */ + break; + case LDD_SDHC_CARD_INFO_RETRIEVAL: + CardInfoRetrieval(DeviceDataPrv, IntFlags, Response); /* Handle the card info retrieval state */ + break; + case LDD_SDHC_CARD_SELECTION: + Finished = CardSelection(DeviceDataPrv, IntFlags, Response); /* Handle the card selection state */ + break; + case LDD_SDHC_TRANSFER: + Finished = Transfer(DeviceDataPrv, IntFlags, Response); /* Handle the transfer state */ + break; + case LDD_SDHC_ERASION: + Finished = Erasion(DeviceDataPrv, IntFlags, Response); /* Handle the erasion state */ + break; + case LDD_SDHC_DATA_WIDTH_SELECTION: + Finished = DataWidthSelection(DeviceDataPrv, IntFlags, Response); /* Handle the data width selection state */ + break; + case LDD_SDHC_BUS_CLOCK_SELECTION: + Finished = BusClockSelection(DeviceDataPrv, IntFlags, Response); /* Handle the bus clock selection state */ + break; + case LDD_SDHC_WRITE_PROTECTION_SETUP: + Finished = WriteProtectionSetup(DeviceDataPrv, IntFlags, Response); /* Handle the write protection setup state */ + break; + case LDD_SDHC_WRITE_PROTECTION_RETRIEVAL: + Finished = WriteProtectionRetrieval(DeviceDataPrv, IntFlags, Response); /* Handle the write protection retrieval state */ + break; + default: + break; + } + } + if (Finished) { + DeviceDataPrv->State = LDD_SDHC_IDLE; + if (DeviceDataPrv->EventMask & LDD_SDHC_ON_FINISHED) { + SDHC1_OnFinished(DeviceDataPrv->UserDataPtr); /* Call the user event */ + } + } +} + +/*lint -restore +esym(960,10.1) Enable MISRA rule (10.1,12.1) checking. */ + +/* END SDHC1 */ + +/* +** ################################################################### +** +** This file was created by Processor Expert 5.3 [05.01] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/source/Peripherals/SDHC1HA.h b/source/Peripherals/SDHC1HA.h new file mode 100644 index 0000000..6e91f65 --- /dev/null +++ b/source/Peripherals/SDHC1HA.h @@ -0,0 +1,1536 @@ +/** ################################################################### +** THIS COMPONENT MODULE IS GENERATED BY THE TOOL. DO NOT MODIFY IT. +** Filename : SDHC1.h +** Project : ProcessorExpert +** Processor : MK60DN512ZVMD10 +** Component : SDHC_LDD +** Version : Component 00.001, Driver 01.03, CPU db: 3.00.003 +** Compiler : CodeWarrior ARM C Compiler +** Date/Time : 2012-07-29, 21:43, # CodeGen: 371 +** Abstract : +** This component implements a SD host controller driver +** interface. Handles control and data transfers to/from +** SD and MMC cards. +** Settings : +** Component name : SDHC1 +** Device : SDHC +** Settings : +** Interface : 4-bit data mode +** Bus clock : 390.625 kHz +** Data timeout exponent : 20 +** DMA : +** Read watermark : 16 +** Write watermark : 16 +** Buffers : +** Transfer buffer table size : 8 +** Interrupt service/event : Enabled +** SDHC : INT_SDHC +** SDHC priority : medium priority +** Pins : 4-bit data mode +** CLK pin : PTE2/SPI1_SCK/UART1_CTS_b/SDHC0_DCLK/ADC1_SE6a +** CLK pin signal : SD_CLK +** CMD pin : PTE3/SPI1_SIN/UART1_RTS_b/SDHC0_CMD/ADC1_SE7a +** CMD pin signal : SD_CMD +** Data : +** DAT0 pin : PTE1/SPI1_SOUT/UART1_RX/SDHC0_D0/I2C1_SCL/ADC1_SE5a +** DAT0 pin signal : SD_DATA0 +** DAT1 : Enabled +** DAT1 pin : PTE0/SPI1_PCS1/UART1_TX/SDHC0_D1/I2C1_SDA/ADC1_SE4a +** DAT1 pin signal : SD_DATA1 +** DAT2 : Enabled +** DAT2 pin : PTE5/SPI1_PCS2/UART3_RX/SDHC0_D2 +** DAT2 pin signal : SD_DATA2 +** DAT3 : Enabled +** DAT3 pin : PTE4/SPI1_PCS0/UART3_TX/SDHC0_D3 +** DAT3 pin signal : SD_DATA3 +** Initialization : +** Enable device : yes +** Auto initialization : no +** Event mask : +** OnCardInserted : Enabled +** OnCardRemoved : Enabled +** OnFinished : Enabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Contents : +** Init - LDD_TDeviceData* SDHC1_Init(LDD_TUserData *UserDataPtr); +** Deinit - void SDHC1_Deinit(LDD_TDeviceData *DeviceDataPtr); +** Enable - LDD_TError SDHC1_Enable(LDD_TDeviceData *DeviceDataPtr); +** Disable - LDD_TError SDHC1_Disable(LDD_TDeviceData *DeviceDataPtr); +** SetEventMask - LDD_TError SDHC1_SetEventMask(LDD_TDeviceData *DeviceDataPtr, LDD_TEventMask... +** GetEventMask - LDD_TEventMask SDHC1_GetEventMask(LDD_TDeviceData *DeviceDataPtr); +** DetectCards - LDD_TError SDHC1_DetectCards(LDD_TDeviceData *DeviceDataPtr); +** SelectCard - LDD_TError SDHC1_SelectCard(LDD_TDeviceData *DeviceDataPtr, uint8_t Id); +** GetCardInfo - LDD_TError SDHC1_GetCardInfo(LDD_TDeviceData *DeviceDataPtr,... +** TransferBlocks - LDD_TError SDHC1_TransferBlocks(LDD_TDeviceData *DeviceDataPtr,... +** EraseBlocks - LDD_TError SDHC1_EraseBlocks(LDD_TDeviceData *DeviceDataPtr, uint32_t... +** SetDataWidth - LDD_TError SDHC1_SetDataWidth(LDD_TDeviceData *DeviceDataPtr, uint8_t Width); +** SelectBusClock - LDD_TError SDHC1_SelectBusClock(LDD_TDeviceData *DeviceDataPtr,... +** SetVoltage - LDD_TError SDHC1_SetVoltage(LDD_TDeviceData *DeviceDataPtr, LDD_SDHC_TVoltage... +** SetWriteProtection - LDD_TError SDHC1_SetWriteProtection(LDD_TDeviceData *DeviceDataPtr,... +** GetWriteProtection - LDD_TError SDHC1_GetWriteProtection(LDD_TDeviceData *DeviceDataPtr, uint32_t... +** CancelOperation - LDD_TError SDHC1_CancelOperation(LDD_TDeviceData *DeviceDataPtr); +** GetStatus - LDD_SDHC_TStatus SDHC1_GetStatus(LDD_TDeviceData *DeviceDataPtr); +** GetError - LDD_SDHC_TError SDHC1_GetError(LDD_TDeviceData *DeviceDataPtr, uint32_t... +** ConnectPin - LDD_TError SDHC1_ConnectPin(LDD_TDeviceData *DeviceDataPtr, LDD_TPinMask... +** SetOperationMode - LDD_TError SDHC1_SetOperationMode(LDD_TDeviceData *DeviceDataPtr,... +** GetDriverState - LDD_TDriverState SDHC1_GetDriverState(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2011 Freescale Semiconductor, Inc. All Rights Reserved. +** +** http : www.freescale.com +** mail : support@freescale.com +** ###################################################################*/ + +#ifndef SDHC1_H +#define SDHC1_H + +/* MODULE SDHC1 */ + +/* Include shared modules, which are used for whole project */ +#include +#include "build.h" +#include "sdhcha.h" + + +/* Configuration constants */ +#define SDHC1_MAX_CARD_NUMBER 1U +#define SDHC1_BUFFER_TABLE_SIZE 8U + +/* Component constants */ +#define SDHC1_OCR_HIGH_VOLTAGE_MASK 0x00FF8000UL +#define SDHC1_OCR_LOW_VOLTAGE_MASK 0x00000080UL +#define SDHC1_OCR_HIGH_CAPACITY_MASK 0x40000000UL +#define SDHC1_IF_COND_LOW_VOLTAGE_MASK 0x00000200UL +#define SDHC1_IF_COND_HIGH_VOLTAGE_MASK 0x00000100UL +#define SDHC1_IF_COND_CHECK_PATTERN 0x000000AAUL +#define SDHC1_VOLT_VALID_RETRY_COUNT 6500U /* Number of OCR (operation conditions register) request repetitions to give the card 1 second to power up (with 400kHz bus clock) */ +#define SDHC1_NO_RESPONSE 0U +#define SDHC1_CSD_SIZE 16U /* Card specific data register size */ +#define SDHC1_EXT_CSD_SIZE 512U /* Extended card specific data register size */ +#define SDHC1_SCR_SIZE 8U /* SD card configuration register size */ +#define SDHC1_SFS_SIZE 64U /* Switch function statuses register size */ +#define SDHC1_WRITE_PROTECT_MASK_SIZE 4U /* Write protection mask size */ + +/* Endianness correction macros */ +#define SDHC1_BE_TO_NE16(x) ((uint16_t)((uint16_t)(x) >> 8) | (uint16_t)((uint16_t)(x) << 8)) /* Big endian to native endian 16-bit */ +#define SDHC1_BE_TO_NE32(x) (((uint32_t)((uint32_t)(x) >> 24) & 0xFFU) | ((uint32_t)((uint32_t)(x) >> 8) & 0xFF00U) | ((uint32_t)((uint32_t)(x) << 8) & 0xFF0000U) | ((uint32_t)((uint32_t)(x) << 24) & 0xFF000000U)) /* Big endian to native endian 32-bit */ +#define SDHC1_NE_TO_BE16(x) ((uint16_t)((uint16_t)(x) >> 8) | (uint16_t)((uint16_t)(x) << 8)) /* Native endian to big endian 16-bit */ +#define SDHC1_NE_TO_BE32(x) (((uint32_t)((uint32_t)(x) >> 24) & 0xFFU) | ((uint32_t)((uint32_t)(x) >> 8) & 0xFF00U) | ((uint32_t)((uint32_t)(x) << 8) & 0xFF0000U) | ((uint32_t)((uint32_t)(x) << 24) & 0xFF000000U)) /* Native endian to big endian 32-bit */ + +/* Command arguments macros */ +#define SDHC1_CMD_ARG_RCA(RCA) (uint32_t)((uint32_t)(RCA) << 16) +#define SDHC1_SD_CMD6_ARG_MODE(Mode) (uint32_t)((uint32_t)(Mode) << 31) +#define SDHC1_SD_CMD6_CHECK_FUNC 0U +#define SDHC1_SD_CMD6_SWITCH_FUNC 1U +#define SDHC1_SD_CMD6_ARG_GROUP_1(Func) (uint32_t)((uint32_t)(Func) << 0) +#define SDHC1_SD_CMD6_GROUP_1_HIGH_SPEED 1U +#define SDHC1_SD_CMD6_ARG_GROUP_2(Func) (uint32_t)((uint32_t)(Func) << 4) +#define SDHC1_MMC_CMD6_ARG_ACCESS(Access) (uint32_t)((uint32_t)(Access) << 24) +#define SDHC1_MMC_CMD6_COMMAND_SET 0U +#define SDHC1_MMC_CMD6_SET_BITS 1U +#define SDHC1_MMC_CMD6_CLEAR_BITS 2U +#define SDHC1_MMC_CMD6_WRITE_BYTES 3U +#define SDHC1_MMC_CMD6_ARG_INDEX(Index) (uint32_t)((uint32_t)(Index) << 16) +#define SDHC1_MMC_CMD6_ARG_VALUE(Value) (uint32_t)((uint32_t)(Value) << 8) +#define SDHC1_MMC_CMD6_ARG_CMD_SET(Set) (uint32_t)((uint32_t)(Set) << 0) + +/* Response 1 status register field access macros */ +#define SDHC1_R1_IS_ADDRESS_OUT_OF_RANGE(Response) ((Response)[0] & 0x80000000UL) +#define SDHC1_R1_IS_ADDRESS_MISALIGN(Response) ((Response)[0] & 0x40000000UL) +#define SDHC1_R1_IS_BLOCK_LEN_ERROR(Response) ((Response)[0] & 0x20000000UL) +#define SDHC1_R1_IS_ERASE_SEQ_ERROR(Response) ((Response)[0] & 0x10000000UL) +#define SDHC1_R1_IS_ERASE_PARAM(Response) ((Response)[0] & 0x08000000UL) +#define SDHC1_R1_IS_WP_VIOLATION(Response) ((Response)[0] & 0x04000000UL) +#define SDHC1_R1_IS_CARD_IS_LOCKED(Response) ((Response)[0] & 0x02000000UL) +#define SDHC1_R1_IS_LOCK_UNLOCK_FAILED(Response) ((Response)[0] & 0x01000000UL) +#define SDHC1_R1_IS_COM_CRC_ERROR(Response) ((Response)[0] & 0x00800000UL) +#define SDHC1_R1_IS_ILLEGAL_COMMAND(Response) ((Response)[0] & 0x00400000UL) +#define SDHC1_R1_IS_CARD_ECC_FAILED(Response) ((Response)[0] & 0x00200000UL) +#define SDHC1_R1_IS_CC_ERROR(Response) ((Response)[0] & 0x00100000UL) +#define SDHC1_R1_IS_ERROR(Response) ((Response)[0] & 0x00080000UL) +#define SDHC1_R1_MMC_IS_UNDERRUN(Response) ((Response)[0] & 0x00040000UL) +#define SDHC1_R1_MMC_IS_OVERRUN(Response) ((Response)[0] & 0x00020000UL) +#define SDHC1_R1_IS_CSD_OVERWRITE(Response) ((Response)[0] & 0x00010000UL) +#define SDHC1_R1_IS_WP_ERASE_SKIP(Response) ((Response)[0] & 0x00008000UL) +#define SDHC1_R1_SD_IS_CARD_ECC_DISABLED(Response) ((Response)[0] & 0x00004000UL) +#define SDHC1_R1_IS_ERASE_RESET(Response) ((Response)[0] & 0x00002000UL) +#define SDHC1_R1_GET_CURRENT_STATE(Response) (((Response)[0] & 0x00001E00UL) >> 9) +#define SDHC1_R1_IDLE_STATE 0x00U +#define SDHC1_R1_READY_STATE 0x01U +#define SDHC1_R1_IDENTIFICATION_STATE 0x02U +#define SDHC1_R1_STAND_BY_STATE 0x03U +#define SDHC1_R1_TRANSFER_STATE 0x04U +#define SDHC1_R1_SENDING_DATA_STATE 0x05U +#define SDHC1_R1_RECEIVE_DATA_STATE 0x06U +#define SDHC1_R1_PROGRAMMING_STATE 0x07U +#define SDHC1_R1_DISCONNECT_STATE 0x08U +#define SDHC1_R1_BUS_TEST_STATE 0x09U +#define SDHC1_R1_SLEEP_STATE 0x0AU +#define SDHC1_R1_IS_READY_FOR_DATA(Response) ((Response)[0] & 0x00000100UL) +#define SDHC1_R1_IS_SWITCH_ERROR(Response) ((Response)[0] & 0x00000080UL) +#define SDHC1_R1_IS_APP_CMD(Response) ((Response)[0] & 0x00000020UL) +#define SDHC1_R1_SD_IS_AKE_SEQ_ERROR(Response) ((Response)[0] & 0x00000008UL) + +/* Response 2 SD CSD (card specific data) v1, v2 and MMC CSD (card specific data) register field access macros */ +#define SDHC1_R2_GET_CSD_STRUCTURE(Response) (((Response)[3] & 0x00C00000UL) >> 22) +#define SDHC1_SD_CSD_VERS_1_0 0U +#define SDHC1_SD_CSD_VERS_2_0 1U +#define SDHC1_MMC_CSD_VERS_1_0 0U +#define SDHC1_MMC_CSD_VERS_1_1 1U +#define SDHC1_MMC_CSD_VERS_1_2 2U +#define SDHC1_MMC_CSD_VERS_IN_EXT_CSD 3U +#define SDHC1_R2_MMC_GET_SPEC_VERS(Response) (((Response)[3] & 0x003C0000UL) >> 18) +#define SDHC1_MMC_CSD_SPEC_VERS_1_X 0U +#define SDHC1_MMC_CSD_SPEC_VERS_1_4 1U +#define SDHC1_MMC_CSD_SPEC_VERS_2_X 2U +#define SDHC1_MMC_CSD_SPEC_VERS_3_X 3U +#define SDHC1_MMC_CSD_SPEC_VERS_4_X 4U +#define SDHC1_R2_GET_TAAC(Response) (((Response)[3] & 0x0000FF00UL) >> 8) +#define SDHC1_R2_GET_NSAC(Response) (((Response)[3] & 0x000000FFUL) >> 0) +#define SDHC1_R2_GET_TRAN_SPEED(Response) (((Response)[2] & 0xFF000000UL) >> 24) +#define SDHC1_R2_GET_CCC(Response) (((Response)[2] & 0x00FFF000UL) >> 12) +#define SDHC1_R2_GET_READ_BL_LEN(Response) (((Response)[2] & 0x00000F00UL) >> 8) +#define SDHC1_R2_GET_READ_BL_PARTIAL(Response) (((Response)[2] & 0x00000080UL) >> 7) +#define SDHC1_R2_GET_WRITE_BLK_MISALIGN(Response) (((Response)[2] & 0x00000040UL) >> 6) +#define SDHC1_R2_GET_READ_BLK_MISALIGN(Response) (((Response)[2] & 0x00000020UL) >> 5) +#define SDHC1_R2_GET_DSR_IMP(Response) (((Response)[2] & 0x00000010UL) >> 4) + +/* Response 2 CSD (card specific data) v1 register field access macros */ +#define SDHC1_R2_CSD_V1_GET_C_SIZE(Response) ((((Response)[2] & 0x00000003UL) << 10) | (((Response)[1] & 0xFFC00000UL) >> 22)) +#define SDHC1_R2_CSD_V1_GET_MIN_VDD_R_CURR(Response) (((Response)[1] & 0x00380000UL) >> 19) +#define SDHC1_R2_CSD_V1_GET_MAX_VDD_R_CURR(Response) (((Response)[1] & 0x00070000UL) >> 16) +#define SDHC1_R2_CSD_V1_GET_MIN_VDD_W_CURR(Response) (((Response)[1] & 0x0000E000UL) >> 13) +#define SDHC1_R2_CSD_V1_GET_MAX_VDD_W_CURR(Response) (((Response)[1] & 0x00001C00UL) >> 10) +#define SDHC1_R2_CSD_V1_GET_C_SIZE_MULT(Response) (((Response)[1] & 0x00000380UL) >> 7) + +/* Response 2 SD CSD (card specific data) v2 register field access macros */ +#define SDHC1_R2_CSD_V2_GET_C_SIZE(Response) (((Response)[1] & 0x3FFFFF00UL) >> 8) + +/* Response 2 SD CSD (card specific data) register field access macros */ +#define SDHC1_R2_SD_GET_ERASE_BLOCK_EN(Response) (((Response)[1] & 0x00000040UL) >> 6) +#define SDHC1_R2_SD_GET_SECTOR_SIZE(Response) ((((Response)[1] & 0x0000003FUL) << 1) | (((Response)[0] & 0x80000000UL) >> 31)) +#define SDHC1_R2_SD_GET_WP_GRP_SIZE(Response) (((Response)[0] & 0x1F000000UL) >> 24) + +/* Response 2 MMC CSD (card specific data) register field access macros */ +#define SDHC1_R2_MMC_GET_ERASE_GRP_SIZE(Response) (((Response)[1] & 0x0000007CUL) >> 2) +#define SDHC1_R2_MMC_GET_ERASE_GRP_MULT(Response) ((((Response)[1] & 0x00000003UL) << 3) | (((Response)[0] & 0xE0000000UL) >> 29)) +#define SDHC1_R2_MMC_GET_WP_GRP_SIZE(Response) (((Response)[0] & 0x1F000000UL) >> 24) + +/* Response 2 CSD (card specific data) register field access macros */ +#define SDHC1_R2_GET_WP_GRP_ENABLE(Response) (((Response)[0] & 0x00800000UL) >> 23) +#define SDHC1_R2_GET_DEFAULT_ECC(Response) (((Response)[0] & 0x00600000UL) >> 21) +#define SDHC1_R2_GET_R2W_FACTOR(Response) (((Response)[0] & 0x001C0000UL) >> 18) +#define SDHC1_R2_GET_WRITE_BL_LEN(Response) (((Response)[0] & 0x0003C000UL) >> 14) +#define SDHC1_R2_GET_WRITE_BL_PARTIAL(Response) (((Response)[0] & 0x00002000UL) >> 13) +#define SDHC1_R2_GET_CONTENT_PROT_APP(Response) (((Response)[0] & 0x00000100UL) >> 8) +#define SDHC1_R2_GET_FILE_FORMAT_GRP(Response) (((Response)[0] & 0x00000080UL) >> 7) +#define SDHC1_R2_GET_COPY(Response) (((Response)[0] & 0x00000040UL) >> 6) +#define SDHC1_R2_GET_PERM_WRITE_PROTECT(Response) (((Response)[0] & 0x00000020UL) >> 5) +#define SDHC1_R2_GET_TMP_WRITE_PROTECT(Response) (((Response)[0] & 0x00000010UL) >> 4) +#define SDHC1_R2_GET_FILE_FORMAT(Response) (((Response)[0] & 0x0000000CUL) >> 2) +#define SDHC1_R2_GET_ECC(Response) (((Response)[0] & 0x00000003UL) >> 0) + +/* Response 2 CSD (card specific data) register writable field masks */ +#define SDHC1_R2_FILE_FORMAT_GRP_MASK 0x00000080UL +#define SDHC1_R2_COPY_MASK 0x00000040UL +#define SDHC1_R2_PERM_WRITE_PROTECT_MASK 0x00000020UL +#define SDHC1_R2_TMP_WRITE_PROTECT_MASK 0x00000010UL +#define SDHC1_R2_FILE_FORMAT_MASK 0x0000000CUL +#define SDHC1_R2_ECC_MASK 0x00000003UL + +/* Response 2 CID register field access macros */ +#define SDHC1_R2_GET_MANUFACTURER_ID(Response) (((Response)[3] & 0x00FF0000UL) >> 16) + +/* Response 2 SD CID register field access macros */ +#define SDHC1_R2_SD_GET_OEM_APPLICATION_ID(Response) (((Response)[3] & 0x0000FFFFUL) >> 0) +#define SDHC1_R2_SD_GET_PRODUCT_NAME(Response) ((((Response)[2] & 0xFFFFFFFFUL) << 8) | (((Response)[1] & 0xFF000000UL) >> 24)) +#define SDHC1_R2_SD_GET_PRODUCT_REVISION(Response) (((Response)[1] & 0x00FF0000UL) >> 16) +#define SDHC1_R2_SD_GET_PRODUCT_SERIAL_NUMBER(Response) ((((Response)[1] & 0x0000FFFFUL) << 16) | (((Response)[0] & 0xFFFF0000UL) >> 16)) +#define SDHC1_R2_SD_GET_MANUFACTURING_DATE(Response) (((Response)[0] & 0x00000FFFUL) >> 0) +/* Response 2 MMC CID register field access macros */ +#define SDHC1_R2_MMC_GET_CARD_BGA(Response) (((Response)[3] & 0x00000300UL) >> 8) +#define SDHC1_R2_MMC_GET_OEM_APPLICATION_ID(Response) (((Response)[3] & 0x000000FFUL) >> 0) +#define SDHC1_R2_MMC_GET_PRODUCT_NAME(Response) ((((Response)[2] & 0xFFFFFFFFUL) << 16) | (((Response)[1] & 0xFFFF0000UL) >> 16)) +#define SDHC1_R2_MMC_GET_PRODUCT_REVISION(Response) (((Response)[1] & 0x0000FF00UL) >> 8) +#define SDHC1_R2_MMC_GET_PRODUCT_SERIAL_NUMBER(Response) ((((Response)[1] & 0x000000FFUL) << 24) | (((Response)[0] & 0xFFFFFF00UL) >> 8)) +#define SDHC1_R2_MMC_GET_MANUFACTURING_DATE(Response) (((Response)[0] & 0x000000FFUL) >> 0) + +/* Response 3 OCR (operation conditions register) access macros */ +#define SDHC1_R3_OCR_IS_CARD_POWER_UP(Response) ((Response)[0] & 0x80000000UL) +#define SDHC1_R3_OCR_IS_CARD_HIGH_CAPACITY(Response) ((Response)[0] & 0x40000000UL) + +/* Response 6 field access macros */ +#define SDHC1_R6_GET_RCA(Response) ((Response)[0] >> 16) + +/* Extended CSD (card specific data) register data block field indices */ +#define SDHC1_EXT_CSD_S_CMD_SET_INDEX 504U +#define SDHC1_EXT_CSD_INI_TIMEOUT_AP_INDEX 241U +#define SDHC1_EXT_CSD_PWR_CL_DDR_52_360_INDEX 239U +#define SDHC1_EXT_CSD_PWR_CL_DDR_52_195_INDEX 238U +#define SDHC1_EXT_CSD_MIN_PERF_DDR_W_8_52_INDEX 235U +#define SDHC1_EXT_CSD_MIN_PERF_DDR_R_8_52_INDEX 234U +#define SDHC1_EXT_CSD_TRIM_MULT_INDEX 232U +#define SDHC1_EXT_CSD_SEC_FEATURE_SUPPORT_INDEX 231U +#define SDHC1_EXT_CSD_SEC_ERASE_MULT_INDEX 230U +#define SDHC1_EXT_CSD_SEC_TRIM_MULT_INDEX 229U +#define SDHC1_EXT_CSD_BOOT_INFO_INDEX 228U +#define SDHC1_EXT_CSD_BOOT_SIZE_MULTI_INDEX 226U +#define SDHC1_EXT_CSD_ACC_SIZE_INDEX 225U +#define SDHC1_EXT_CSD_HC_ERASE_GRP_SIZE_INDEX 224U +#define SDHC1_EXT_CSD_ERASE_TIMEOUT_MULT_INDEX 223U +#define SDHC1_EXT_CSD_REL_WR_SEC_C_INDEX 222U +#define SDHC1_EXT_CSD_HC_WP_GRP_SIZE_INDEX 221U +#define SDHC1_EXT_CSD_S_C_VCC_INDEX 220U +#define SDHC1_EXT_CSD_S_C_VCCQ_INDEX 219U +#define SDHC1_EXT_CSD_S_A_TIMEOUT_INDEX 217U +#define SDHC1_EXT_CSD_SEC_COUNT_INDEX 212U +#define SDHC1_EXT_CSD_MIN_PERF_W_8_52_INDEX 210U +#define SDHC1_EXT_CSD_MIN_PERF_R_8_52_INDEX 209U +#define SDHC1_EXT_CSD_MIN_PERF_W_8_26_4_52_INDEX 208U +#define SDHC1_EXT_CSD_MIN_PERF_R_8_26_4_52_INDEX 207U +#define SDHC1_EXT_CSD_MIN_PERF_W_4_26_INDEX 206U +#define SDHC1_EXT_CSD_MIN_PERF_R_4_26_INDEX 205U +#define SDHC1_EXT_CSD_PWR_CL_26_360_INDEX 203U +#define SDHC1_EXT_CSD_PWR_CL_52_360_INDEX 202U +#define SDHC1_EXT_CSD_PWR_CL_26_195_INDEX 201U +#define SDHC1_EXT_CSD_PWR_CL_52_195_INDEX 200U +#define SDHC1_EXT_CSD_CARD_TYPE_INDEX 196U +#define SDHC1_EXT_CSD_CSD_STRUCTURE_INDEX 194U +#define SDHC1_EXT_CSD_EXT_CSD_REV_INDEX 192U +#define SDHC1_EXT_CSD_CMD_SET_INDEX 191U +#define SDHC1_EXT_CSD_CMD_SET_REV_INDEX 189U +#define SDHC1_EXT_CSD_POWER_CLASS_INDEX 187U +#define SDHC1_EXT_CSD_HS_TIMING_INDEX 185U +#define SDHC1_EXT_CSD_BUS_WIDTH_INDEX 183U +#define SDHC1_EXT_CSD_ERASED_MEM_CONT_INDEX 181U +#define SDHC1_EXT_CSD_PARTITION_CONFIG_INDEX 179U +#define SDHC1_EXT_CSD_BOOT_CONFIG_PROT_INDEX 178U +#define SDHC1_EXT_CSD_BOOT_BUS_WIDTH_INDEX 177U +#define SDHC1_EXT_CSD_ERASE_GROUP_DEF_INDEX 175U +#define SDHC1_EXT_CSD_BOOT_WP_INDEX 173U +#define SDHC1_EXT_CSD_USER_WP_INDEX 171U +#define SDHC1_EXT_CSD_FW_CONFIG_INDEX 169U +#define SDHC1_EXT_CSD_RPMB_SIZE_MULT_INDEX 168U +#define SDHC1_EXT_CSD_RST_N_FUNCTION_INDEX 162U +#define SDHC1_EXT_CSD_PARTITIONING_SUPPORT_INDEX 160U +#define SDHC1_EXT_CSD_MAX_ENH_SIZE_MULT_INDEX 157U +#define SDHC1_EXT_CSD_PARTITIONS_ATTRIBUTE_INDEX 156U +#define SDHC1_EXT_CSD_PARTITION_SETTING_COMPLETED_INDEX 155U +#define SDHC1_EXT_CSD_GP_SIZE_MULT_1_0_INDEX 154U +#define SDHC1_EXT_CSD_GP_SIZE_MULT_1_1_INDEX 153U +#define SDHC1_EXT_CSD_GP_SIZE_MULT_1_2_INDEX 152U +#define SDHC1_EXT_CSD_GP_SIZE_MULT_2_0_INDEX 151U +#define SDHC1_EXT_CSD_GP_SIZE_MULT_2_1_INDEX 150U +#define SDHC1_EXT_CSD_GP_SIZE_MULT_2_2_INDEX 149U +#define SDHC1_EXT_CSD_GP_SIZE_MULT_3_0_INDEX 148U +#define SDHC1_EXT_CSD_GP_SIZE_MULT_3_1_INDEX 147U +#define SDHC1_EXT_CSD_GP_SIZE_MULT_3_2_INDEX 146U +#define SDHC1_EXT_CSD_GP_SIZE_MULT_4_0_INDEX 145U +#define SDHC1_EXT_CSD_GP_SIZE_MULT_4_1_INDEX 144U +#define SDHC1_EXT_CSD_GP_SIZE_MULT_4_2_INDEX 143U +#define SDHC1_EXT_CSD_ENH_SIZE_MULT_INDEX 140U +#define SDHC1_EXT_CSD_ENH_START_ADDR_INDEX 136U +#define SDHC1_EXT_CSD_SEC_BAD_BLK_MGMNT_INDEX 134U + +/* SCR (SD card configuration register) data block field access macros */ +#define SDHC1_SCR_GET_SCR_STRUCTURE(Response) ((((uint8_t*)(Response))[0] & 0xF0U) >> 4) +#define SDHC1_SCR_GET_SD_SPEC(Response) ((((uint8_t*)(Response))[0] & 0x0FU) >> 0) +#define SDHC1_SCR_SD_SPEC_VERS_1_0X 0U +#define SDHC1_SCR_SD_SPEC_VERS_1_10 1U +#define SDHC1_SCR_SD_SPEC_VERS_2_00 2U +#define SDHC1_SCR_GET_DATA_STAT_AFTER_ERASE(Response) ((((uint8_t*)(Response))[1] & 0x80U) >> 7) +#define SDHC1_SCR_GET_SD_SECURITY(Response) ((((uint8_t*)(Response))[1] & 0x70U) >> 4) +#define SDHC1_SCR_GET_SD_BUS_WIDTHS(Response) ((((uint8_t*)(Response))[1] & 0x0FU) >> 0) +#define SDHC1_SCR_SD_BUS_WIDTH_1_BIT_MASK 0x01U +#define SDHC1_SCR_SD_BUS_WIDTH_4_BIT_MASK 0x04U + +/* Switch function status block position in the component's card data structure info block */ +#define SDHC1_SFS_BLOCK_START 8U +/* Switch function status block field access macros */ +#define SDHC1_SFS_IS_FUNC_SUPPORTED(Response, Group, Index) ((SDHC1_BE_TO_NE16(((uint16_t*)(Response))[6U - ((Group) - 1U)]) >> (Index)) & 1U) +#define SDHC1_SFS_HIGH_SPEED_FUNC_GROUP 1U +#define SDHC1_SFS_HIGH_SPEED_FUNC_INDEX 1U + +/* Voltage validation substates */ +#define SDHC1_VV_START 0U +#define SDHC1_VV_SDHC_CHECK 1U +#define SDHC1_VV_SD_CHECK 2U +#define SDHC1_VV_MMC_CHECK 3U +#define SDHC1_VV_FINISH 4U + +/* Card registration substates */ +#define SDHC1_CR_START 0U +#define SDHC1_CR_GET_CID 1U +#define SDHC1_CR_GET_RCA 2U +#define SDHC1_CR_FINISH 3U + +/* Card info retrieval substates */ +#define SDHC1_CIR_START 0U +#define SDHC1_CIR_STAND_BY_STATE 1U +#define SDHC1_CIR_GET_CSD 2U +#define SDHC1_CIR_TRANSFER_STATE 3U +#define SDHC1_CIR_GET_EXT_CSD 4U +#define SDHC1_CIR_BUS_TEST_4_BIT_WRITE 5U +#define SDHC1_CIR_BUS_TEST_4_BIT_READ 6U +#define SDHC1_CIR_BUS_TEST_8_BIT_WRITE 7U +#define SDHC1_CIR_BUS_TEST_8_BIT_READ 8U +#define SDHC1_CIR_GET_SCR 9U +#define SDHC1_CIR_GET_FUNC_STATUS 10U +#define SDHC1_CIR_FINISH 11U + +/* Blocks erasion substates */ +#define SDHC1_E_SET_START 0U +#define SDHC1_E_SET_END 1U +#define SDHC1_E_EXECUTE 2U +#define SDHC1_E_FINISH 3U + +/* Data width selection substates */ +#define SDHC1_DWS_START 0U +#define SDHC1_DWS_BUSY 1U +#define SDHC1_DWS_FINISH 2U + +/* Command states */ +#define SDHC1_CMD_DATA_LEN 0U +#define SDHC1_CMD_START 1U +#define SDHC1_CMD_ACMD 2U +#define SDHC1_CMD_FINISH 3U +#define SDHC1_CMD_DATA 4U +#define SDHC1_CMD_ERROR 5U + +/* ADMA2 transfer buffer descriptor attribute constants */ +#define SDHC1_ADMA2_VALID 0x0001U /* Descriptor line is valid */ +#define SDHC1_ADMA2_END 0x0002U /* Descriptor line is ending */ +#define SDHC1_ADMA2_INT 0x0004U /* Generate interrupt when the descriptor is done*/ +#define SDHC1_ADMA2_ATTR_ACT_NOP 0x0000U /* No operation */ +#define SDHC1_ADMA2_ATTR_ACT_RSV 0x0010U /* Reserved (no operation) */ +#define SDHC1_ADMA2_ATTR_ACT_TRAN 0x0020U /* Transfer data with address and length set in this descriptor line */ +#define SDHC1_ADMA2_ATTR_ACT_LINK 0x0030U /* Link to another descriptor */ +#define SDHC1_SINGLE_BLOCK_TRANS_ATTRS (SDHC1_ADMA2_VALID | SDHC1_ADMA2_END | SDHC1_ADMA2_ATTR_ACT_TRAN) + +#define SDHC1_TRANSFER_TABLE_ALIGN 4U /* Transfer table memory alignment */ +#define SDHC1_TRANSFER_BUFFER_ALIGN 4U /* Transfer buffer memory alignment */ + +/* Pins port register bit indices where to configure pulls */ +#define SDHC1_PIN_CMD_PORT_INDEX 3u +#define SDHC1_PIN_DAT0_PORT_INDEX 1u +#define SDHC1_PIN_DAT1_PORT_INDEX 0u +#define SDHC1_PIN_DAT2_PORT_INDEX 5u +#define SDHC1_PIN_DAT3_PORT_INDEX 4u + +#define SDHC_BASE_PTR SDHC_BASE + +#define LDD_SDHC_CARD_DATA_WIDTH_1_BIT 0x01u /* Card supports 1 bit data bus */ +#define LDD_SDHC_CARD_DATA_WIDTH_4_BIT 0x02u /* Card supports 4 bit data bus */ +#define LDD_SDHC_CARD_DATA_WIDTH_8_BIT 0x04u /* Card supports 8 bit data bus */ +#define LDD_SDHC_CARD_BLOCK_READ 0x01u /* Card supports block reading */ +#define LDD_SDHC_CARD_BLOCK_WRITE 0x04u /* Card supports block writing */ +#define LDD_SDHC_CARD_ERASE 0x08u /* Card supports block erasion */ +#define LDD_SDHC_CARD_WRITE_PROTECTION 0x10u /* Card supports write protection */ +#define LDD_SDHC_CARD_IO 0x80u /* Card supports IO */ + +#define LDD_SDHC_CLK_PIN 0x01u /* SD clock pin mask */ +#define LDD_SDHC_CMD_PIN 0x02u /* SD command line pin mask */ +#define LDD_SDHC_DAT0_PIN 0x04u /* SD data line 0 pin mask */ +#define LDD_SDHC_DAT1_PIN 0x08u /* SD data line 1 pin mask */ +#define LDD_SDHC_DAT2_PIN 0x10u /* SD data line 2 pin mask */ +#define LDD_SDHC_DAT3_PIN 0x20u /* SD data line 3 pin mask */ +#define LDD_SDHC_DAT4_PIN 0x40u /* SD data line 4 pin mask */ +#define LDD_SDHC_DAT5_PIN 0x80u /* SD data line 5 pin mask */ +#define LDD_SDHC_DAT6_PIN 0x0100u /* SD data line 6 pin mask */ +#define LDD_SDHC_DAT7_PIN 0x0200u /* SD data line 7 pin mask */ +#define LDD_SDHC_CD_PIN 0x0400u /* SD card detection pin mask */ +#define LDD_SDHC_WP_PIN 0x0800u /* SD write protection pin mask */ +#define LDD_SDHC_LCTL_PIN 0x1000u /* SD LED control pin mask */ +#define LDD_SDHC_VS_PIN 0x2000u /* SD voltage control pin mask */ + +#define LDD_SDHC_ON_CARD_INSERTED 0x01u /* OnCardInserted event mask */ +#define LDD_SDHC_ON_CARD_REMOVED 0x02u /* OnCardRemoved event mask */ +#define LDD_SDHC_ON_FINISHED 0x04u /* OnFinished event mask */ + +#define CPU_CLOCK_CONFIG_0 0x00U /* Clock configuration 0 identifier */ + +#define SDHC_PDD_CMD0_GO_IDLE_STATE SDHCHA_nCMD0_GO_IDLE_STATE +#define SDHC_PDD_CMD1_SEND_OP_COND SDHCHA_nCMD1_MMC_SEND_OP_COND +#define SDHC_PDD_CMD2_ALL_SEND_CID SDHCHA_nCMD2_ALL_SEND_CID +#define SDHC_PDD_CMD3_SET_RELATIVE_ADDR SDHCHA_nCMD3_SET_RELATIVE_ADDR +#define SDHC_PDD_CMD6_SWITCH SDHCHA_nCMD6_SWITCH +#define SDHC_PDD_CMD7_SELECT_CARD SDHCHA_nCMD7_SELECT_CARD +#define SDHC_PDD_CMD8_SEND_EXT_CSD SDHCHA_nCMD8_SEND_EXT_CSD +#define SDHC_PDD_CMD9_SEND_CSD SDHCHA_nCMD9_SEND_CSD +#define SDHC_PDD_CMD12_STOP_TRANSMISSION SDHCHA_nCMD12_STOP_TRANS +#define SDHC_PDD_CMD13_SEND_STATUS SDHCHA_nCMD13_SEND_STATUS +#define SDHC_PDD_CMD14_BUS_TEST_READ SDHCHA_nCMD14_BUS_TEST_READ +#define SDHC_PDD_CMD16_SET_BLOCKLEN SDHCHA_nCMD16_SET_BLOCKLEN +#define SDHC_PDD_CMD17_READ_SINGLE_BLOCK SDHCHA_nCMD17_READ_SINGLE_BLOCK +#define SDHC_PDD_CMD18_READ_MULTIPLE_BLOCK SDHCHA_nCMD18_READ_MULTIPLE_BLOCK +#define SDHC_PDD_CMD19_BUS_TEST_WRITE SDHCHA_nCMD19_BUS_TEST_WRITE +#define SDHC_PDD_CMD24_WRITE_BLOCK SDHCHA_nCMD24_WRITE_BLOCK +#define SDHC_PDD_CMD25_WRITE_MULTIPLE_BLOCK SDHCHA_nCMD25_WRITE_MULTIPLE_BLOCK +#define SDHC_PDD_CMD27_PROGRAM_CSD SDHCHA_nCMD27_PROGRAM_CSD +#define SDHC_PDD_CMD28_SET_WRITE_PROT SDHCHA_nCMD28_SET_WRITE_PROT +#define SDHC_PDD_CMD29_CLR_WRITE_PROT SDHCHA_nCMD29_CLR_WRITE_PROT +#define SDHC_PDD_CMD30_SEND_WRITE_PROT SDHCHA_nCMD30_SEND_WRITE_PROT +#define SDHC_PDD_CMD32_TAG_SECTOR_START SDHCHA_nCMD32_TAG_SECTOR_START +#define SDHC_PDD_CMD33_TAG_SECTOR_END SDHCHA_nCMD33_TAG_SECTOR_END +#define SDHC_PDD_CMD35_TAG_ERASE_GROUP_START SDHCHA_nCMD35_TAG_ERASE_GROUP_START +#define SDHC_PDD_CMD36_TAG_ERASE_GROUP_END SDHCHA_nCMD36_TAG_ERASE_GROUP_END +#define SDHC_PDD_CMD38_ERASE SDHCHA_nCMD38_ERASE +#define SDHC_PDD_CMD55_APP_CMD SDHCHA_nCMD55_APP_CMD + +#define SDHC_PDD_ACMD6_SET_BUS_WIDTH SDHCHA_nACMD6_SET_BUS_WIDTH +#define SDHC_PDD_ACMD41_SD_APP_OP_COND SDHCHA_nACMD41_SEND_OP_COND +#define SDHC_PDD_ACMD51_SEND_SCR SDHCHA_nACMD51_MMC_SEND_SCR + + +#define SDHC_PDD_NO_RESPONSE SDHCHA_nRESPONSE_NIL +#define SDHC_PDD_RESPONSE_LENGTH_136 SDHCHA_nRESPONSE_136 +#define SDHC_PDD_RESPONSE_LENGTH_48 SDHCHA_nRESPONSE_48 +#define SDHC_PDD_RESPONSE_LENGTH_48_BUSY_CHECK SDHCHA_nRESPONSE_48_BUSY +#define SDHC_PDD_ENABLE_DMA SDHCHA_nENABLE_DMA +#define SDHC_PDD_DATA_PRESENT SDHCHA_nDATA_PRESENT +#define SDHC_PDD_DATA_READ SDHCHA_nDATA_READ +#define SDHC_PDD_DATA_WRITE SDHCHA_nDATA_WRITE +#define SDHC_PDD_ENABLE_BLOCK_COUNT SDHCHA_nENABLE_BLOCK_COUNT +#define SDHC_PDD_ENABLE_AUTO_CMD12 SDHCHA_nENABLE_AUTO_CMD12 +#define SDHC_PDD_MULTIPLE_BLOCK SDHCHA_nMULTIPLE_BLOCK +#define SDHC_PDD_DATA_TIMEOUT_ERROR_INT SDHCHA_nDATA_TIMEOUT_ERROR_INT +#define SDHC_PDD_DATA_END_BIT_ERROR_INT SDHCHA_nDATA_END_BIT_ERROR_INT +#define SDHC_PDD_DATA_CRC_ERROR_INT SDHCHA_nDATA_CRC_ERROR_INT +#define SDHC_PDD_DMA_ERROR_INT SDHCHA_nDMA_ERROR_INT +#define SDHC_PDD_COMMAND_TIMEOUT_ERROR_INT SDHCHA_nCOMMAND_TIMEOUT_ERROR_INT +#define SDHC_PDD_COMMAND_CRC_ERROR_INT SDHCHA_nCOMMAND_CRC_ERROR_INT +#define SDHC_PDD_COMMAND_END_BIT_ERROR_INT SDHCHA_nCOMMAND_END_BIT_ERROR_INT +#define SDHC_PDD_COMMAND_INDEX_ERROR_INT SDHCHA_nCOMMAND_INDEX_ERROR_INT +#define SDHC_PDD_COMMAND_COMPLETE_INT SDHCHA_nCOMMAND_COMPLETE_INT +#define SDHC_PDD_TRANSFER_COMPLETE_INT SDHCHA_nTRANSFER_COMPLETE_INT +#define SDHC_PDD_BUFFER_READ_READY_INT SDHCHA_nBUFFER_READ_READY_INT +#define SDHC_PDD_BUFFER_WRITE_READY_INT SDHCHA_nBUFFER_WRITE_READY_INT +#define SDHC_PDD_AUTO_CMD12_CRC_ERROR SDHCHA_nAUTO_CMD12_CRC_ERROR +#define SDHC_PDD_AUTO_CMD12_END_BIT_ERROR SDHCHA_nAUTO_CMD12_END_BIT_ERROR +#define SDHC_PDD_AUTO_CMD12_INDEX_ERROR SDHCHA_nAUTO_CMD12_INDEX_ERROR +#define SDHC_PDD_AUTO_CMD12_ERROR_INT SDHCHA_nAUTO_CMD12_ERROR_INT +#define SDHC_PDD_AUTO_CMD12_TIMEOUT_ERROR SDHCHA_nAUTO_CMD12_TIMEOUT_ERROR + +#define SDHC_PDD_1_BIT_MODE SDHCHA_n1_BIT_MODE +#define SDHC_PDD_4_BIT_MODE SDHCHA_n4_BIT_MODE +#define SDHC_PDD_8_BIT_MODE SDHCHA_n8_BIT_MODE + +#define PDD_ENABLE true +#define PDD_DISABLE false + +/* Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define SDHC1_PRPH_BASE_ADDRESS 0x400B1000U + +/* Methods configuration constants - generated for all enabled component's methods */ +#define SDHC1_Init_METHOD_ENABLED +#define SDHC1_Deinit_METHOD_ENABLED +#define SDHC1_Enable_METHOD_ENABLED +#define SDHC1_Disable_METHOD_ENABLED +#define SDHC1_SetEventMask_METHOD_ENABLED +#define SDHC1_GetEventMask_METHOD_ENABLED +#define SDHC1_DetectCards_METHOD_ENABLED +#define SDHC1_SelectCard_METHOD_ENABLED +#define SDHC1_GetCardInfo_METHOD_ENABLED +#define SDHC1_TransferBlocks_METHOD_ENABLED +#define SDHC1_EraseBlocks_METHOD_ENABLED +#define SDHC1_SetDataWidth_METHOD_ENABLED +#define SDHC1_SelectBusClock_METHOD_ENABLED +#define SDHC1_SetVoltage_METHOD_ENABLED +#define SDHC1_SetWriteProtection_METHOD_ENABLED +#define SDHC1_GetWriteProtection_METHOD_ENABLED +#define SDHC1_CancelOperation_METHOD_ENABLED +#define SDHC1_GetStatus_METHOD_ENABLED +#define SDHC1_GetError_METHOD_ENABLED +#define SDHC1_ConnectPin_METHOD_ENABLED +#define SDHC1_SetOperationMode_METHOD_ENABLED +#define SDHC1_GetDriverState_METHOD_ENABLED + +/* Events configuration constants - generated for all enabled component's events */ +#define SDHC1_OnCardInserted_EVENT_ENABLED +#define SDHC1_OnCardRemoved_EVENT_ENABLED +#define SDHC1_OnFinished_EVENT_ENABLED + + +#define SDHC1_NO_CARD 1 /* Special card ID for the SelectCard method indicating that no card should be selected (unselect all). */ + +#define SDHC_DSADDR *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, DSADDR ) ) +#define SDHC_BLKATTR *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, BLKATTR ) ) +#define SDHC_CMDARG *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, CMDARG ) ) +#define SDHC_XFERTYP *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, XFERTYP ) ) +#define SDHC_CMDRSP *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, CMDRSP[0]) ) +#define SDHC_DATPORT *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, DATPORT) ) +#define SDHC_PRSSTAT *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, PRSSTAT) ) +#define SDHC_PROCTL *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, PROCTL ) ) +#define SDHC_SYSCTL *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, SYSCTL ) ) +#define SDHC_IRQSTAT *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, IRQSTAT ) ) +#define SDHC_IRQSTATEN *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, IRQSTATEN ) ) +#define SDHC_IRQSIGEN *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, IRQSIGEN ) ) +#define SDHC_AC12ERR *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, AC12ERR ) ) +#define SDHC_HTCAPBLT *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, HTCAPBLT ) ) +#define SDHC_WML *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, WML ) ) +#define SDHC_FEVT *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, FEVT ) ) +#define SDHC_ADMAES *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, ADMAES ) ) +#define SDHC_ADSADDR *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, ADSADDR ) ) +#define SDHC_VENDOR *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, VENDOR ) ) +#define SDHC_MMCBOOT *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, MMCBOOT ) ) +#define SDHC_HOSTVER *(volatile uint32*)( SDHC_BASE + offsetof( SDHC_Type, HOSTVER ) ) + + + +/* typedefs */ +typedef void LDD_TUserData; +typedef uint8 LDD_TClockConfiguration; +typedef uint32 LDD_TEventMask; +typedef uint32 LDD_TPinMask; +typedef uint32 LDD_TCallbackParam; +typedef void ( *LDD_TCallback )( LDD_TCallbackParam* ); + + +/* enums */ +/* non media specific */ +typedef enum +{ + ERR_OK, + ERR_DISABLED, + ERR_PARAM_MASK, + ERR_PARAM_BUFFER_COUNT, + ERR_PARAM_WIDTH, + ERR_PARAM_ID, + ERR_PARAM_MODE, + ERR_NOTAVAIL, + ERR_BUSY +} LDD_TError; + +typedef enum +{ + DOM_RUN, + DOM_WAIT, + DOM_SLEEP, + DOM_STOP +} LDD_TDriverOperationMode; + +typedef enum +{ + LDD_DRIVER_DISABLED_IN_CLOCK_CONFIGURATION, + LDD_DRIVER_DISABLED_BY_USER, + LDD_DRIVER_BUSY, +} LDD_TDriverState; + +/* SD card specific */ +typedef enum +{ /* Component states */ + LDD_SDHC_DISABLED, + LDD_SDHC_RESET, + LDD_SDHC_IDLE, + LDD_SDHC_VOLTAGE_VALIDATION, + LDD_SDHC_CARD_REGISTRATION, + LDD_SDHC_CARD_SELECTION, + LDD_SDHC_CARD_INFO_RETRIEVAL, + LDD_SDHC_TRANSFER, + LDD_SDHC_ERASION, + LDD_SDHC_IO_REG_TRANSFER, + LDD_SDHC_DATA_WIDTH_SELECTION, + LDD_SDHC_BUS_CLOCK_SELECTION, + LDD_SDHC_WRITE_PROTECTION_SETUP, + LDD_SDHC_WRITE_PROTECTION_RETRIEVAL +} LDD_SDHC_TStatus; + +typedef enum +{ /* Operation completion error codes */ + LDD_SDHC_ERR_OK, /* No error */ + LDD_SDHC_ERR_DMA, /* DMA or block size error */ + LDD_SDHC_ERR_NOT_SUPPORTED, /* Initiated operation is not supported by the card (supported operations are contained in the card information structure) */ + LDD_SDHC_ERR_TIMEOUT, /* Command or data timeout */ + LDD_SDHC_ERR_COMMAND_CRC, /* Command CRC check failed */ + LDD_SDHC_ERR_DATA_CRC, /* Data CRC check failed */ + LDD_SDHC_ERR_ADDRESS_OUT_OF_RANGE, /* The card address is beyond the card capacity */ + LDD_SDHC_ERR_ADDRESS_MISALIGN, /* The card address does not align with physical blocks of the card */ + LDD_SDHC_ERR_BLOCK_LEN_ERROR, /* Block length exceeds the maximum value for the card */ + LDD_SDHC_ERR_WP_VIOLATION, /* Attempt to program a write protected block */ + LDD_SDHC_ERR_CARD_IS_LOCKED, /* The card is locked by the host */ + LDD_SDHC_ERR_WP_ERASE_SKIP, /* Only partial address space was erased due to existing write protected blocks */ + LDD_SDHC_ERR_INTERNAL_FAILURE, /* Internal component error */ + LDD_SDHC_ERR_CARD_FAILURE /* The card was unable to complete the operation */ +} LDD_SDHC_TError; + + + +typedef enum +{ + LDD_SDHC_LOW_VOLTAGE, + LDD_SDHC_HIGH_VOLTAGE +} LDD_SDHC_TVoltage; + + + +typedef enum { + SDHC1_IDLE = 0, + SDHC1_READY = 1, + SDHC1_IDENT = 2, + SDHC1_STAND_BY = 3, + SDHC1_TRANSFER = 4, + SDHC1_SENDING = 5, + SDHC1_RECEIVE = 6, + SDHC1_PROGRAMMING = 7, + SDHC1_DISCONNECT = 8, + SDHC1_BUS_TEST = 9, + SDHC1_SLEEP = 10 +} SDHC1_TCardState; + +typedef enum { /* Card types */ + LDD_SDHC_SD, /* Secure Digital memory card */ + LDD_SDHC_SDIO, /* Secure Digital IO card */ + LDD_SDHC_SDCOMBO, /* Combined Secure Digital memory and IO card */ + LDD_SDHC_MMC, /* MultiMediaCard memory card */ + LDD_SDHC_CE_ATA /* Consumer Electronics ATA card */ +} LDD_SDHC_TCardType; + +typedef enum { /* Transfer operations */ + LDD_SDHC_READ, + LDD_SDHC_WRITE +} LDD_SDHC_TTransferOperation; + +typedef enum { /* Write protection types */ + LDD_SDHC_GROUP, /* Write protection by groups */ + LDD_SDHC_CARD /* Whole card write protection */ +} LDD_SDHC_TWriteProtectType; + +typedef enum { + SDHC1_BUS_CLOCK_390_625kHz, + SDHC1_BUS_CLOCK_12_5MHz, + SDHC1_BUS_CLOCK_25MHz +} SDHC1_TBusClock; + + +/* structure type definitions */ +typedef struct { + bool Initialized; /* Indicates if the structure contains valid card data */ + LDD_SDHC_TCardType Type; /* Card type (see SDHC1_TCardType) */ + uint32_t CID[4]; /* Card ID (from the card) */ + uint16_t RCA; /* Relative card address */ + uint32_t CSD[4]; /* The CSD (card specific data) register value retrieved from the card */ + uint8_t Block[512]; /* The extended CSD (card specific data) or SCR (SD card configuration register) value retrieved from the card */ + uint8_t DataWidths; /* Data widths succeeded in bus test */ + bool HighCapacity; /* Indicates block addressing requirement */ +} SDHC1_TCardInfo; + +typedef struct { + + uint16_t Attributes; /* Transfer buffer attributes */ + uint16_t Length; /* Transfer buffer data length */ + uint32_t Address; /* Transfer buffer data address */ +} SDHC1_TTransferBufferDesc; + +typedef struct { /* Card write protection properties */ + uint16_t GroupSize; /* The size of write protected group in number of erase groups */ + bool Permanent; /* Indicates whether card is permanently write protected (read-only) */ +} LDD_SDHC_TCardWriteProtect; + +typedef struct { /* Card access properties */ + uint16_t MaxBlockLength; /* Max. transferable block length */ + bool MisalignBlock; /* Indicates if the data block can be spread over more than one physical block of the memory device */ + bool PartialBlock; /* Indicates whether partial block sizes can be used in block access */ +} LDD_SDHC_TCardAccess; + +typedef struct { /* Card erasion properties */ + uint16_t SectorSize; /* The size of an erasable unit */ + uint8_t Pattern; /* Memory content after erase */ +} LDD_SDHC_TCardErase; + +typedef struct { /* Transfer buffer descriptor */ + uint16_t Size; /* Buffer data size */ + uint8_t *DataPtr; /* Pointer to buffer data */ +} LDD_SDHC_TBufferDesc; + +typedef struct { /* Card capabilities */ + uint8_t DataWidths; /* Bit mask of supported data bus widths */ + uint8_t Operations; /* Bit mask of supported operations */ + bool HighSpeed; /* Indicates whether the card supports high clock configuration (SD bus clock frequency higher than about 25MHz) */ + bool HighCapacity; /* Indicates whether the card requires block addressing instead of byte addressing */ + bool LowVoltage; /* Indicates whether the card supports the host's low voltage range */ + LDD_SDHC_TCardAccess Read; /* Card data read access capabilities */ + LDD_SDHC_TCardAccess Write; /* Card data write access capabilities */ + LDD_SDHC_TCardErase Erase; /* Card data erasion capabilities */ + LDD_SDHC_TCardWriteProtect WriteProtect; /* Write protection properties */ +} LDD_SDHC_TCardCaps; + +typedef struct { /* Card features description */ + LDD_SDHC_TCardType Type; /* Card type */ + uint16_t BlockLength; /* Physical memory block length */ + uint32_t BlockCount; /* Number of physical memory blocks */ + LDD_SDHC_TCardCaps Caps; /* Card capabilities */ +} LDD_SDHC_TCardInfo; + +/* unusual forward declaration because both + structures contain pointers to the other type! */ +typedef struct LDD_SDHC1_TDeviceData LDD_SDHC1_TDeviceData; +typedef struct LDD_SDHC_TSDData LDD_SDHC_TSDData; + +struct LDD_SDHC_TSDData +{ + LDD_SDHC1_TDeviceData *SDHCPtr; /* SDHC component data */ + //LDD_TDeviceData *GPIOPtr; /* GPIO component data */ + bool Finished; /* Operation end indication */ + bool Inserted; /* Card insertion indication */ + uint8 CardId; /* Initialized card ID */ + LDD_SDHC_TCardInfo CardInfo; /* Initialized card info */ +}; + +struct LDD_SDHC1_TDeviceData +{ + bool Enabled; /* Indicates whether the device is enabled */ + LDD_SDHC_TSDData *UserDataPtr; /* User data structure pointer */ + LDD_TEventMask EventMask; /* Event mask used for run-time enabling and disabling of events */ + LDD_SDHC_TStatus State; /* Main state of the component */ + uint8_t Substate; /* Substate of main state */ + uint8_t CmdState; /* Card command state */ + uint8_t CardId; /* Card ID of the selected card */ + uint8_t NewCardId; /* Card ID actually registered during card registration */ + LDD_SDHC_TCardType CardType; /* Card type actually identified during voltage validation or the type of the selected card */ + bool HighCapacity; /* High capacity card indication. Needed for special initialization of SDHC cards. */ + SDHC1_TCardState CardState; /* State of the selected card */ + bool HighVoltage; /* Indicates whether high bus voltage is currently set */ + uint32_t CardsVoltages; /* Mask of voltages supported by all cards */ + uint16_t RetryCounter; /* Counter for command timeout until give up */ + SDHC1_TCardInfo Cards[SDHC1_MAX_CARD_NUMBER]; /* Card data structures list */ + LDD_SDHC_TError LastError; /* The last error that has occurred during a card operation */ + uint32_t LastErrorAddress; /* Card memory address of the last correctly accessed location before an error has occurred */ + uint8_t TransferTableMem[(SDHC1_BUFFER_TABLE_SIZE * sizeof(SDHC1_TTransferBufferDesc)) + SDHC1_TRANSFER_TABLE_ALIGN]; /* Memory for the transfer buffer descriptors table */ + SDHC1_TTransferBufferDesc *TransferTable; /* Pointer to the transfer buffer descriptors table */ + uint32_t TransferBlockSize; /* Size of buffers to transfer */ + uint32_t TransferBlockCount; /* Number of buffers to transfer */ + LDD_SDHC_TCardInfo *CardInfoPtr; /* Card info structure pointer where to store the result of the GetCardInfo method call */ + LDD_SDHC_TWriteProtectType WriteProtType; /* Write protection type to set */ + uint32_t *WriteProtMaskPtr; /* Write protection mask pointer where to store the result of the GetWriteProtection method call */ + bool WriteProtFlag; /* Write protection flag value to be set */ + LDD_SDHC_TTransferOperation TransferOperation; /* Ongoing transfer operation */ + uint32_t Address; /* Card memory address used in an ongoing operation */ + uint8_t CSDMem[SDHC1_CSD_SIZE + SDHC1_TRANSFER_BUFFER_ALIGN]; /* Buffer for card CSD (card specific data) register programming */ + uint8_t *CSDPtr; /* Aligned CSD (card specific data) register buffer pointer */ + uint8_t BusTestMem[8U + SDHC1_TRANSFER_BUFFER_ALIGN]; /* Bus test result buffer for MMC cards */ + uint8_t *BusTestPtr; /* Aligned pointer to bus test result */ + uint8_t DataWidth; /* Communication data width currently set */ + SDHC1_TBusClock Frequency; /* Bus clock frequency currently set */ + uint32_t ErasionStart; /* Start address of the erased memory range */ + uint32_t ErasionEnd; /* End address of the erased memory range */ + bool Cancel; /* Indicates ongoing operation cancelation */ + LDD_TClockConfiguration SpeedMode; /* Clock configuration currently set */ + bool EnabledMode; /* Indicates whether the device is enabled in the current clock configuration */ +}; + +#define SDHC_PDD_IsSDClockStable( x ) \ +(SDHC_PRSSTAT_SDSTB_MASK == ( SDHC_PRSSTAT & SDHC_PRSSTAT_SDSTB_MASK )) +#define SDHC_PDD_InitCard( x ) \ +{ \ + SDHC_SYSCTL |= SDHC_SYSCTL_RSTA_MASK; \ + SDHC_SYSCTL |= SDHC_SYSCTL_INITA_MASK; \ +} + +#define SDHC_PDD_IsCardInitComplete( x ) \ +( 0 == ( SDHC_SYSCTL & SDHC_SYSCTL_INITA_MASK ) ) + +#define SDHC_PDD_SetCommandArgument( x, y ) \ +( SDHC_CMDARG = y ) + +#define SDHC_PDD_SendCommand( x, y, z ) \ +( SDHC_XFERTYP = ( y << SDHC_XFERTYP_CMDINX_SHIFT ) | z ) \ + +#define PE_LDD_RegisterDeviceStructure( x, y ) \ + +#define PE_LDD_UnregisterDeviceStructure( x, y ) \ + +#define PE_LDD_UnregisterDeviceStructure( x ) \ + +#define SDHC1_OnFinished( x ) \ +( ( x -> Finished = true ) ) + +#define SDHC1_OnCardRemoved( x, y ) + +/* TODO */ +// #define SDHC_PDD_EnableSDHCClock( x, y ) +// if( true == y ) SDHC_SYSCTL |= ( SDHC_SYSCTL_IPGEN_MASK | +// SDHC_SYSCTL_HCKEN_MASK | +// SDHC_SYSCTL_PEREN_MASK | +// SDHC_SYSCTL_SDCLKEN_MASK ); + +#define SDHC_PDD_EnableSDHCClock( x, y ) \ +if( true == y ) SDHC_SYSCTL |= ( SDHC_SYSCTL_SDCLKEN_MASK ); \ +if( false == y ) SDHC_SYSCTL &= ~( SDHC_SYSCTL_SDCLKEN_MASK ) + +#define SDHC1_OnCardInserted( x, y ) \ + +#define SDHC_PDD_SetDataTransferWidth( x, y ) \ +( SDHC_PROCTL = ( SDHC_PROCTL & ~SDHC_PROCTL_DTW_MASK ) | SDHC_PROCTL_DTW( y ) ) + +#define SDHC_PDD_ClearInterruptFlags( x, y ) \ +( SDHC_IRQSTAT = y ) + +#define SDHC_PDD_GetAutoCMD12ErrorFlags( x ) \ +( SDHC_AC12ERR ) + +#define SDHC_PDD_GetCommandResponse( x, y ) \ +( memcpy( (uint32*)&y, (const void*) \ + ( SDHC_BASE + offsetof( SDHC_Type, CMDRSP[0] ) ) , 16 ) ) + +#define SDHC_PDD_GetDMAAddress( x ) \ +( SDHC_DSADDR & SDHC_DSADDR_DSADDR_MASK ) + +#define SDHC_PDD_GetInterruptFlags( x ) \ +( SDHC_IRQSTAT ) + +#define SDHC_PDD_ResetDevice( x ) \ + +#define SDHC_PDD_SetADMAAddress( x, y ) \ +( SDHC_ADSADDR = (uint32)y ) + +#define SDHC_PDD_SetBlockCount( x, y ) \ +( SDHC_BLKATTR = ( SDHC_BLKATTR & ~SDHC_BLKATTR_BLKCNT_MASK ) | \ + SDHC_BLKATTR_BLKCNT( y ) ) + +#define SDHC_PDD_SetBlockSize( x, y ) \ +( SDHC_BLKATTR = ( SDHC_BLKATTR & ~SDHC_BLKATTR_BLKSIZE_MASK ) | \ + SDHC_BLKATTR_BLKSIZE( y ) ) + +#define SDHC_PDD_SetSDHCClockDivisor( x, y ) \ +( SDHC_SYSCTL = ( SDHC_SYSCTL & ~SDHC_SYSCTL_DVS_MASK ) | \ + SDHC_SYSCTL_DVS( y ) ) + +#define SDHC_PDD_SetSDHCClockFrequency( x, y ) \ +( SDHC_SYSCTL = ( SDHC_SYSCTL & ~SDHC_SYSCTL_SDCLKFS_MASK ) | \ + SDHC_SYSCTL_SDCLKFS( y ) ) + + + + + + + + + + + + + + + + + + + +LDD_SDHC1_TDeviceData* SDHC1_Init(LDD_TUserData *UserDataPtr); +/* +** =================================================================== +** Method : SDHC1_Init (component SDHC_LDD) +** +** Description : +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property <"Enable device"> is set to "yes" then the device +** is also enabled (see the description of the method). +** In this case the method is not necessary and need +** not to be generated. This method can be called only once. +** Before the second call of Init the method must be +** called first. +** Parameters : +** NAME - DESCRIPTION +** * UserDataPtr - Pointer to user data +** structure pointer. +** Returns : +** --- - Pointer to the device data structure. +** =================================================================== +*/ + +void SDHC1_Deinit(LDD_SDHC1_TDeviceData *DeviceDataPtr); +/* +** =================================================================== +** Method : SDHC1_Deinit (component SDHC_LDD) +** +** Description : +** Deinitializes the device. Switches off the device, frees the +** device data structure memory, interrupt vectors, etc. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Returns : Nothing +** =================================================================== +*/ + +LDD_TError SDHC1_Enable(LDD_SDHC1_TDeviceData *DeviceDataPtr); +/* +** =================================================================== +** Method : SDHC1_Enable (component SDHC_LDD) +** +** Description : +** Enables the component. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - OK +** =================================================================== +*/ + +LDD_TError SDHC1_Disable(LDD_SDHC1_TDeviceData *DeviceDataPtr); +/* +** =================================================================== +** Method : SDHC1_Disable (component SDHC_LDD) +** +** Description : +** Disables the component. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - OK +** =================================================================== +*/ + +LDD_TError SDHC1_SetEventMask(LDD_SDHC1_TDeviceData *DeviceDataPtr, LDD_TEventMask EventMask); +/* +** =================================================================== +** Method : SDHC1_SetEventMask (component SDHC_LDD) +** +** Description : +** Sets event mask. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** EventMask - Event mask +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - OK +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_PARAM_MASK - Invalid mask (one or more +** event is unmaskable) +** =================================================================== +*/ + +LDD_TEventMask SDHC1_GetEventMask(LDD_SDHC1_TDeviceData *DeviceDataPtr); +/* +** =================================================================== +** Method : SDHC1_GetEventMask (component SDHC_LDD) +** +** Description : +** Returns event mask. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Returns : +** --- - Current event mask. +** =================================================================== +*/ + +LDD_TError SDHC1_DetectCards(LDD_SDHC1_TDeviceData *DeviceDataPtr); +/* +** =================================================================== +** Method : SDHC1_DetectCards (component SDHC_LDD) +** +** Description : +** Detects newly inserted and removed cards. The OnCardInserted +** event will be called for every new card and the +** OnCardRemoved event will be called for every removed card. +** This method should be used when card detection pin is not +** available. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Card detection started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** =================================================================== +*/ + +LDD_TError SDHC1_SelectCard(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint8_t Id); +/* +** =================================================================== +** Method : SDHC1_SelectCard (component SDHC_LDD) +** +** Description : +** Selects a card by its identification number. All further +** operations will apply to this card. Special card +** identification number _NO_CARD will deselect the +** active card. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Id - Card identification number passed by the +** OnCardInserted event parameter. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Card selection started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** ERR_PARAM_ID - Invalid card ID +** =================================================================== +*/ + +LDD_TError SDHC1_GetCardInfo(LDD_SDHC1_TDeviceData *DeviceDataPtr, LDD_SDHC_TCardInfo *InfoPtr); +/* +** =================================================================== +** Method : SDHC1_GetCardInfo (component SDHC_LDD) +** +** Description : +** Returns card information about the selected card. Method +** call starts the card information retrieval process. After +** the card information has been received, the OnFinished event +** is called (the component state changes to idle) and the +** information is stored in the specified variable. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** * InfoPtr - Pointer to a variable, where card +** information will be stored. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Card information retrieval started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** =================================================================== +*/ + +LDD_TError SDHC1_TransferBlocks(LDD_SDHC1_TDeviceData *DeviceDataPtr, LDD_SDHC_TTransferOperation Operation, uint32_t Address, LDD_SDHC_TBufferDesc *BufferDescListPtr, uint16_t BufferDescCount); +/* +** =================================================================== +** Method : SDHC1_TransferBlocks (component SDHC_LDD) +** +** Description : +** Initiates a data block transfer on the selected card. +** Transfer can be a read or write operation depending on the +** transfer operation parameter. Read operation reads data +** blocks from the specified address on a memory card and +** stores their content into buffers specified by the buffer +** descriptor list. Write operation writes data blocks +** specified by the buffer descriptor list to a card memory on +** the specified address. Data blocks should be the same size +** and the block size should be supported by the memory card. +** Buffer addresses should be aligned to a hardware specific +** address boundary. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Operation - Transfer operation +** Address - Card memory address. Byte address +** in case of standard capacity memory cards, +** 512 byte block number in case of high +** capacity memory cards. +** * BufferDescListPtr - Pointer to +** data block buffer descriptor list. +** BufferDescCount - Data block buffer +** descriptor list item count +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Transfer started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** ERR_PARAM_ADDRESS - Invalid buffer address +** (one or more buffer address from the list +** of buffer descriptors is misaligned) +** ERR_PARAM_BUFFER_COUNT - Buffer count +** exceeds the internal buffer table size +** =================================================================== +*/ + +LDD_TError SDHC1_EraseBlocks(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Address, uint32_t Size); +/* +** =================================================================== +** Method : SDHC1_EraseBlocks (component SDHC_LDD) +** +** Description : +** Initiates a memory area erasion on the selected card. Erase +** operation erases a memory area of the specified size from +** the specified address on a memory card. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Address - Address of the beginning of the +** erased area. Byte address in case of +** standard capacity memory card and 512 byte +** block number in case of high capacity +** memory card. +** Size - Size of the erased area. Byte size in +** case of standard capacity memory card and +** 512 byte blocks count in case of high +** capacity memory card. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Erasing started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** =================================================================== +*/ + +LDD_TError SDHC1_SetDataWidth(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint8_t Width); +/* +** =================================================================== +** Method : SDHC1_SetDataWidth (component SDHC_LDD) +** +** Description : +** Initiates a data width setup. The card has to support the +** specified data width. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Width - Data bus bit count. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Setup started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** ERR_PARAM_WIDTH - Invalid data width +** =================================================================== +*/ + +LDD_TError SDHC1_SelectBusClock(LDD_SDHC1_TDeviceData *DeviceDataPtr, SDHC1_TBusClock Frequency); +/* +** =================================================================== +** Method : SDHC1_SelectBusClock (component SDHC_LDD) +** +** Description : +** Initiates a SD bus clock frequency change. If the frequency +** is for high speed mode, initiates a high speed mode setup on +** the selected card. The card has to support the specified bus +** clock frequency. This method is enabled only if a list of +** bus clock frequencies is specified. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Frequency - Bus clock frequency identifier. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Setup started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** =================================================================== +*/ + +LDD_TError SDHC1_SetVoltage(LDD_SDHC1_TDeviceData *DeviceDataPtr, LDD_SDHC_TVoltage Voltage); +/* +** =================================================================== +** Method : SDHC1_SetVoltage (component SDHC_LDD) +** +** Description : +** Initiates a bus voltage change. The card has to support the +** specified voltage. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Voltage - Voltage identifier. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Setup started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** =================================================================== +*/ + +LDD_TError SDHC1_SetWriteProtection(LDD_SDHC1_TDeviceData *DeviceDataPtr, LDD_SDHC_TWriteProtectType Type, uint32_t Address, bool Protected); +/* +** =================================================================== +** Method : SDHC1_SetWriteProtection (component SDHC_LDD) +** +** Description : +** Initiates a write protection setup for the selected card. If +** the write protection type is LDD_SDHC_GROUP, write +** protection will be set for the addressed write protection +** group. Write protection group size is contained within the +** card information structure. If the write protection type is +** LDD_SDHC_CARD, write protection will be set for the whole +** card and the address parameter will be ignored. Only a whole +** card write protection clear can remove this protection. The +** card has to support write protection. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Type - Write protection type. +** Address - Address of the write protection +** group, if the write protection type is +** LDD_SDHC_GROUP. Byte address in case of +** standard capacity memory card and 512 byte +** block number in case of high capacity +** memory card. +** Protected - Indicates whether the +** addressed write protection group or card +** should be write protected or not. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Setup started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** =================================================================== +*/ + +LDD_TError SDHC1_GetWriteProtection(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t Address, uint32_t *MaskPtr); +/* +** =================================================================== +** Method : SDHC1_GetWriteProtection (component SDHC_LDD) +** +** Description : +** Initiates a write protection mask retrieval for the selected +** card. After the mask has been received, the OnFinished event +** is called and the mask is stored in the specified variable. +** The returned mask contains a bit mask of write protected +** write protection groups starting at the specified address. +** The least significant bit represents the status of the first +** write protection group. Bits of write protection groups out +** of range are cleared. The card has to support write +** protection. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Address - Address of the write protection +** group. Byte address in case of standard +** capacity memory card and 512 byte block +** number in case of high capacity memory card. +** * MaskPtr - Pointer to a variable, where the +** write protection groups status mask will be +** stored. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Write protection mask retrieval +** started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_BUSY - Another card operation is in +** progress +** =================================================================== +*/ + +LDD_TError SDHC1_CancelOperation(LDD_SDHC1_TDeviceData *DeviceDataPtr); +/* +** =================================================================== +** Method : SDHC1_CancelOperation (component SDHC_LDD) +** +** Description : +** Initiates a cancelation of the ongoing operation. The +** OnFinished event will be called for the stopped operation. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - Operation cancelation started +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_NOTAVAIL - No operation is in progress +** =================================================================== +*/ + +LDD_SDHC_TStatus SDHC1_GetStatus(LDD_SDHC1_TDeviceData *DeviceDataPtr); +/* +** =================================================================== +** Method : SDHC1_GetStatus (component SDHC_LDD) +** +** Description : +** Returns the current component status, specifying the ongoing +** operation. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** Returns : +** --- - Component status. +** =================================================================== +*/ + +LDD_SDHC_TError SDHC1_GetError(LDD_SDHC1_TDeviceData *DeviceDataPtr, uint32_t *AddressPtr); +/* +** =================================================================== +** Method : SDHC1_GetError (component SDHC_LDD) +** +** Description : +** Returns the last error code and the memory address where the +** error occurred (if applicable). +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to the device +** data structure. +** * AddressPtr - Pointer to a variable, where +** the error address will be stored. +** Returns : +** --- - The last error code. +** =================================================================== +*/ + +LDD_TError SDHC1_ConnectPin(LDD_SDHC1_TDeviceData *DeviceDataPtr, LDD_TPinMask PinMask); +/* +** =================================================================== +** Method : SDHC1_ConnectPin (component SDHC_LDD) +** +** Description : +** This method reconnects the requested pins associated with +** the selected peripheral in the component. This method is +** only available for CPU derivatives and peripherals that +** support the runtime pin sharing with other internal on-chip +** peripherals. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Pointer to device data +** structure. +** PinMask - Mask for the requested pins. The +** peripheral pins are reconnected according +** to this mask. +** Returns : +** --- - +** Error code, possible values: +** ERR_OK - OK +** ERR_PARAM_MASK - Invalid pin mask +** =================================================================== +*/ + +LDD_TError SDHC1_SetOperationMode(LDD_SDHC1_TDeviceData *DeviceDataPtr, LDD_TDriverOperationMode OperationMode, LDD_TCallback ModeChangeCallback, LDD_TCallbackParam *ModeChangeCallbackParamPtr); +/* +** =================================================================== +** Method : SDHC1_SetOperationMode (component SDHC_LDD) +** +** Description : +** This method requests to change the component's operation +** mode. Upon a request to change the operation mode, the +** component will finish a pending job first and then notify a +** caller that an operation mode has been changed. When no job +** is pending (ERR_OK), the component changes an operation mode +** immediately and notify a caller about this change. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Device data structure +** pointer returned by Init method. +** OperationMode - Requested driver +** operation mode. +** ModeChangeCallback - Callback to +** notify the upper layer once a mode has been +** changed. +** * ModeChangeCallbackParamPtr +** - Pointer to callback parameter to notify +** the upper layer once a mode has been +** changed. +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_DISABLED - The component is disabled +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_PARAM_MODE - Invalid operation mode +** ERR_BUSY - A job is pending +** =================================================================== +*/ + +LDD_TDriverState SDHC1_GetDriverState(LDD_SDHC1_TDeviceData *DeviceDataPtr); +/* +** =================================================================== +** Method : SDHC1_GetDriverState (component SDHC_LDD) +** +** Description : +** This method returns the current driver status. +** Parameters : +** NAME - DESCRIPTION +** * DeviceDataPtr - Device data structure +** pointer returned by Init method. +** Returns : +** --- - +** The current driver status mask. The +** following status masks defined in PE_LDD.h +** can be used to check the current driver +** status: +** PE_LDD_DRIVER_DISABLED_IN_CLOCK_CONFIGURATION - +** Driver is disabled in the current speed +** mode +** PE_LDD_DRIVER_DISABLED_BY_USER - Driver is +** disabled by the user +** PE_LDD_DRIVER_BUSY - Driver is in the BUSY +** state +** =================================================================== +*/ + +/* {FreeRTOS RTOS Adapter} ISR function prototype */ +//PE_ISR(SDHC1_Interrupt); +/* +** =================================================================== +** Method : SDHC1_Interrupt (component SDHC_LDD) +** +** Description : +** The method services the interrupt of the selected peripheral(s) +** and eventually invokes event(s) of the component. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +/* END SDHC1 */ + +#endif +/* ifndef SDHC1_H */ +/* +** ################################################################### +** +** This file was created by Processor Expert 5.3 [05.01] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/source/Peripherals/SDHCHA.c b/source/Peripherals/SDHCHA.c new file mode 100644 index 0000000..51e0640 --- /dev/null +++ b/source/Peripherals/SDHCHA.c @@ -0,0 +1,213 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: SDHC */ +/* DESCRIPTION: This code provides setup and functions for the SDHC */ +/* hardware module */ +/* FILE NAME: SDHC.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include "types.h" +#include "CPUAbstract.h" +#include "regset.h" +#include "declarations.h" +#include "OS.h" +#include "disk.h" +#include "sdhc.h" +#include "SDHCHA.h" +#include "timer.h" +#include "sim.h" + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +#include "sdhc1ha.h" +#endif //BUILD_MK6X + +const REGSET_tstReg32Val SDHCHA_rastSDHCReg32HWInitVal[] = SDHCHA_nReg32HWInitSet; +const REGSET_tstReg32Val SDHCHA_rastSDHCReg32HWDeInitVal[] = SDHCHA_nReg32HWDeInitSet; +bool SDHCHA_boTimeout; +uint8 SDHCHA_au8SectorBuffer[SDHCHA_nSectorSize]; + +SDHCHA_tstSDData stSDData; + +#if defined(BUILD_MK60) +static void SDHC_vWait(LDD_SDHC_TSDData*, bool*); +#endif //BUILD_MK6X + +void SDHCHA_vStart(uint32* const u32Stat) +{ + //REGSET_vInitReg32(&SDHC_rastSDHCReg32HWInitVal[0]); + //stSDData.SDHCPtr = SDHC1_Init(NULL); + OS_xModuleStartOK(*u32Stat); + //SDHCHA_vCardInitialise(); +} + +void SDHCHA_vRun(uint32* const u32Stat) +{ +#ifdef BUILD_MK60 + SDHCHA_tstBufferDesc stBufferDesc; + static uint32 u32Sector = 0x10a00; + + stBufferDesc.DataPtr = (uint8*)&SDHC_au8SectorBuffer; + stBufferDesc.Size = SDHCHA_nSectorSize; + + //enError = SDHC1_TransferBlocks(stSDData.SDHCPtr, SDHC_nTransferReadOperation, u32Sector, &stBufferDesc, 1); + + if(0 == SDHC_au8SectorBuffer[511]) + { + u32Sector += 0x200; + } +#endif //BUILD_MK60 + /* TODO suppress warning */ + //(void)stBufferDesc; +} + +void SDHCHA_vTerminate(uint32* const u32Stat) +{ + +} + +void SDHCHA_vHWInit(void) +{ + REGSET_vInitReg32(&SDHCHA_rastSDHCReg32HWInitVal[0]); +} + +void SDHCHA_vHWDeInit(void) +{ + REGSET_vInitReg32(&SDHCHA_rastSDHCReg32HWDeInitVal[0]); +} + +uint8 SDHCHA_u8DiskRead(uint8* const pu8Buf, const uint32 u32Sector, const uint16 u16SectorCount) +{ +#ifdef BUILD_MK60 + SDHCHA_tenError enError; + SDHCHA_tstBufferDesc stBufferDesc; + + stBufferDesc.DataPtr = pu8Buf; + stBufferDesc.Size = SDHCHA_nSectorSize * u16SectorCount; + + enError = SDHC1_TransferBlocks(stSDData.SDHCPtr, SDHCHA_nTransferReadOperation, u32Sector, &stBufferDesc, 1); + + while(LDD_SDHC_TRANSFER == stSDData.SDHCPtr->State){}; +#endif //BUILD_MK60 + + /* TODO suppress warning */ + //(void)enError; + return 0; +} + +uint8 SDHCHA_u8DiskWrite(uint8* const pu8Buf, const uint32 u32Sector, const uint16 u16SectorCount) +{ + return 0; +} + + +#ifdef BUILD_MK60 +static void SDHCHA_vWait(LDD_SDHC_TSDData* pstSDData, bool* pboErrorFlag) +{ + LDD_SDHC_TError enError; + + (void)TIMER_vConfigureAlarm(SDHC_nWaitTimeoutMs, SHDC_vWaitTimeoutCB); + + while(!pstSDData->Finished && !SDHC_boTimeout); + + pstSDData->Finished = FALSE; + + enError = SDHC1_GetError(pstSDData->SDHCPtr, NULL); + + if (enError != LDD_SDHC_ERR_OK) { + //SD_ErrorHandler(SD, Error); + *pboErrorFlag = TRUE; + } +} +#endif //BUILD_MK60 + +void SHDC_vWaitTimeoutCB(void) +{ + SDHCHA_boTimeout = true; +} + +#ifdef BUILD_MK60 +static void SDHCHA_vCardInitialise(void) +{ + + bool boError = FALSE; + MPU_Type* pstMPU = MPU; + + /* disable memory protection - DMA is used in SD Card init */ + pstMPU -> CESR = 0; + + //MATTHEW + stSDData.Inserted = true; + + /* turn on DMAMUX clock */ + SIM_vSetReg32(SIM_SCGC6, SIM_SCGC6_DMAMUX0_MASK); + + if(!boError && stSDData.Inserted) + { +// if(NULL != stSDData.SDHCPtr) +// { +// SDHC1_Deinit(stSDData.SDHCPtr); +// stSDData.SDHCPtr = SDHC1_Init(NULL); +// SDHC_vWait(&stSDData, &boError); +// } +// else + { + stSDData.SDHCPtr = SDHC1_Init(&stSDData); + SDHC_vWait(&stSDData, &boError); + } + + if(SDHC1_DetectCards(stSDData.SDHCPtr) != ERR_OK) + { + boError = TRUE; + } + + SDHC_vWait(&stSDData, &boError); + + if (!boError && stSDData.CardId != SDHC1_NO_CARD) + { + /* card detected - selecting card... */ + if (SDHC1_SelectCard(stSDData.SDHCPtr, stSDData.CardId) != ERR_OK) + { + boError = TRUE; + } + SDHC_vWait(&stSDData, &boError); + } + + if (!boError) + { + /* card selected - requesting card info... */ + if (SDHC1_GetCardInfo(stSDData.SDHCPtr, &stSDData.CardInfo) != ERR_OK) + { + boError = TRUE; + } + SDHC_vWait(&stSDData, &boError); + } + + if (!boError) + { + /* card info obtained - set faster bus speed */ + if (SDHC1_SelectBusClock(stSDData.SDHCPtr, SDHC_tenSDHCBusClock12_5MHz) != ERR_OK) + { + boError = TRUE; + } + SDHC_vWait(&stSDData, &boError); + } + } + if (!boError) { + if (stSDData.CardInfo.Caps.DataWidths&SDHC_nCardDataWidth8Bit) { + boError = SDHC1_SetDataWidth(stSDData.SDHCPtr, SDHC_nCardDataWidth8Bit)!=ERR_OK; + } else if (stSDData.CardInfo.Caps.DataWidths&SDHC_nCardDataWidth4Bit) { + boError = SDHC1_SetDataWidth(stSDData.SDHCPtr, SDHC_nCardDataWidth4Bit)!=ERR_OK; + } else if (stSDData.CardInfo.Caps.DataWidths&SDHC_nCardDataWidth1Bit) { + boError = SDHC1_SetDataWidth(stSDData.SDHCPtr, SDHC_nCardDataWidth1Bit)!=ERR_OK; + } + SDHC_vWait(&stSDData, &boError); + /* selected highest possible data width */ + } +} +#endif //BUILD_MK60 + diff --git a/source/Peripherals/SDHCHA.h b/source/Peripherals/SDHCHA.h new file mode 100644 index 0000000..4d57fa5 --- /dev/null +++ b/source/Peripherals/SDHCHA.h @@ -0,0 +1,164 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: SDHC Header File */ +/* DESCRIPTION: This code provides macros for setup and control of the */ +/* SDHC hardware module */ +/* FILE NAME: SDHC.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef SDHCHA_H +#define SDHCHA_H + +#include +#include +#include +#include "disk.h" + + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +#define SDHCHA_nReg32HWInitSet \ +{ \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[ 0])), (uint32)~(PORT_PCR_ISF_MASK | PORT_PCR_MUX_MASK), REGSET_enAnd }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[ 0])), (uint32)(PORT_PCR_MUX(4) | PORT_PCR_PS_MASK | PORT_PCR_PE_MASK | PORT_PCR_DSE_MASK), REGSET_enOr }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[ 1])), (uint32)~(PORT_PCR_ISF_MASK | PORT_PCR_MUX_MASK), REGSET_enAnd }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[ 1])), (uint32)(PORT_PCR_MUX(4) | PORT_PCR_PS_MASK | PORT_PCR_PE_MASK | PORT_PCR_DSE_MASK), REGSET_enOr }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[ 2])), (uint32)~(PORT_PCR_ISF_MASK | PORT_PCR_MUX_MASK), REGSET_enAnd }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[ 2])), (uint32)PORT_PCR_MUX(4), REGSET_enOr }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[ 3])), (uint32)~(PORT_PCR_ISF_MASK | PORT_PCR_MUX_MASK), REGSET_enAnd }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[ 3])), (uint32)(PORT_PCR_MUX(4) | PORT_PCR_PS_MASK | PORT_PCR_PE_MASK | PORT_PCR_DSE_MASK), REGSET_enOr }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[ 4])), (uint32)~(PORT_PCR_ISF_MASK | PORT_PCR_MUX_MASK), REGSET_enAnd }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[ 4])), (uint32)(PORT_PCR_MUX(4) | PORT_PCR_PS_MASK | PORT_PCR_PE_MASK | PORT_PCR_DSE_MASK), REGSET_enOr }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[ 5])), (uint32)~(PORT_PCR_ISF_MASK | PORT_PCR_MUX_MASK), REGSET_enAnd }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[ 5])), (uint32)(PORT_PCR_MUX(4) | PORT_PCR_PS_MASK | PORT_PCR_PE_MASK | PORT_PCR_DSE_MASK), REGSET_enOr }, \ + { NULL, 0, REGSET_enOverwrite } \ +}; +#endif //BUILD_MK6X + + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +#define SDHCHA_nReg32HWDeInitSet \ +{ \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[ 6])), (uint32)PORT_PCR_MUX(1), REGSET_enOverwrite }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[ 7])), (uint32)PORT_PCR_MUX(1), REGSET_enOverwrite }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[ 8])), (uint32)PORT_PCR_MUX(1), REGSET_enOverwrite }, \ + { (volatile uint32*)(PORTE_BASE + offsetof(PORT_Type, PCR[26])), (uint32)PORT_PCR_MUX(1), REGSET_enOverwrite }, \ + { NULL, 0, REGSET_enOverwrite } \ +}; +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E +#define SDHCHA_nReg32HWDeInitSet \ +{ \ + { NULL, 0, REGSET_enOverwrite } \ +}; +#endif //BUILD_SAM3X8E + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +/* command opcode macros */ +#define SDHCHA_nCMD0_GO_IDLE_STATE 0u +#define SDHCHA_nCMD1_MMC_SEND_OP_COND 1u +#define SDHCHA_nCMD2_ALL_SEND_CID 2u +#define SDHCHA_nCMD3_SET_RELATIVE_ADDR 3u +#define SDHCHA_nCMD6_SWITCH 6u +#define SDHCHA_nCMD7_SELECT_CARD 7u +#define SDHCHA_nCMD8_SEND_EXT_CSD 8u +#define SDHCHA_nCMD9_SEND_CSD 9u +#define SDHCHA_nCMD12_STOP_TRANS 12u +#define SDHCHA_nCMD13_SEND_STATUS 13u +#define SDHCHA_nCMD14_BUS_TEST_READ 14u +#define SDHCHA_nCMD16_SET_BLOCKLEN 16u +#define SDHCHA_nCMD17_READ_SINGLE_BLOCK 17u +#define SDHCHA_nCMD18_READ_MULTIPLE_BLOCK 18u +#define SDHCHA_nCMD19_BUS_TEST_WRITE 19u +#define SDHCHA_nCMD24_WRITE_BLOCK 24u +#define SDHCHA_nCMD25_WRITE_MULTIPLE_BLOCK 25u +#define SDHCHA_nCMD27_PROGRAM_CSD 27u +#define SDHCHA_nCMD28_SET_WRITE_PROT 28u +#define SDHCHA_nCMD29_CLR_WRITE_PROT 29u +#define SDHCHA_nCMD30_SEND_WRITE_PROT 30u +#define SDHCHA_nCMD32_TAG_SECTOR_START 32u +#define SDHCHA_nCMD33_TAG_SECTOR_END 33u +#define SDHCHA_nCMD35_TAG_ERASE_GROUP_START 35u +#define SDHCHA_nCMD36_TAG_ERASE_GROUP_END 36u +#define SDHCHA_nCMD38_ERASE 38u +#define SDHCHA_nCMD55_APP_CMD 55u +/* application command opcode macros */ +#define SDHCHA_nACMD6_SET_BUS_WIDTH 6u +#define SDHCHA_nACMD41_SEND_OP_COND 41u +#define SDHCHA_nACMD51_MMC_SEND_SCR 51u +/* XFERTYP bit macros */ +#define SDHCHA_nRESPONSE_NIL 0x0 << SDHC_XFERTYP_RSPTYP_SHIFT +#define SDHCHA_nRESPONSE_136 0x1 << SDHC_XFERTYP_RSPTYP_SHIFT +#define SDHCHA_nRESPONSE_48 0x2 << SDHC_XFERTYP_RSPTYP_SHIFT +#define SDHCHA_nRESPONSE_48_BUSY 0x3 << SDHC_XFERTYP_RSPTYP_SHIFT +#define SDHCHA_nENABLE_DMA SDHC_XFERTYP_DMAEN_MASK +#define SDHCHA_nDATA_PRESENT SDHC_XFERTYP_DPSEL_MASK +#define SDHCHA_nDATA_READ SDHC_XFERTYP_DTDSEL_MASK +#define SDHCHA_nDATA_WRITE 0x0 +#define SDHCHA_nENABLE_BLOCK_COUNT SDHC_XFERTYP_BCEN_MASK +#define SDHCHA_nENABLE_AUTO_CMD12 SDHC_XFERTYP_AC12EN_MASK +#define SDHCHA_nMULTIPLE_BLOCK SDHC_XFERTYP_MSBSEL_MASK +/* IRQSTAT bit macros */ +#define SDHCHA_nDATA_TIMEOUT_ERROR_INT SDHC_IRQSTAT_DTOE_MASK +#define SDHCHA_nDATA_END_BIT_ERROR_INT SDHC_IRQSTAT_DEBE_MASK +#define SDHCHA_nDATA_CRC_ERROR_INT SDHC_IRQSTAT_DCE_MASK +#define SDHCHA_nCOMMAND_TIMEOUT_ERROR_INT SDHC_IRQSTAT_CTOE_MASK +#define SDHCHA_nCOMMAND_CRC_ERROR_INT SDHC_IRQSTAT_CCE_MASK +#define SDHCHA_nCOMMAND_END_BIT_ERROR_INT SDHC_IRQSTAT_CEBE_MASK +#define SDHCHA_nCOMMAND_INDEX_ERROR_INT SDHC_IRQSTAT_CIE_MASK +#define SDHCHA_nDMA_ERROR_INT SDHC_IRQSTAT_DMAE_MASK +#define SDHCHA_nCOMMAND_COMPLETE_INT SDHC_IRQSTAT_CC_MASK +#define SDHCHA_nTRANSFER_COMPLETE_INT SDHC_IRQSTAT_TC_MASK +#define SDHCHA_nBUFFER_READ_READY_INT SDHC_IRQSTAT_BRR_MASK +#define SDHCHA_nBUFFER_WRITE_READY_INT SDHC_IRQSTAT_BWR_MASK +/* AC12ERR bit macros */ +#define SDHCHA_nAUTO_CMD12_CRC_ERROR SDHC_AC12ERR_AC12CE_MASK +#define SDHCHA_nAUTO_CMD12_END_BIT_ERROR SDHC_AC12ERR_AC12EBE_MASK +#define SDHCHA_nAUTO_CMD12_INDEX_ERROR SDHC_AC12ERR_AC12IE_MASK +#define SDHCHA_nAUTO_CMD12_ERROR_INT SDHC_AC12ERR_AC12NE_MASK +#define SDHCHA_nAUTO_CMD12_TIMEOUT_ERROR SDHC_AC12ERR_AC12TOE_MASK + +#define SDHC1_NO_RESPONSE 0U +#define SDHC1_CSD_SIZE 16U /* Card specific data register size */ +#define SDHC1_EXT_CSD_SIZE 512U /* Extended card specific data register size */ +#define SDHC1_SCR_SIZE 8U /* SD card configuration register size */ +#define SDHC1_SFS_SIZE 64U /* Switch function statuses register size */ + +typedef struct LDD_SDHC_TSDData LDD_SDHC_TSDData; + +/* redefines of sdhc1 macros */ +#define SDHCHA_nSectorSize SDHC1_EXT_CSD_SIZE +#define SDHCHA_nTransferReadOperation LDD_SDHC_READ +#define SDHCHA_tstBufferDesc LDD_SDHC_TBufferDesc +#define SDHCHA_tenError LDD_TError +#define SDHCHA_tstSDData LDD_SDHC_TSDData +#define SDHCHA_tenSDHCBusClock12_5MHz SDHC1_BUS_CLOCK_12_5MHz +#define SDHCHA_nCardDataWidth8Bit LDD_SDHC_CARD_DATA_WIDTH_8_BIT +#define SDHCHA_nCardDataWidth4Bit LDD_SDHC_CARD_DATA_WIDTH_4_BIT +#define SDHCHA_nCardDataWidth1Bit LDD_SDHC_CARD_DATA_WIDTH_1_BIT +/**/ +#define SDHCHA_n1_BIT_MODE 0x0 +#define SDHCHA_n4_BIT_MODE 0x1 +#define SDHCHA_n8_BIT_MODE 0x2 +/* timeouts */ +#define SDHC_nWaitTimeoutMs 100u +#define SDHC_nTransferTimeoutExponent 14u +#define SDHCHA_nWaitTimeoutMs 100u +#define SDHCHA_nTransferTimeoutExponent 14u +#endif //BUILD_MK6X + +void SDHCHA_vStart(uint32* const); +void SDHCHA_vRun(uint32* const); +void SDHCHA_vTerminate(uint32* const); +void SDHCHA_vHWInit(void); +void SDHCHA_vHWDeInit(void); +uint8 SDHCHA_u8DiskRead(uint8* const, const uint32, const uint16); +uint8 SDHCHA_u8DiskWrite(uint8* const, const uint32, const uint16); +void SHDCHA_vWaitTimeoutCB(void); + +#endif //SDHCHA_H + diff --git a/source/Peripherals/SPIHA.c b/source/Peripherals/SPIHA.c new file mode 100644 index 0000000..3caea56 --- /dev/null +++ b/source/Peripherals/SPIHA.c @@ -0,0 +1,351 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include "SPIHA.h" + + +const REGSET_tstReg8Val SPIHA_rastPIMReg8ValSPI0[] = SPIHA_nReg8SetSPI0; +const REGSET_tstReg8Val SPIHA_rastPIMReg8ValSPI1[] = SPIHA_nReg8SetSPI1; +const SPIHA_tstDivisorMap SPIHA_rastDivisorMap[] = SPIHA_nDivisorMap; +IOAPI_tstTransferCB* SPIHA_pstTransferCB; +uint32 SPIHA_u32BytesToTransfer; +void* SPIHA_pvData; +IOAPI_tpfTransferCB SPIHA_pfCB; +tstSPIModule* SPIHA_pstSPI; + +uint32 SPI_u32PortClockRequested; + +static sint32 SPIHA_u32GetSPIIndex(IOAPI_tenEHIOResource); + +void SPIHA_vStart(puint32 const u32Stat) +{ + SPIHA_pfCB = NULL; + SPIHA_pstSPI = NULL; + SPIHA_u32BytesToTransfer = 0; + OS_xModuleStartOK(*u32Stat); +} + +void SPIHA_vRun(puint32 const pu32Stat) +{ + +} + +void SPIHA_vTerminate(puint32 const pu32Stat) +{ + +} + +uint32 SPIHA_u32InitBus(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tstPortConfigCB* pstPortConfigCB) +{ + uint32 u32MuxSel = ~0; + sint32 i32IDX = SPIHA_u32GetSPIIndex(enEHIOResource); + + if ((-1 != i32IDX) && (TRUE == DLL_boInitDLLChannel(enEHIOResource, pstPortConfigCB))) + { +#ifdef BUILD_MK60 + tstSPIModule* pstSPI; + IRQn_Type enIRQType; + REGSET_tstReg32Val SPI_astSPIReg32Val[3]; + uint32 u32Mul; + uint32 u32DivCalc; + uint32 u32Div; + uint32 u32DivMapIDX; + + switch (enEHIOResource) + { + case EH_VIO_SPI1: + { + SPI_xRequestPortClock(SIM_SCGC4_SPI0_MASK); + + SPI_astSPIReg32Val[0].reg = (vpuint32)(PORTD_BASE + offsetof(PORT_Type, PCR[8])); + SPI_astSPIReg32Val[0].val = (uint32)(PORT_PCR_MUX(2) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK); + SPI_astSPIReg32Val[0].writeMode = REGSET_enOverwrite; + + SPI_astSPIReg32Val[1].reg = (vpuint32)(PORTD_BASE + offsetof(PORT_Type, PCR[9])); + SPI_astSPIReg32Val[1].val = (uint32)(PORT_PCR_MUX(2) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK); + SPI_astSPIReg32Val[1].writeMode = REGSET_enOverwrite; + + SPI_astSPIReg32Val[2].reg = NULL; + REGSET_vInitReg32(&SPI_astSPIReg32Val[0]); + + enSVCResult = SYSAPI_enBaudRateUnavailable; + pstSPI = I2C0; + + SPI_xRequestPortClock(SIM_SCGC4_SPI0_MASK); + u32Mul = pstPortConfigCB->u32BaudRateHz / (SYS_FREQ_BUS / SPI_rastDivisorMap[0].u32SCLDivider); + u32Mul = (4 < u32Mul) ? 4 : u32Mul; + + switch (u32Mul) + { + case 0: u32Mul = 1; break; + case 3: u32Mul = 2; break; + default: u32Mul = 4; break; + } + + u32DivCalc = SYS_FREQ_BUS / (u32Mul * pstPortConfigCB->u32BaudRateHz); + + if (SPI_rastDivisorMap[63].u32SCLDivider < u32DivCalc) break; + enSVCResult = SYSAPI_enOK; + + SPI_xCalcDivisor; + enIRQType = I2C0_IRQn; + + pstSPI->F = (I2C_F_MULT(u32Mul) | I2C_F_ICR(u32Div)); + pstSPI->C1 |= I2C_C1_SPIEN_MASK; + IRQ_vEnableIRQ(enIRQType); + break; + } + case EH_VIO_SPI2: + { + SPI_xRequestPortClock(SIM_SCGC4_SPI1_MASK); + break; + } + default: + { + break; + } + } +#endif //BUILD_MK60 + +#ifdef BUILD_SAM3X8E + Spi* pstSPIModule = NULL; + u32MuxSel = 0; + + switch (pstPortConfigCB->enVIOResource) + { + case EH_VIO_SPI1: + { + pstSPIModule = SPI0; + break; + } + default: + { + break; + } + } + + if (NULL != pstPortConfigCB) + { + spi_enable_clock(pstSPIModule);//matthew non standard clock setup + spi_reset(pstSPIModule); + spi_set_master_mode(pstSPIModule); + spi_disable_mode_fault_detect(pstSPIModule); + spi_disable_loopback(pstSPIModule); + spi_set_peripheral_chip_select_value(pstSPIModule, spi_get_pcs(SPIHA_nDeviceID)); + spi_set_fixed_peripheral_select(pstSPIModule); + spi_disable_peripheral_select_decode(pstSPIModule); + spi_set_delay_between_chip_select(pstSPIModule, 0); + + spi_set_transfer_delay(pstSPIModule, SPIHA_nDeviceID, 0, 0); + spi_set_bits_per_transfer(pstSPIModule, SPIHA_nDeviceID, SPIHA_nBitCount); + spi_set_baudrate_div(pstSPIModule, SPIHA_nDeviceID, SPIHA_xSPIBaudRateDivider(pstPortConfigCB->u32BaudRateHz)); + spi_configure_cs_behavior(pstSPIModule, SPIHA_nDeviceID, SPI_CS_KEEP_LOW); + + spi_set_clock_polarity(pstSPIModule, SPIHA_nDeviceID, pstPortConfigCB->stPinConfig.uPinInfo.stSPIPinInfo.boClockIdleHigh); + spi_set_clock_phase(pstSPIModule, SPIHA_nDeviceID, pstPortConfigCB->stPinConfig.uPinInfo.stSPIPinInfo.boShiftRising); + spi_enable(pstSPIModule); + spi_enable_interrupt(pstSPIModule, SPI_IER_TDRE); + IRQ_vEnableIRQ(SPI0_IRQn, IRQ_enPRIO_15, SPI_vInterrupt, NULL);//matthew this could be moved out of HAL is generic CMx! + } +#endif //BUILD_SAM3X8E + } + return u32MuxSel; +} + +void SPIHA_vInitTransfer(IOAPI_tstTransferCB* pstTransferCB) +{ +#ifdef BUILD_MK60 + SPIHA_pstTransferCB = pstTransferCB; + tstSPIModule* pstSPIModule = NULL; + bool boTemp; + volatile uint32 u32Count; + + switch (pstTransferCB->enEHIOResource) + { + case EH_VIO_SPI1: + { + /* TODO */ + //SPIHA_pstSPI = I2C0; + //SPIHA_u32BytesToTransfer = pstTransferCB->u32ByteCount - 1; + //SPIHA_pfCB = pstTransferCB->pfCB; + //SPIHA_pvData = pstTransferCB->pvData; + //SPIHA_pstSPI->C1 |= (I2C_C1_TX_MASK | I2C_C1_SPIIE_MASK | I2C_C1_MST_MASK); + //SPIHA_pstSPI->D = *(uint8*)SPI_pvData; + //SPIHA_pvData = (void*)((uint32)SPI_pvData + 1); + } + default: + { + break; + } + } +#endif //BUILD_MK60 + +#ifdef BUILD_SAM3X8E + switch (pstTransferCB->enEHIOResource) + { + case EH_VIO_SPI1: + { + pstSPIModule = SPI0; + } + default: + { + break; + } + } + + if (NULL != pstSPIModule) + { + SPIHA_pstSPI = SPI0; + SPIHA_u32BytesToTransfer = pstTransferCB->u32ByteCount - 1; + SPIHA_pfCB = pstTransferCB->pfCB; + SPIHA_pvData = pstTransferCB->pvData; + + if (TRUE == pstTransferCB->boBlockingMode) + { + for (u32Count = 0; u32Count < 250; u32Count++) + { + __asm("nop"); + } + } + + spi_write(pstSPIModule, (uint16)*(puint8)pstTransferCB->pvData, 0, 0); + + if (TRUE == pstTransferCB->boBlockingMode) + { + while (0 < SPIHA_u32BytesToTransfer) + { + for (u32Count = 0; u32Count < 250; u32Count++) + { + __asm("nop"); + } + + SPIHA_pvData = (void*)((uint32)SPIHA_pvData + 1); + spi_write(pstSPIModule, (uint16)*(puint8)SPIHA_pvData, 0, 0); + SPIHA_u32BytesToTransfer--; + } + + for (u32Count = 0; u32Count < 250; u32Count++) + { + __asm("nop"); + } + } + else + { + SPIHA_pvData = (void*)((uint32)SPIHA_pvData + 1); + spi_enable_interrupt(pstSPIModule, SPI_SR_TDRE); + } + } +#endif //BUILD_SAM3X8E +} + +void SPIHA_vInterruptHandler(IOAPI_tenEHIOResource enEHIOResource) +{ +#ifdef BUILD_MK60 + IOAPI_tenPortMode enMode; + tstSPIModule* pstSPI = NULL; + volatile uint32 u32Counter; + + SPIHA_pstSPI->S |= I2C_S_SPIIF_MASK; + + if (0 < SPIHA_u32BytesToTransfer) + { + SPIHA_pstSPI->D = *(uint8*)SPI_pvData; + SPIHA_pvData = (void*)((uint32)SPI_pvData + 1); + SPIHA_u32BytesToTransfer -= 1; + } + else + { + SPIHA_pstSPI->C1 &= ~(I2C_C1_SPIIE_MASK | I2C_C1_MST_MASK); + + enMode = DLL_enGetChannelMode(enEHIOResource); + + if (IOAPI_enPortSerialTransfer == enMode) + { + SRLTFR_vNotifyCB(EH_VIO_SPI1); + } + else if (IOAPI_enPortComms == enMode) + { + //DLL_vFrameRXCB(enEHIOResource, &CAN_stRXDLLData); + } + } +#endif //BUILD_MK60 + +#ifdef BUILD_SAM3X8E + uint16 u16Data; + + switch(enEHIOResource) + { + case EH_VIO_SPI1: + { + pstSPI = SPI0; + break; + } + default: + { + break; + } + } + + if (((NULL != SPIHA_pstSPI) && (NULL != pstSPI)) && + (SPIHA_pstSPI == pstSPI)) + { + if (0 < SPIHA_u32BytesToTransfer) + { + u16Data = (uint16)*(puint8)SPIHA_pvData; + spi_write(SPIHA_pstSPI, u16Data, 0, 0); + SPIHA_pvData = (void*)((uint32)SPIHA_pvData + 1); + SPIHA_u32BytesToTransfer -= 1; + + for (u32Counter = 0; u32Counter < 199; u32Counter++) + { + __asm("nop"); + } + } + else + { + enMode = DLL_enGetChannelMode(enEHIOResource); + + if (IOAPI_enPortSerialTransfer == enMode) + { + SRLTFR_vNotifyCB(EH_VIO_SPI1); + } + else if (IOAPI_enPortComms == enMode) + { + //DLL_vFrameRXCB(enEHIOResource, &CAN_stRXDLLData); + } + + spi_disable_interrupt(pstSPI, SPI_SR_TDRE); + } + } + else if (NULL != pstSPI) + { + spi_disable_interrupt(pstSPI, SPI_SR_TDRE); + } +#endif //BUILD_SAM3X8E +} + +static sint32 SPIHA_u32GetSPIIndex(IOAPI_tenEHIOResource enEHIOResource) +{ + sint32 i32IDX = -1; + + if ((EH_VIO_SPI1 <= enEHIOResource) && (EH_VIO_SPI2 >= enEHIOResource)) + { + i32IDX = enEHIOResource - EH_VIO_SPI1; + } + + return i32IDX; +} + + + + + + diff --git a/source/Peripherals/SPIHA.h b/source/Peripherals/SPIHA.h new file mode 100644 index 0000000..dba4cf3 --- /dev/null +++ b/source/Peripherals/SPIHA.h @@ -0,0 +1,182 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef SPIHA_H +#define SPIHA_H + +#include +#include "build.h" +#include "CPUAbstract.h" +#include "declarations.h" +#include "DLL.h" +#include "IRQ.h" +#include "IOAPI.h" +#include "MATH.h" +#include "OS.h" +#include "PIM.h" +#include "PERSPI.h" +#include "PIMAPI.h" +#include "regset.h" +#include "RESM.h" +#include "SIM.h" + +#ifdef BUILD_SAM3X8E +#include "spi.h" +#endif //BUILD_SAM3X8E + +#ifdef BUILD_MK64 +#include "mk64f12.h" +#endif + +#include "SRLTFR.h" +#include "sys.h" +#include "types.h" + +#define SPIHA_nBitCount 8 +#define SPIHA_nDeviceID 0 +#define SPIHA_xSPIBaudRateDivider(b) spi_calc_baudrate_div(b, SYS_FREQ_BUS) + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +#define SPIHA_nReg8SetSPI0 \ +{ \ + { (volatile uint8*)(I2C0_BASE + offsetof(I2C_Type, C1)), (uint8)I2C_C1_IICEN_MASK, REGSET_enOverwrite }, \ + { NULL, 0, REGSET_enOverwrite } \ +}; +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E +#define SPIHA_nReg8SetSPI0 \ +{ \ + { NULL, 0, REGSET_enOverwrite } \ +}; +#endif //BUILD_SAM3X8E + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +#define SPIHA_nReg8SetSPI1 \ +{ \ + { (volatile uint8*)(I2C1_BASE + offsetof(I2C_Type, C1)), (uint8)I2C_C1_IICEN_MASK, REGSET_enOverwrite }, \ + { NULL, 0, REGSET_enOverwrite } \ +}; +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E +#define SPIHA_nReg8SetSPI1 \ +{ \ + { NULL, 0, REGSET_enOverwrite } \ +}; +#endif //BUILD_SAM3X8E + +#define SPIHA_nDivisorMap \ +{ \ + {20, 7}, \ + {22, 7}, \ + {24, 8}, \ + {26, 8}, \ + {28, 9}, \ + {30, 9}, \ + {34, 10}, \ + {40, 10}, \ + {28, 7}, \ + {32, 7}, \ + {36, 9}, \ + {40, 9}, \ + {44, 11}, \ + {48, 11}, \ + {56, 13}, \ + {68, 13}, \ + {48, 9}, \ + {56, 9}, \ + {64, 13}, \ + {72, 13}, \ + {80, 17}, \ + {88, 17}, \ + {104, 21}, \ + {128, 21}, \ + {80, 9}, \ + {96, 9}, \ + {112, 17}, \ + {128, 17}, \ + {144, 25}, \ + {160, 25}, \ + {192, 33}, \ + {240, 33}, \ + {160, 17}, \ + {192, 17}, \ + {224, 33}, \ + {256, 33}, \ + {288, 49}, \ + {320, 49}, \ + {384, 65}, \ + {480, 65}, \ + {320, 33}, \ + {384, 33}, \ + {448, 65}, \ + {512, 65}, \ + {576, 97}, \ + {640, 97}, \ + {768, 129}, \ + {960, 129}, \ + {640, 65}, \ + {768, 65}, \ + {896, 129}, \ + {1024, 129}, \ + {1152, 193}, \ + {1280, 193}, \ + {1536, 257}, \ + {1920, 257}, \ + {1280, 129}, \ + {1536, 129}, \ + {1792, 257}, \ + {2048, 257}, \ + {2304, 385}, \ + {2560, 385}, \ + {3072, 513}, \ + {3840, 513} \ +} + +#define SPI_xRequestPortClock(x) \ +/* turn on clock */ \ +SIM_vSetReg32(SIM_SCGC4, x); \ +SPI_u32PortClockRequested |= x + +#define SPI_xCalcDivisor \ +for (u32DivMapIDX = 0; \ + u32DivMapIDX < (sizeof(SPI_rastDivisorMap) / sizeof(SPI_tstDivisorMap)); \ + u32DivMapIDX++) \ +{ \ + u32Div = u32DivMapIDX; \ + if (SPI_rastDivisorMap[u32DivMapIDX].u32SCLDivider > u32DivCalc) break; \ +} + +typedef struct +{ + uint32 u32SCLDivider; + uint32 u32SDAHold; +} SPIHA_tstDivisorMap; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +typedef SPI_Type tstSPIModule; +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E +typedef Spi tstSPIModule; +#endif //BUILD_SAM3X8E + + +void SPIHA_vStart(puint32 const); +void SPIHA_vRun(puint32 const); +void SPIHA_vTerminate(puint32 const); +uint32 SPIHA_u32InitBus(IOAPI_tenEHIOResource, IOAPI_tstPortConfigCB*); +void SPIHA_vInitTransfer(IOAPI_tstTransferCB*); +void SPIHA_vInterruptHandler(IOAPI_tenEHIOResource); + +#endif //SPIHA_H + diff --git a/source/Peripherals/SRLTFR.c b/source/Peripherals/SRLTFR.c new file mode 100644 index 0000000..5a48a26 --- /dev/null +++ b/source/Peripherals/SRLTFR.c @@ -0,0 +1,113 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: SRLTFR */ +/* DESCRIPTION: Serial Transfer file */ +/* FILE NAME: SRLTFR.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _SRLTFR_C + +#include +#include "IIC.h" +#include "IOAPI.h" +#include "PERSPI.h" +#include "SYSAPI.h" +#include "types.h" +#include "CQUEUE.h" +#include "SRLTFR.h" +#include "declarations.h" + +IOAPI_tenEHIOResource SRLTFR_enActiveEHIOResource; + +void SRLTFR_vStart(puint32 const pu32Arg) +{ + CQUEUE_xInit(&SRLTFR_stTransferQueue, SRLTFR_nTransfersMax, SRLTFR_astTransferInfo); + SRLTFR_enActiveEHIOResource = EH_IO_Invalid; +} + +void SRLTFR_vRun(puint32 const pu32Arg) +{ + if (!CQUEUE_xIsEmpty(&SRLTFR_stTransferQueue)) + { + switch (SRLTFR_astTransferInfo[SRLTFR_stTransferQueue.u32Head].enEHIOResource) + { + case EH_VIO_IIC1: + case EH_VIO_IIC2: + { + IIC_vInitTransfer(&SRLTFR_astTransferInfo[SRLTFR_stTransferQueue.u32Head]); + SRLTFR_enActiveEHIOResource = SRLTFR_astTransferInfo[SRLTFR_stTransferQueue.u32Head].enEHIOResource; + } + case EH_VIO_SPI1: + case EH_VIO_SPI2: + { + SPI_vInitTransfer(&SRLTFR_astTransferInfo[SRLTFR_stTransferQueue.u32Head]); + SRLTFR_enActiveEHIOResource = SRLTFR_astTransferInfo[SRLTFR_stTransferQueue.u32Head].enEHIOResource; + } + default: + { + + } + } + } +} + +void SRLTFR_vTerminate(puint32 const pu32Arg) +{ + +} + +SYSAPI_tenSVCResult SRLTFR_enEnqueue(IOAPI_tstTransferCB* pstTransferCB) +{ + SYSAPI_tenSVCResult enSVCResult = SYSAPI_enQueueFull; + uint32 u32Flag; + + + if (!CQUEUE_xIsFull(&SRLTFR_stTransferQueue)) + { + memcpy((void*)&SRLTFR_astTransferInfo[SRLTFR_stTransferQueue.u32Head], + (void*)pstTransferCB, + sizeof(IOAPI_tstTransferCB)); + + enSVCResult = SYSAPI_enOK; + CQUEUE_xAddItem(&SRLTFR_stTransferQueue); + + if (TRUE == pstTransferCB->boBlockingMode) + { + SRLTFR_vRun(&u32Flag); + enSVCResult = SYSAPI_enOK; + + /* Clear the queue because it was all sent in blocking mode */ + CQUEUE_xRemoveItem(&SRLTFR_stTransferQueue); + } + } + + + return enSVCResult; +} + +void SRLTFR_vNotifyCB(IOAPI_tenEHIOResource enEHIOResource) +{ + IOAPI_enTransferType enTransferType; + IOAPI_tpfTransferCB pfCB; + + if (SRLTFR_enActiveEHIOResource == enEHIOResource) + { + enTransferType = SRLTFR_astTransferInfo[SRLTFR_stTransferQueue.u32Head].enTransferType; + pfCB = SRLTFR_astTransferInfo[SRLTFR_stTransferQueue.u32Head].pfCB; + + if ((NULL != pfCB) && (IOAPI_IO_TX == enTransferType)) + { + (*pfCB)(enEHIOResource, + SRLTFR_astTransferInfo[SRLTFR_stTransferQueue.u32Head].pvData, + SRLTFR_astTransferInfo[SRLTFR_stTransferQueue.u32Head].u32ByteCount, + SRLTFR_astTransferInfo[SRLTFR_stTransferQueue.u32Head].enTransferType); + } + CQUEUE_xRemoveItem(&SRLTFR_stTransferQueue); + } +} + + diff --git a/source/Peripherals/SRLTFR.h b/source/Peripherals/SRLTFR.h new file mode 100644 index 0000000..706ff85 --- /dev/null +++ b/source/Peripherals/SRLTFR.h @@ -0,0 +1,40 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: SRLTFR */ +/* DESCRIPTION: Serial Transfer header file */ +/* FILE NAME: SRLTFR.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef SRLTFR_H +#define SRLTFR_H + +#include +#include +#include +#include "CQUEUE.h" + +#define SRLTFR_nTransfersMax 5u + +#ifdef _SRLTFR_C + #define EXTERN +#else + #undef EXTERN + #define EXTERN extern +#endif + +EXTERN IOAPI_tstTransferCB SRLTFR_astTransferInfo[SRLTFR_nTransfersMax]; +EXTERN CQUEUE_tstQueue SRLTFR_stTransferQueue; + +void SRLTFR_vStart(uint32* const); +void SRLTFR_vRun(uint32* const); +void SRLTFR_vTerminate(uint32* const); +SYSAPI_tenSVCResult SRLTFR_enEnqueue(IOAPI_tstTransferCB*); +void SRLTFR_vNotifyCB(IOAPI_tenEHIOResource); + + +#endif // CAN_H + diff --git a/source/Peripherals/TIME.c b/source/Peripherals/TIME.c new file mode 100644 index 0000000..cd3dea9 --- /dev/null +++ b/source/Peripherals/TIME.c @@ -0,0 +1,44 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: TIME */ +/* DESCRIPTION: This code provides setup and functions for the RTC */ +/* hardware module */ +/* FILE NAME: TIME.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include +#include +#include +#include "mk64f12.h" +#include "os.h" +#include "time.h" + +void TIME_vStart(uint32* const pu32Stat) +{ + OS_xModuleStartOK(*pu32Stat); +} + +void TIME_vRun(uint32* const pu32Stat) +{ + +} + +void TIME_vTerminate(uint32* const pu32Stat) +{ + +} + +bool TIME_stGetTime(TIME_tstTime* const pstTime) +{ + return true; +} + +uint32 TIME_u32GetFATTime( void ) +{ + return 0; +} diff --git a/source/Peripherals/TIME.h b/source/Peripherals/TIME.h new file mode 100644 index 0000000..95efebe --- /dev/null +++ b/source/Peripherals/TIME.h @@ -0,0 +1,40 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: TIME Header File */ +/* DESCRIPTION: This code provides struct definitions for the RTC */ +/* hardware module */ +/* FILE NAME: TIME.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef TIME_H +#define TIME_H + +#include "declarations.h" +#include "CPUAbstract.h" +#include "os.h" +#include "sys.h" +#include "time.h" + +typedef struct +{ + uint32 biYear:7; + uint32 biMonth:4; + uint32 biDay:5; + uint32 biHours:5; + uint32 biMinutes:6; + uint32 biSeconds:5; +} TIME_tstTime; + + +void TIME_vStart( uint32* const ); +void TIME_vRun( uint32* const ); +void TIME_vTerminate( uint32* const ); +bool TIME_stGetTime( TIME_tstTime* const ); +uint32 TIME_u32GetFATTime( void ); + +#endif // TIME_H + diff --git a/source/Peripherals/UARTHA.c b/source/Peripherals/UARTHA.c new file mode 100644 index 0000000..578726e --- /dev/null +++ b/source/Peripherals/UARTHA.c @@ -0,0 +1,221 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#include "types.h" +#include "CPUAbstract.h" +#include "peruart.h" +#include "regset.h" +#include "sys.h" +#include "IRQ.h" +#include "declarations.h" +#include "os.h" +#include "DLL.h" +#include "SIM.h" + +#ifdef BUILD_SAM3X8E +#include "uart.h" +#endif + +const UART_tstUARTCB UARTHA_rastUARTCB[] = UARTHA_nDataCB; + +static tstUARTModule* UARTHA_pstGetUART(IOAPI_tenEHIOResource); +static sint32 UARTHA_u32GetUARTIndex(IOAPI_tenEHIOResource); + +void UARTHA_vStart(uint32* const u32Stat) +{ + OS_xModuleStartOK(*u32Stat); +} + +void UARTHA_vRun(uint32* const u32Stat) +{ + +} + +void UARTHA_vTerminate(uint32* const u32Stat) +{ + +} + +SYSAPI_tenSVCResult UARTHA_enInitBus(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tstPortConfigCB* pstPortConfigCB) +{ + sint32 i32IDX = UARTHA_u32GetUARTIndex(enEHIOResource); + SYSAPI_tenSVCResult enSVCResult = SYSAPI_enBadResource; + tstUARTModule* pstUART; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + REGSET_tstReg8Val astUARTReg8Val[4]; + uint16 u16BaudDiv; + + if ((-1 != i32IDX) && (TRUE == DLL_boInitDLLChannel(enEHIOResource, pstPortConfigCB))) + { + + /* turn on UARTn clock */ + SIM_vSetReg32(UARTHA_rastUARTCB[i32IDX].enSIMReg, UARTHA_rastUARTCB[i32IDX].u32SIMRegMask); + + pstUART = UARTHA_rastUARTCB[i32IDX].pstUART; + + u16BaudDiv = (uint16)(UARTHA_rastUARTCB[i32IDX].u32SourceClockHz + / (16u * pstPortConfigCB->u32BaudRateHz)); + + astUARTReg8Val[0].reg = (volatile uint8*)((uint8*)pstUART + offsetof(UART_Type, BDH)); + astUARTReg8Val[0].val = (uint8)(u16BaudDiv / 0x100); + astUARTReg8Val[0].writeMode = REGSET_enOverwrite; + + astUARTReg8Val[1].reg = (volatile uint8*)((uint8*)pstUART + offsetof(UART_Type, BDL)); + astUARTReg8Val[1].val = (uint8)(u16BaudDiv % 0x100); + astUARTReg8Val[1].writeMode = REGSET_enOverwrite; + + astUARTReg8Val[2].reg = (volatile uint8*)((uint8*)pstUART + offsetof(UART_Type, C2)); + astUARTReg8Val[2].val = (uint8)(UART_C2_TE_MASK | UART_C2_RE_MASK | UART_C2_RIE_MASK); + astUARTReg8Val[2].writeMode = REGSET_enOverwrite; + + astUARTReg8Val[3].reg = NULL; + + REGSET_vInitReg8(&astUARTReg8Val[0]); + + IRQ_vEnableIRQ(UARTHA_rastUARTCB[i32IDX].IRQn, IRQ_enPRIO_15, UART_vInterrupt, UART_vInterrupt); + + enSVCResult = SYSAPI_enOK; + } +#endif //BUILD_MK60 + +#ifdef BUILD_SAM3X8E + sam_uart_opt_t stUARTOptions; + uint32 u32RetVal; + + if ((-1 != i32IDX) && (TRUE == DLL_boInitDLLChannel(enEHIOResource, pstPortConfigCB))) + { + pstUART = UARTHA_rastUARTCB[i32IDX].pstUART; + + stUARTOptions.ul_mck = SYS_FREQ_BUS; + stUARTOptions.ul_baudrate = pstPortConfigCB->u32BaudRateHz; + stUARTOptions.ul_mode = UART_MR_PAR_NO | UART_MR_CHMODE_NORMAL; + + u32RetVal = uart_init(pstUART, &stUARTOptions); + + enSVCResult = (0 == u32RetVal) ? SYSAPI_enOK : SYSAPI_enBaudRateUnavailable; + } +#endif //BUILD_SAM3X8E + + return enSVCResult; +} + +void UARTHA_vSendChar(IOAPI_tenEHIOResource enEHIOResource, uint8 ucData) +{ + tstUARTModule* pstUART = UARTHA_pstGetUART(enEHIOResource); + + if (NULL != pstUART) + { +#if defined(BUILD_MK60) || defined(BUILD_MK64) + pstUART -> D = ucData; + //pstUART -> C2 |= UART_C2_TIE_MASK; /* Set UART TIE bit */ +#endif + } +} + +uint8 UARTHA_u8GetChar(IOAPI_tenEHIOResource enEHIOResource) +{ + tstUARTModule* pstUART = UARTHA_pstGetUART(enEHIOResource); + + if (NULL != pstUART) + { +#if defined(BUILD_MK60) || defined(BUILD_MK64) + return pstUART -> D; +#endif + } + + return 0; +} + +static tstUARTModule* UARTHA_pstGetUART(IOAPI_tenEHIOResource enEHIOResource) +{ + tstUARTModule* pstUART; + + switch(enEHIOResource) + { +#if defined(BUILD_MK60) || defined(BUILD_MK64) + case EH_VIO_UART1: + pstUART = UART0; + break; + + case EH_VIO_UART2: + pstUART = UART1; + break; + + case EH_VIO_UART3: + pstUART = UART2; + break; + + case EH_VIO_UART4: + pstUART = UART3; + break; + + case EH_VIO_UART5: + pstUART = UART4; + break; + + case EH_VIO_UART6: + pstUART = UART5; + break; +#endif //BUILD_MK60 + default: + pstUART = NULL; + break; + } + + return pstUART; +} + +static sint32 UARTHA_u32GetUARTIndex(IOAPI_tenEHIOResource enEHIOResource) +{ + return 0; +} + + +void UARTHA_vDisableTXInterrupt(IOAPI_tenEHIOResource enEHIOResource) +{ +#if defined(BUILD_MK60) || defined(BUILD_MK64) + tstUARTModule* pstUART = UARTHA_pstGetUART(enEHIOResource); + pstUART -> C2 &= ~UART_C2_TIE_MASK; /* Clear UART TIE bit */ +#endif +} + +void UARTHA_vEnableTXInterrupt(IOAPI_tenEHIOResource enEHIOResource) +{ +#if defined(BUILD_MK60) || defined(BUILD_MK64) + tstUARTModule* pstUART = UARTHA_pstGetUART(enEHIOResource); + pstUART -> C2 &= UART_C2_TIE_MASK; /* Set UART TIE bit */ +#endif +} + +void UARTHA_vDisableRXInterrupt(IOAPI_tenEHIOResource enEHIOResource) +{ +#if defined(BUILD_MK60) || defined(BUILD_MK64) + tstUARTModule* pstUART = UARTHA_pstGetUART(enEHIOResource); + pstUART -> C2 &= ~UART_C2_RIE_MASK; /* Clear UART RIE bit */ +#endif +} + +void UARTHA_vEnableRXInterrupt(IOAPI_tenEHIOResource enEHIOResource) +{ +#if defined(BUILD_MK60) || defined(BUILD_MK64) + tstUARTModule* pstUART = UARTHA_pstGetUART(enEHIOResource); + pstUART -> C2 &= UART_C2_RIE_MASK; /* Set UART RIE bit */ +#endif +} + + + + + + + diff --git a/source/Peripherals/UARTHA.h b/source/Peripherals/UARTHA.h new file mode 100644 index 0000000..740488d --- /dev/null +++ b/source/Peripherals/UARTHA.h @@ -0,0 +1,74 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: UARTHA Header File */ +/* DESCRIPTION: UART Hardware Adaption */ +/* FILE NAME: UART.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef UARTHA_H +#define UARTHA_H + +#if defined(BUILD_MK60) +#include "mk60f12.h" +typedef UART_Type tstUARTModule; +#endif //BUILD_MK60 + +#if defined(BUILD_MK64) +#include "mk64f12.h" +typedef UART_Type tstUARTModule; +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +//#include "sam3x8e.h" +typedef struct Uart tstUARTModule; +#endif + +#ifdef BUILD_MK60 +#define UARTHA_nDataCB \ +{ \ + {SYS_FREQ_CORE, SIM_SCGC4, SIM_SCGC4_UART0_MASK, UART0, UART0_RX_TX_IRQn}, \ + {SYS_FREQ_BUS, SIM_SCGC4, SIM_SCGC4_UART1_MASK, UART1, UART1_RX_TX_IRQn}, \ + {SYS_FREQ_BUS, SIM_SCGC4, SIM_SCGC4_UART2_MASK, UART2, UART2_RX_TX_IRQn}, \ + {SYS_FREQ_BUS, SIM_SCGC4, SIM_SCGC4_UART3_MASK, UART3, UART3_RX_TX_IRQn}, \ + {SYS_FREQ_BUS, SIM_SCGC1, SIM_SCGC1_UART4_MASK, UART4, UART4_RX_TX_IRQn}, \ + {SYS_FREQ_BUS, SIM_SCGC1, SIM_SCGC1_UART5_MASK, UART5, UART5_RX_TX_IRQn} \ +} +#endif + +#ifdef BUILD_MK64 +#define UARTHA_nDataCB \ +{ \ + {SYS_FREQ_CORE, SIM_SCGC4, SIM_SCGC4_UART0_MASK, UART0, UART0_RX_TX_IRQn}, \ + {SYS_FREQ_BUS, SIM_SCGC4, SIM_SCGC4_UART1_MASK, UART1, UART1_RX_TX_IRQn}, \ + {SYS_FREQ_BUS, SIM_SCGC4, SIM_SCGC4_UART2_MASK, UART2, UART2_RX_TX_IRQn}, \ + {SYS_FREQ_BUS, SIM_SCGC4, SIM_SCGC4_UART3_MASK, UART3, UART3_RX_TX_IRQn}, \ + {SYS_FREQ_BUS, SIM_SCGC1, SIM_SCGC1_UART4_MASK, UART4, UART4_RX_TX_IRQn}, \ + {SYS_FREQ_BUS, SIM_SCGC1, SIM_SCGC1_UART5_MASK, UART5, UART5_RX_TX_IRQn} \ +} +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +#define UARTHA_nDataCB \ +{ \ + {0, 0, 0, 0, 0} \ +} +#endif //BUILD_SAM3X8E + +void UARTHA_vStart(uint32* const); +void UARTHA_vRun(uint32* const); +void UARTHA_vTerminate(uint32* const); +SYSAPI_tenSVCResult UARTHA_enInitBus(IOAPI_tenEHIOResource, IOAPI_tstPortConfigCB*); +void UARTHA_vSendChar(IOAPI_tenEHIOResource, uint8); +uint8 UARTHA_u8GetChar(IOAPI_tenEHIOResource); +void UARTHA_vDisableTXInterrupt(IOAPI_tenEHIOResource); +void UARTHA_vEnableTXInterrupt(IOAPI_tenEHIOResource); +void UARTHA_vDisableRXInterrupt(IOAPI_tenEHIOResource); +void UARTHA_vEnableRXInterrupt(IOAPI_tenEHIOResource); + + +#endif //UARTHA_H + diff --git a/source/Peripherals/USBHA.c b/source/Peripherals/USBHA.c new file mode 100644 index 0000000..0fcebe4 --- /dev/null +++ b/source/Peripherals/USBHA.c @@ -0,0 +1,142 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#include "types.h" +#include "CPUAbstract.h" +#include "perusb.h" +#include "regset.h" +#include "sys.h" +#include "IRQ.h" +#include "declarations.h" +#include "os.h" +#include "DLL.h" +#include "SIM.h" + +#ifdef BUILD_SAM3X8E +#include "uotghs_device.h" +#include "udc.h" +#include "udi_cdc.h" +#endif //BUILD_SAM3X8E + + +bool my_flag_authorise_cdc_transfer = false; +uint8 USBHA_u8Port; + + +void USBHA_vStart(uint32* const u32Stat) +{ + OS_xModuleStartOK(*u32Stat); +} + +void USBHA_vRun(uint32* const u32Stat) +{ + +} + +void USBHA_vTerminate(uint32* const u32Stat) +{ + +} + +SYSAPI_tenSVCResult USBHA_enInitBus(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tstPortConfigCB* pstPortConfigCB) +{ + SYSAPI_tenSVCResult enSVCResult; + bool boRetVal = false; + +#ifdef BUILD_MK60 + tstUSBModule* pstUSB; + +#endif //BUILD_MK60 + +#ifdef BUILD_SAM3X8E + uint8_t bmAttributes; + udc_start(); + + bmAttributes = USB_EP_TYPE_CONTROL; + udd_ep_alloc(0, bmAttributes, 512u); + + boRetVal = DLL_boInitDLLChannel(enEHIOResource, pstPortConfigCB); +#endif //BUILD_SAM3X8E + + enSVCResult = TRUE == boRetVal ? SYSAPI_enOK : SYSAPI_enBadResource; + return enSVCResult; +} + +bool my_callback_cdc_enable(void) +{ + my_flag_authorise_cdc_transfer = true; + return true; +} +void my_callback_cdc_disable(void) +{ + my_flag_authorise_cdc_transfer = false; +} + +void my_callback_rx_notify(uint8_t port) +{ + DLL_tstRXDLLData* pstRXDLLData = DLL_pstGetRXBuffer(EH_VIO_USB); + puint8 pu8RXData = pstRXDLLData->u8Data; + + USBHA_u8Port = port; + + uint32 u32BytesRXCount = udi_cdc_get_nb_received_data(); + pstRXDLLData->u8DataCount = u32BytesRXCount; + + udi_cdc_read_buf((void*)pu8RXData, u32BytesRXCount); + DLL_vFrameRXCB(EH_VIO_USB, pu8RXData); +} + +void my_callback_tx_empty_notify(uint8_t port) +{ + +} + +#ifdef BUILD_SAM3X8E +void my_callback_config(uint8_t port, usb_cdc_line_coding_t * cfg) +{ + +} +#endif //BUILD_SAM3X8E + +void my_callback_cdc_set_dtr(uint8_t port, bool b_enable) +{ + +} + +void my_callback_cdc_set_rts(uint8_t port, bool b_enable) +{ + +} + + +void USBHA_vSend(IOAPI_tenEHIOResource enEHIOResource, puint8 pu8Data, uint32 u32TXByteCount) +{ + if (my_flag_authorise_cdc_transfer) + { + udi_cdc_write_buf((const void*)pu8Data, u32TXByteCount); + } +} + +puint8 USBHA_pu8Receive(IOAPI_tenEHIOResource enEHIOResource) +{ + return 0; +} + + + + + + + + + + diff --git a/source/Peripherals/USBHA.h b/source/Peripherals/USBHA.h new file mode 100644 index 0000000..12e4264 --- /dev/null +++ b/source/Peripherals/USBHA.h @@ -0,0 +1,48 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: USBHA Header File */ +/* DESCRIPTION: USB Hardware Adaption */ +/* FILE NAME: USB.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef USBHA_H +#define USBHA_H + +#ifdef BUILD_MK60 +#include "mk60f12.h" +typedef USB_Type tstUARTModule; +#endif + +#ifdef BUILD_SAM3X8E +//#include "sam3x8e.h" +typedef struct Uart tstUARTModule; +#endif + +#ifdef BUILD_MK60 +#define USBHA_nDataCB \ +{ \ +} +#endif + +#ifdef BUILD_SAM3X8E +#define UARTHA_nDataCB \ +{ \ + {0, 0, 0, 0, 0} \ +} +#endif //BUILD_SAM3X8E + +void USBHA_vStart(uint32* const); +void USBHA_vRun(uint32* const); +void USBHA_vTerminate(uint32* const); +SYSAPI_tenSVCResult USBHA_enInitBus(IOAPI_tenEHIOResource, IOAPI_tstPortConfigCB*); +void USBHA_vSend(IOAPI_tenEHIOResource, puint8, uint32); +puint8 USBHA_pu8Receive(IOAPI_tenEHIOResource); + + + +#endif //USBHA_H + diff --git a/source/Peripherals/VCOMHA.c b/source/Peripherals/VCOMHA.c new file mode 100644 index 0000000..2fa8e47 --- /dev/null +++ b/source/Peripherals/VCOMHA.c @@ -0,0 +1,757 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_device_registers.h" +#include "clock_config.h" +#include "board.h" + +#include +#include + + +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device.h" + +#include "usb_device_class.h" +#include "usb_device_cdc_acm.h" +#include "usb_device_ch9.h" + + +#include "build.h" +#include "types.h" +#include "sysapi.h" +#include "dll.h" + +#include "usb_device_descriptor.h" +#include "CPUAbstract.h" +#include "declarations.h" +#include + +#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U)) +//#include "fsl_sysmpu.h" +#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */ +#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0) +#include "usb_phy.h" +#endif +#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \ + defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \ + defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U) +#include "fsl_smc.h" +#endif +#include "fsl_common.h" +#include "pin_mux.h" +/******************************************************************************* +* Definitions +******************************************************************************/ +/* USB clock source and frequency*/ +#define USB_FS_CLK_SRC kCLOCK_UsbSrcPll0 +#define USB_FS_CLK_FREQ CLOCK_GetFreq(kCLOCK_PllFllSelClk) + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +void BOARD_InitHardware(void); +void BOARD_DbgConsole_Deinit(void); +void BOARD_DbgConsole_Init(void); +usb_status_t USB_DeviceCdcVcomCallback(class_handle_t handle, uint32_t event, void *param); +usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param); + +/******************************************************************************* +* Variables +******************************************************************************/ +extern usb_device_endpoint_struct_t g_UsbDeviceCdcVcomDicEndpoints[]; +extern usb_device_class_struct_t g_UsbDeviceCdcVcomConfig; +/* Data structure of virtual com device */ +static usb_cdc_vcom_struct_t s_cdcVcom; + +/* Line codinig of cdc device */ +static uint8_t s_lineCoding[LINE_CODING_SIZE] = { + /* E.g. 0x00,0xC2,0x01,0x00 : 0x0001C200 is 115200 bits per second */ + (LINE_CODING_DTERATE >> 0U) & 0x000000FFU, + (LINE_CODING_DTERATE >> 8U) & 0x000000FFU, + (LINE_CODING_DTERATE >> 16U) & 0x000000FFU, + (LINE_CODING_DTERATE >> 24U) & 0x000000FFU, + LINE_CODING_CHARFORMAT, + LINE_CODING_PARITYTYPE, + LINE_CODING_DATABITS}; + +/* Abstract state of cdc device */ +static uint8_t s_abstractState[COMM_FEATURE_DATA_SIZE] = {(STATUS_ABSTRACT_STATE >> 0U) & 0x00FFU, + (STATUS_ABSTRACT_STATE >> 8U) & 0x00FFU}; + +/* Country code of cdc device */ +static uint8_t s_countryCode[COMM_FEATURE_DATA_SIZE] = {(COUNTRY_SETTING >> 0U) & 0x00FFU, + (COUNTRY_SETTING >> 8U) & 0x00FFU}; + +/* CDC ACM information */ +USB_DATA_ALIGNMENT static usb_cdc_acm_info_t s_usbCdcAcmInfo = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0}; +/* Data buffer for receiving and sending*/ +USB_DATA_ALIGNMENT static uint8_t s_currRecvBuf[USB_DATA_BUFF_SIZE]; +USB_DATA_ALIGNMENT static uint8_t s_currSendBuf[USB_DATA_BUFF_SIZE]; +volatile static uint32_t s_recvSize = 0; +volatile static uint32_t s_sendSize = 0; + +/* USB device class information */ +static usb_device_class_config_struct_t s_cdcAcmConfig[1] = {{ + USB_DeviceCdcVcomCallback, 0, &g_UsbDeviceCdcVcomConfig, +}}; + +/* USB device class configuration information */ +static usb_device_class_config_list_struct_t s_cdcAcmConfigList = { + s_cdcAcmConfig, USB_DeviceCallback, 1, +}; + +#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \ + defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \ + defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U) +volatile static uint8_t s_waitForDataReceive = 0; +volatile static uint8_t s_comOpen = 0; +#endif +/******************************************************************************* +* Code +******************************************************************************/ +/*! + * @brief CDC class specific callback function. + * + * This function handles the CDC class specific requests. + * + * @param handle The CDC ACM class handle. + * @param event The CDC ACM class event type. + * @param param The parameter of the class specific request. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcVcomCallback(class_handle_t handle, uint32_t event, void *param) +{ + uint32_t len; + uint16_t *uartBitmap; + usb_device_cdc_acm_request_param_struct_t *acmReqParam; + usb_device_endpoint_callback_message_struct_t *epCbParam; + usb_status_t error = kStatus_USB_Error; + usb_cdc_acm_info_t *acmInfo = &s_usbCdcAcmInfo; + acmReqParam = (usb_device_cdc_acm_request_param_struct_t *)param; + epCbParam = (usb_device_endpoint_callback_message_struct_t *)param; + switch (event) + { + case kUSB_DeviceCdcEventSendResponse: + { + if ((epCbParam->length != 0) && (!(epCbParam->length % g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize))) + { + /* If the last packet is the size of endpoint, then send also zero-ended packet, + ** meaning that we want to inform the host that we do not have any additional + ** data, so it can flush the output. + */ + error = USB_DeviceCdcAcmSend(handle, USB_CDC_VCOM_BULK_IN_ENDPOINT, NULL, 0); + } + //else if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions)) + else if (1 == s_cdcVcom.attach) + { + if ((epCbParam->buffer != NULL) || ((epCbParam->buffer == NULL) && (epCbParam->length == 0))) + { + /* User: add your own code for send complete event */ + /* Schedule buffer for next receive event */ + error = USB_DeviceCdcAcmRecv(handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, + g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize); +#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \ + defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \ + defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U) + s_waitForDataReceive = 1; + USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK; +#endif + } + } + else + { + } + } + break; + case kUSB_DeviceCdcEventRecvResponse: + { + //if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions)) + if (1 == s_cdcVcom.attach) + { + s_recvSize = epCbParam->length; + +#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \ + defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \ + defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U) + s_waitForDataReceive = 0; + USB0->INTEN |= USB_INTEN_SOFTOKEN_MASK; +#endif + if (!s_recvSize) + { + /* Schedule buffer for next receive event */ + error = USB_DeviceCdcAcmRecv(handle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, + g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize); +#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \ + defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \ + defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U) + s_waitForDataReceive = 1; + USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK; +#endif + } + } + } + break; + case kUSB_DeviceCdcEventSerialStateNotif: + ((usb_device_cdc_acm_struct_t *)handle)->hasSentState = 0; + error = kStatus_USB_Success; + break; + case kUSB_DeviceCdcEventSendEncapsulatedCommand: + break; + case kUSB_DeviceCdcEventGetEncapsulatedResponse: + break; + case kUSB_DeviceCdcEventSetCommFeature: + if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == acmReqParam->setupValue) + { + if (1 == acmReqParam->isSetup) + { + *(acmReqParam->buffer) = s_abstractState; + } + else + { + *(acmReqParam->length) = 0; + } + } + else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == acmReqParam->setupValue) + { + if (1 == acmReqParam->isSetup) + { + *(acmReqParam->buffer) = s_countryCode; + } + else + { + *(acmReqParam->length) = 0; + } + } + else + { + } + error = kStatus_USB_Success; + break; + case kUSB_DeviceCdcEventGetCommFeature: + if (USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE == acmReqParam->setupValue) + { + *(acmReqParam->buffer) = s_abstractState; + *(acmReqParam->length) = COMM_FEATURE_DATA_SIZE; + } + else if (USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING == acmReqParam->setupValue) + { + *(acmReqParam->buffer) = s_countryCode; + *(acmReqParam->length) = COMM_FEATURE_DATA_SIZE; + } + else + { + } + error = kStatus_USB_Success; + break; + case kUSB_DeviceCdcEventClearCommFeature: + break; + case kUSB_DeviceCdcEventGetLineCoding: + *(acmReqParam->buffer) = s_lineCoding; + *(acmReqParam->length) = LINE_CODING_SIZE; + error = kStatus_USB_Success; + break; + case kUSB_DeviceCdcEventSetLineCoding: + { + if (1 == acmReqParam->isSetup) + { + *(acmReqParam->buffer) = s_lineCoding; + } + else + { + *(acmReqParam->length) = 0; + } + } + error = kStatus_USB_Success; + break; + case kUSB_DeviceCdcEventSetControlLineState: + { + s_usbCdcAcmInfo.dteStatus = acmReqParam->setupValue; + /* activate/deactivate Tx carrier */ + if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION) + { + acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_TX_CARRIER; + } + else + { + acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_TX_CARRIER; + } + + /* activate carrier and DTE */ + if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE) + { + acmInfo->uartState |= USB_DEVICE_CDC_UART_STATE_RX_CARRIER; + } + else + { + acmInfo->uartState &= (uint16_t)~USB_DEVICE_CDC_UART_STATE_RX_CARRIER; + } + + /* Indicates to DCE if DTE is present or not */ + acmInfo->dtePresent = (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE) ? true : false; + + /* Initialize the serial state buffer */ + acmInfo->serialStateBuf[0] = NOTIF_REQUEST_TYPE; /* bmRequestType */ + acmInfo->serialStateBuf[1] = USB_DEVICE_CDC_NOTIF_SERIAL_STATE; /* bNotification */ + acmInfo->serialStateBuf[2] = 0x00; /* wValue */ + acmInfo->serialStateBuf[3] = 0x00; + acmInfo->serialStateBuf[4] = 0x00; /* wIndex */ + acmInfo->serialStateBuf[5] = 0x00; + acmInfo->serialStateBuf[6] = UART_BITMAP_SIZE; /* wLength */ + acmInfo->serialStateBuf[7] = 0x00; + /* Notifiy to host the line state */ + acmInfo->serialStateBuf[4] = acmReqParam->interfaceIndex; + /* Lower byte of UART BITMAP */ + uartBitmap = (uint16_t *)&acmInfo->serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE - 2]; + *uartBitmap = acmInfo->uartState; + len = (uint32_t)(NOTIF_PACKET_SIZE + UART_BITMAP_SIZE); + if (0 == ((usb_device_cdc_acm_struct_t *)handle)->hasSentState) + { + error = USB_DeviceCdcAcmSend(handle, USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT, acmInfo->serialStateBuf, len); + if (kStatus_USB_Success != error) + { + usb_echo("kUSB_DeviceCdcEventSetControlLineState error!"); + } + ((usb_device_cdc_acm_struct_t *)handle)->hasSentState = 1; + } + + /* Update status */ + if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION) + { + /* To do: CARRIER_ACTIVATED */ + } + else + { + /* To do: CARRIER_DEACTIVATED */ + } +#if 0 +// Disable Transaction for .NET applications + if (acmInfo->dteStatus & USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE) + { + /* DTE_ACTIVATED */ + if (1 == s_cdcVcom.attach) + { + s_cdcVcom.startTransactions = 1; +#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \ + defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \ + defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U) + s_waitForDataReceive = 1; + USB0->INTEN &= ~USB_INTEN_SOFTOKEN_MASK; + s_comOpen = 1; + usb_echo("USB_APP_CDC_DTE_ACTIVATED\r\n"); +#endif + } + } + else + { + /* DTE_DEACTIVATED */ + if (1 == s_cdcVcom.attach) + { + s_cdcVcom.startTransactions = 0; + } + } +#endif //0 + } + break; + case kUSB_DeviceCdcEventSendBreak: + break; + default: + break; + } + + return error; +} + +/*! + * @brief USB device callback function. + * + * This function handles the usb device specific requests. + * + * @param handle The USB device handle. + * @param event The USB device event type. + * @param param The parameter of the device specific request. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param) +{ + usb_status_t error = kStatus_USB_Error; + uint16_t *temp16 = (uint16_t *)param; + uint8_t *temp8 = (uint8_t *)param; + + switch (event) + { + case kUSB_DeviceEventBusReset: + { + s_cdcVcom.attach = 0; +#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \ + (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + /* Get USB speed to configure the device, including max packet size and interval of the endpoints. */ + if (kStatus_USB_Success == USB_DeviceClassGetSpeed(CONTROLLER_ID, &s_cdcVcom.speed)) + { + USB_DeviceSetSpeed(handle, s_cdcVcom.speed); + } +#endif + } + break; + case kUSB_DeviceEventSetConfiguration: + if (param) + { + s_cdcVcom.attach = 1; + s_cdcVcom.currentConfiguration = *temp8; + if (USB_CDC_VCOM_CONFIGURE_INDEX == (*temp8)) + { + /* Schedule buffer for receive */ + USB_DeviceCdcAcmRecv(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_OUT_ENDPOINT, s_currRecvBuf, + g_UsbDeviceCdcVcomDicEndpoints[0].maxPacketSize); + } + } + break; + case kUSB_DeviceEventSetInterface: + if (s_cdcVcom.attach) + { + uint8_t interface = (uint8_t)((*temp16 & 0xFF00U) >> 0x08U); + uint8_t alternateSetting = (uint8_t)(*temp16 & 0x00FFU); + if (interface < USB_CDC_VCOM_INTERFACE_COUNT) + { + s_cdcVcom.currentInterfaceAlternateSetting[interface] = alternateSetting; + } + } + break; + case kUSB_DeviceEventGetConfiguration: + break; + case kUSB_DeviceEventGetInterface: + break; + case kUSB_DeviceEventGetDeviceDescriptor: + if (param) + { + error = USB_DeviceGetDeviceDescriptor(handle, (usb_device_get_device_descriptor_struct_t *)param); + } + break; + case kUSB_DeviceEventGetConfigurationDescriptor: + if (param) + { + error = USB_DeviceGetConfigurationDescriptor(handle, + (usb_device_get_configuration_descriptor_struct_t *)param); + } + break; + case kUSB_DeviceEventGetStringDescriptor: + if (param) + { + /* Get device string descriptor request */ + error = USB_DeviceGetStringDescriptor(handle, (usb_device_get_string_descriptor_struct_t *)param); + } + break; + default: + break; + } + + return error; +} + +/*! + * @brief USB Interrupt service routine. + * + * This function serves as the USB interrupt service routine. + * + * @return None. + */ +#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) +void USBHS_IRQHandler(void) +{ + USB_DeviceEhciIsrFunction(s_cdcVcom.deviceHandle); +} +#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 1U) +#if defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 1U) +void USB1_IRQHandler(void) +{ + USB_DeviceEhciIsrFunction(s_cdcVcom.deviceHandle); +} +#endif +#endif +#endif +#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U) +void USB0_IRQHandler(void) +{ + USB_DeviceKhciIsrFunction(s_cdcVcom.deviceHandle); +} +#endif +#if (defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) +void USB0_IRQHandler(void) +{ + USB_DeviceLpcIp3511IsrFunction(s_cdcVcom.deviceHandle); +} +#endif +#if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U) +void USB1_IRQHandler(void) +{ + USB_DeviceLpcIp3511IsrFunction(s_cdcVcom.deviceHandle); +} +#endif + +/*! + * @brief Application initialization function. + * + * This function initializes the application. + * + * @return None. + */ +void VCOM_vStart(uint32* const u32Stat) +{ + uint8_t irqNo; + + CPU_vDisableMPROT(); + +#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0) + uint8_t ehciIrq[] = USBHS_IRQS; + irqNo = ehciIrq[CONTROLLER_ID - kUSB_ControllerEhci0]; + +#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 1U) + if (CONTROLLER_ID == kUSB_ControllerEhci0) + { + CLOCK_EnableUsbhs0PhyPllClock(USB_HS_PHY_CLK_SRC, USB_HS_PHY_CLK_FREQ); + CLOCK_EnableUsbhs0Clock(USB_HS_CLK_SRC, USB_HS_CLK_FREQ); + } + else + { + CLOCK_EnableUsbhs1PhyPllClock(USB_HS_PHY_CLK_SRC, USB_HS_PHY_CLK_FREQ); + CLOCK_EnableUsbhs1Clock(USB_HS_CLK_SRC, USB_HS_CLK_FREQ); + } +#else + CLOCK_EnableUsbhs0PhyPllClock(USB_HS_PHY_CLK_SRC, USB_HS_PHY_CLK_FREQ); + CLOCK_EnableUsbhs0Clock(USB_HS_CLK_SRC, USB_HS_CLK_FREQ); +#endif + + USB_EhciPhyInit(CONTROLLER_ID, BOARD_XTAL0_CLK_HZ); +#endif + +#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0) + uint8_t khciIrq[] = USB_IRQS; + irqNo = khciIrq[CONTROLLER_ID - kUSB_ControllerKhci0]; + + SystemCoreClockUpdate(); + + CLOCK_EnableUsbfs0Clock(USB_FS_CLK_SRC, USB_FS_CLK_FREQ); +#endif + +#if (defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) + uint8_t usbDeviceIP3511Irq[] = USB_IRQS; + irqNo = usbDeviceIP3511Irq[CONTROLLER_ID - kUSB_ControllerLpcIp3511Fs0]; + + /* enable USB IP clock */ + CLOCK_EnableUsbfs0DeviceClock(USB_FS_CLK_SRC, USB_FS_CLK_FREQ); +#endif + +#if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U) + uint8_t usbDeviceIP3511Irq[] = USBHSD_IRQS; + irqNo = usbDeviceIP3511Irq[CONTROLLER_ID - kUSB_ControllerLpcIp3511Hs0]; + /* enable USB IP clock */ + CLOCK_EnableUsbhs0DeviceClock(USB_HS_CLK_SRC, USB_HS_CLK_FREQ); +#endif + +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +#if defined(FSL_FEATURE_USBHSD_USB_RAM) && (FSL_FEATURE_USBHSD_USB_RAM) + for (int i = 0; i < FSL_FEATURE_USBHSD_USB_RAM; i++) + { + ((uint8_t *)FSL_FEATURE_USBHSD_USB_RAM_BASE_ADDRESS)[i] = 0x00U; + } +#endif +#endif + +#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U)) + //SYSMPU_Enable(SYSMPU, 0); +#endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */ + +/* + * If the SOC has USB KHCI dedicated RAM, the RAM memory needs to be clear after + * the KHCI clock is enabled. When the demo uses USB EHCI IP, the USB KHCI dedicated + * RAM can not be used and the memory can't be accessed. + */ +#if (defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)) +#if (defined(FSL_FEATURE_USB_KHCI_USB_RAM_BASE_ADDRESS) && (FSL_FEATURE_USB_KHCI_USB_RAM_BASE_ADDRESS > 0U)) + for (int i = 0; i < FSL_FEATURE_USB_KHCI_USB_RAM; i++) + { + ((uint8_t *)FSL_FEATURE_USB_KHCI_USB_RAM_BASE_ADDRESS)[i] = 0x00U; + } +#endif /* FSL_FEATURE_USB_KHCI_USB_RAM_BASE_ADDRESS */ +#endif /* FSL_FEATURE_USB_KHCI_USB_RAM */ + + s_cdcVcom.speed = USB_SPEED_FULL; + s_cdcVcom.attach = 0; + s_cdcVcom.cdcAcmHandle = (class_handle_t)NULL; + s_cdcVcom.deviceHandle = NULL; + + if (kStatus_USB_Success != USB_DeviceClassInit(CONTROLLER_ID, &s_cdcAcmConfigList, &s_cdcVcom.deviceHandle)) + { + usb_echo("USB device init failed\r\n"); + } + else + { + usb_echo("USB device CDC virtual com demo\r\n"); + s_cdcVcom.cdcAcmHandle = s_cdcAcmConfigList.config->classHandle; + } + +#if defined(__GIC_PRIO_BITS) + GIC_SetPriority((IRQn_Type)irqNo, USB_DEVICE_INTERRUPT_PRIORITY); +#else + NVIC_SetPriority((IRQn_Type)irqNo, USB_DEVICE_INTERRUPT_PRIORITY); +#endif + EnableIRQ((IRQn_Type)irqNo); + + USB_DeviceRun(s_cdcVcom.deviceHandle); +} + +/*! + * @brief Application task function. + * + * This function runs the task for application. + * + * @return None. + */ +void VCOM_vRun(uint32* const u32Stat) +{ + usb_status_t error = kStatus_USB_Error; + //if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions)) + if (1 == s_cdcVcom.attach) + { + if ((0 != s_recvSize) && (0xFFFFFFFFU != s_recvSize)) + { + DLL_tstRXDLLData* pstRXDLLData = DLL_pstGetRXBuffer(EH_VIO_USB); + puint8 pu8RXData = pstRXDLLData->u8Data; + pstRXDLLData->u8DataCount = s_recvSize; + memcpy(pstRXDLLData->u8Data, s_currRecvBuf, s_recvSize); + + /* User Code */ + DLL_vFrameRXCB(EH_VIO_USB, pu8RXData); + + s_recvSize = 0; + } + + if (s_sendSize) + { + uint32_t size = s_sendSize; + s_sendSize = 0; + + error = USB_DeviceCdcAcmSend(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_IN_ENDPOINT, s_currSendBuf, size); + + if (error != kStatus_USB_Success) + { + /* Failure to send Data Handling code here */ + } + } +#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \ + defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \ + defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U) + if ((s_waitForDataReceive)) + { + if (s_comOpen == 1) + { + /* Wait for all the packets been sent during opening the com port. Otherwise these packets may + * wake up the system. + */ + usb_echo("Waiting to enter lowpower ...\r\n"); + for (uint32_t i = 0U; i < 16000000U; ++i) + { + __ASM("NOP"); /* delay */ + } + + s_comOpen = 0; + } + usb_echo("Enter lowpower\r\n"); + BOARD_DbgConsole_Deinit(); + USB0->INTEN &= ~USB_INTEN_TOKDNEEN_MASK; + SMC_SetPowerModeVlps(SMC); + + s_waitForDataReceive = 0; + USB0->INTEN |= USB_INTEN_TOKDNEEN_MASK; + BOARD_DbgConsole_Init(); + usb_echo("Exit lowpower\r\n"); + } +#endif + } +} + + +SYSAPI_tenSVCResult VCOM_enInitBus(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tstPortConfigCB* pstPortConfigCB) +{ + SYSAPI_tenSVCResult enSVCResult = SYSAPI_enBadResource; + + if (TRUE == DLL_boInitDLLChannel(enEHIOResource, pstPortConfigCB)) + { + enSVCResult = SYSAPI_enOK; + } + + return enSVCResult; +} + + +void VCOM_vTerminate(uint32* const u32Stat) +{ + + +} + + +void VCOMHA_vSend(IOAPI_tenEHIOResource enEHIOResource, puint8 pu8Data, uint32 u32TXByteCount) +{ + usb_status_t error = kStatus_USB_Error; + + if (0 != u32TXByteCount) + { + memcpy(s_currSendBuf, pu8Data, u32TXByteCount); + error = USB_DeviceCdcAcmSend(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_IN_ENDPOINT, s_currSendBuf, u32TXByteCount); + + if (error != kStatus_USB_Success) + { + /* Failure to send Data Handling code here */ + } + } +} + + +#if USB_DEVICE_CONFIG_USE_TASK +#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) +// USB_DeviceEhciTaskFunction(s_cdcVcom.deviceHandle); +#endif +#if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U) +// USB_DeviceKhciTaskFunction(s_cdcVcom.deviceHandle); +#endif +#if (defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) +// USB_DeviceLpcIp3511TaskFunction(s_cdcVcom.deviceHandle); +#endif +#if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U) +// USB_DeviceLpcIp3511TaskFunction(s_cdcVcom.deviceHandle); +#endif +#endif +// } +//} diff --git a/source/Peripherals/VCOMHA.h b/source/Peripherals/VCOMHA.h new file mode 100644 index 0000000..4fedf2d --- /dev/null +++ b/source/Peripherals/VCOMHA.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _USB_CDC_VCOM_H_ +#define _USB_CDC_VCOM_H_ 1 + +#include "build.h" +#include "types.h" +#include "ioapi.h" +//#include "usb_device_class.h" +//#include "usb_device_descriptor.h" + +/******************************************************************************* +* Definitions +******************************************************************************/ +//#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0) +//#define CONTROLLER_ID kUSB_ControllerEhci0 +//#define DATA_BUFF_SIZE HS_CDC_VCOM_BULK_OUT_PACKET_SIZE +//#endif + + +#define CONTROLLER_ID kUSB_ControllerKhci0 +#define DATA_BUFF_SIZE FS_CDC_VCOM_BULK_OUT_PACKET_SIZE + + +//#if defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U) +//#define CONTROLLER_ID kUSB_ControllerLpcIp3511Fs0 +//#define DATA_BUFF_SIZE FS_CDC_VCOM_BULK_OUT_PACKET_SIZE +//#endif + +//#if defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U) +//#define CONTROLLER_ID kUSB_ControllerLpcIp3511Hs0 +//#define DATA_BUFF_SIZE HS_CDC_VCOM_BULK_OUT_PACKET_SIZE +//#endif + +#define USB_DEVICE_INTERRUPT_PRIORITY (5U) + +/* Currently configured line coding */ +#define LINE_CODING_SIZE (0x07) +#define LINE_CODING_DTERATE (115200) +#define LINE_CODING_CHARFORMAT (0x00) +#define LINE_CODING_PARITYTYPE (0x00) +#define LINE_CODING_DATABITS (0x08) + +/* Communications feature */ +#define COMM_FEATURE_DATA_SIZE (0x02) +#define STATUS_ABSTRACT_STATE (0x0000) +#define COUNTRY_SETTING (0x0000) + +/* Notification of serial state */ +#define NOTIF_PACKET_SIZE (0x08) +#define UART_BITMAP_SIZE (0x02) +#define NOTIF_REQUEST_TYPE (0xA1) + +/* Define the types for application */ +typedef struct _usb_cdc_vcom_struct +{ + usb_device_handle deviceHandle; /* USB device handle. */ + class_handle_t cdcAcmHandle; /* USB CDC ACM class handle. */ + volatile uint8_t attach; /* A flag to indicate whether a usb device is attached. 1: attached, 0: not attached */ + uint8_t speed; /* Speed of USB device. USB_SPEED_FULL/USB_SPEED_LOW/USB_SPEED_HIGH. */ + volatile uint8_t + startTransactions; /* A flag to indicate whether a CDC device is ready to transmit and receive data. */ + uint8_t currentConfiguration; /* Current configuration value. */ + uint8_t currentInterfaceAlternateSetting + [USB_CDC_VCOM_INTERFACE_COUNT]; /* Current alternate setting value for each interface. */ +} usb_cdc_vcom_struct_t; + +/* Define the infomation relates to abstract control model */ +typedef struct _usb_cdc_acm_info +{ + uint8_t serialStateBuf[NOTIF_PACKET_SIZE + UART_BITMAP_SIZE]; /* Serial state buffer of the CDC device to notify the + serial state to host. */ + bool dtePresent; /* A flag to indicate whether DTE is present. */ + uint16_t breakDuration; /* Length of time in milliseconds of the break signal */ + uint8_t dteStatus; /* Status of data terminal equipment */ + uint8_t currentInterface; /* Current interface index. */ + uint16_t uartState; /* UART state of the CDC device. */ +} usb_cdc_acm_info_t; + + +void VCOM_vStart(uint32* const u32Stat); +void VCOM_vRun(uint32* const u32Stat); +void VCOM_vTerminate(uint32* const u32Stat); +void VCOMHA_vSend(IOAPI_tenEHIOResource enEHIOResource, puint8 pu8Data, uint32 u32TXByteCount); + +#endif /* _USB_CDC_VCOM_H_ */ diff --git a/source/Peripherals/WDTHA.c b/source/Peripherals/WDTHA.c new file mode 100644 index 0000000..ab0f231 --- /dev/null +++ b/source/Peripherals/WDTHA.c @@ -0,0 +1,42 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: WDTHA */ +/* DESCRIPTION: This code provides watchdog functions abstraction */ +/* layer */ +/* FILE NAME: WDTHA.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include "WDTHA.h" + +void WDTHA_vStart(uint16 u16ResetVal, uint16 u16WindowVal) +{ +#ifdef BUILD_SAM3X8E + Wdt* pstWDT = WDT; + uint32 u32Mode = 0; + + if (0 == u16ResetVal) + { + u32Mode = WDT_MR_WDDIS; + } + + wdt_init(pstWDT, u32Mode, u16ResetVal, u16WindowVal); +#endif //BUILD_SAM3X8E +} + +bool WDTHA_boReset(uint16 u32InputVal) +{ +#ifdef BUILD_SAM3X8E + Wdt* pstWDT = WDT; + + wdt_restart(pstWDT); + + return TRUE; +#endif //BUILD_SAM3X8E + + return FALSE; +} + diff --git a/source/Peripherals/WDTHA.h b/source/Peripherals/WDTHA.h new file mode 100644 index 0000000..b3ef783 --- /dev/null +++ b/source/Peripherals/WDTHA.h @@ -0,0 +1,33 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: WDTHA header file */ +/* DESCRIPTION: This code provides watchdog functions abstraction */ +/* layer */ +/* FILE NAME: WDTHA.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef WDTHA_H +#define WDTHA_H + +#include "types.h" +#include "declarations.h" + +#ifdef BUILD_SAM3X8E +#include "wdt.h" +#endif //BUILD_SAM3X8E + +#ifdef BUILD_MK64 +#include "mk64f12.h" +#endif //BUILD_MK64 + +void WDTHA_vStart(uint16, uint16); +bool WDTHA_boReset(uint16); + +#endif //WDTHA_H + + + diff --git a/source/Peripherals/peradc.h b/source/Peripherals/peradc.h new file mode 100644 index 0000000..c03eb1a --- /dev/null +++ b/source/Peripherals/peradc.h @@ -0,0 +1,49 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: ADC Header File */ +/* DESCRIPTION: ADC */ +/* FILE NAME: ADC.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef PERADC_H +#define PERADC_H + +#include "ADCAPI.h" +#include "IOAPI.h" +#include "SYSAPI.h" +#include "types.h" + +#define ADC_nCalFromRecord 1 + +typedef enum +{ + ADC_enqueueChannelErr, + ADC_enqueueQueueFullErr +} ADC_tenEnqueueErr; + + +typedef struct +{ + IOAPI_tenEHIOResource enEHIOResource; + uint32 u32Result; +} ADC_tstADCResult; + + +#define ADC_nConversionsMax 10u +#define ADC_nChannels IO_AD_Count + +void ADC_vStart(uint32* const); +void ADC_vRun(uint32* const); +void ADC_vTerminate(uint32* const); +void ADC_vInterruptHandler(IOAPI_tenEHIOResource, void*); +SYSAPI_tenSVCResult ADC_vInitADCResource(IOAPI_tenEHIOResource, IOAPI_tenEHIOType, ADCAPI_tstADCCB*); +bool ADC_vTriggerQueue(ADCAPI_tenTrigger); +bool ADC_boBackupCalibrations(void); +void ADC_vRunConversionQueueHAs(void); + +#endif //PERADC_H + diff --git a/source/Suites/UDS/Include/UDSAL.h b/source/Suites/UDS/Include/UDSAL.h new file mode 100644 index 0000000..d1b731c --- /dev/null +++ b/source/Suites/UDS/Include/UDSAL.h @@ -0,0 +1,289 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef UDSAL_H +#define UDSAL_H + +//#include "ADC.h" +#include "build.h" +#include "client.h" +#include "COMMONNL.h" +#include "CQUEUE.h" +#include "declarations.h" +//#include "DIAG.h" +#include "DIAGAPI.h" +#include "DLL.h" +#include "FEE.h" +#include "KERNELDIAG.h" +#include "CPUAbstract.h" +#include "MSG.h" +#include "OS.h" +#include "types.h" +#include "UDSNL.h" +#include "UDSSL.h" + + +#define UDSAL_COMMON_BUFF_SIZE 21 +#define UDSAL_READ_TRANSFER_SIZE 32 +#define UDSAL_WRITE_TRANSFER_SIZE 32 + +#ifdef BUILD_PBL + #define UDSAL_DL_BUFF_SIZE 32768 +#else + #define UDSAL_DL_BUFF_SIZE 1 +#endif + + +#define UDSAL_DDDI_CID_START 0x9000 +#define UDSAL_DDDI_CID_END 0x9FFF + +#if defined(BUILD_KERNEL_APP) + #define UDSAL_nDDDICacheCount 1 + #define UDSAL_nDDDICacheSize 0x80 +#elif defined(BUILD_KERNEL) + #define UDSAL_nDDDICacheCount 4 + #define UDSAL_nDDDICacheSize 0x150 +#elif defined(BUILD_SBL) + #define UDSAL_nDDDICacheCount 1 + #define UDSAL_nDDDICacheSize 0x150 +#elif defined(BUILD_PBL) + #define UDSAL_nDDDICacheCount 1 + #define UDSAL_nDDDICacheSize 0x80 +#endif + +//UDS supported services +#define UDSAL_SID_MODE1 0x01 +#define UDSAL_SID_MODE2 0x02 +#define UDSAL_SID_MODE3 0x03 +#define UDSAL_SID_MODE4 0x04 +#define UDSAL_SID_MODE6 0x06 +#define UDSAL_SID_MODE7 0x07 +#define UDSAL_SID_DSC 0x10 +#define UDSAL_SID_ER 0x11 +#define UDSAL_SID_RDTCREC 0x12 +#define UDSAL_SID_CLRDTCINF 0x14 +#define UDSAL_SID_RDTCSTAT 0x17 +#define UDSAL_SID_RSTATBYDTC 0x18 +#define UDSAL_SID_RECUID 0x1A +#define UDSAL_SID_STPUDSAL 0x20 +#define UDSAL_SID_RDBI 0x22 +#define UDSAL_SID_RMBA 0x23 +#define UDSAL_SID_SA 0x27 +#define UDSAL_SID_CC 0x28 +#define UDSAL_SID_DDDI 0x2C +#define UDSAL_SID_WDBI 0x2E +#define UDSAL_SID_IOBCID 0x2F +#define UDSAL_SID_IOBLID 0x30 +#define UDSAL_SID_RC 0x31 +#define UDSAL_SID_RD 0x34 +#define UDSAL_SID_RU 0x35 +#define UDSAL_SID_TD 0x36 +#define UDSAL_SID_RTE 0x37 +#define UDSAL_SID_WMBA 0x3D +#define UDSAL_SID_TP 0x3E +#define UDSAL_SID_CNTRDTC 0x85 +#define UDSAL_SID_INSTRSTAT 0xA2 +#define UDSAL_SID_INSTRBLID 0xA5 +#define UDSAL_SID_RBDYNLID 0xAA +#define UDSAL_SID_INSTRBCID 0xB2 +#define UDSAL_SID_COUNT 34 + +//UDS subservice +#define UDSAL_SSID_RC_STR 0x01 +#define UDSAL_SSID_RC_STPR 0x02 +#define UDSAL_SSID_RC_RRR 0x03 + +#define UDSAL_DDDI_SSID_DMBA 0x02 + +//UDS routine user IDs +#define UDSAL_RCUID_RUN_DL 0x9000 +#define UDSAL_RCUID_PARTITION 0x9001 +#define UDSAL_RCUID_WORK_TO_NVM 0x9002 +#define UDSAL_RCUID_CLEAR_NVM 0x9003 +#define UDSAL_RCUID_BCKP_ADCCAL 0x9080 + +//UDS response code +#define UDSAL_RSP_GR 0x10 +#define UDSAL_RSP_SNS 0x11 +#define UDSAL_RSP_SFNS 0x12 +#define UDSAL_RSP_IMLOIF 0x13 +#define UDSAL_RSP_RTL 0x14 +#define UDSAL_RSP_BRR 0x21 +#define UDSAL_RSP_CNC 0x22 +#define UDSAL_RSP_RSE 0x24 +#define UDSAL_RSP_NRFSC 0x25 +#define UDSAL_RSP_FPEORA 0x26 +#define UDSAL_RSP_ROOR 0x31 +#define UDSAL_RSP_SAD 0x33 +#define UDSAL_RSP_IK 0x35 +#define UDSAL_RSP_ENOA 0x36 +#define UDSAL_RSP_RTDNE 0x37 +#define UDSAL_RSP_TDS 0x71 +#define UDSAL_RSP_GPF 0x72 +#define UDSAL_RSP_WBSC 0x73 +#define UDSAL_RSP_RCRRP 0x78 +#define UDSAL_RSP_SFNSIAS 0x7E +#define UDSAL_RSP_SNSIAS 0x7F +#define UDSAL_RSP_NSUPINSESS 0x80 +#define UDSAL_RSP_SUPPRESS 0xFD +#define UDSAL_RSP_FLOW 0xFE +#define UDSAL_RSP_OK 0xFF + +//buffer index breakdown +#define UDSAL_IDX_LEN 0x00 +#define UDSAL_IDX_SID 0x02 +#define UDSAL_IDX_SUBSID 0x03 +#define UDSAL_IDX_RW_CID 0x04 +#define UDSAL_IDX_RW_DATA 0x05 + +//diag MSG IDs +#define UDSAL_ID_UDSAL 0x0C6 +#define UDSAL_ID_UDSAL_EXT false +#define UDSAL_ID_FUNC 0x7DF + +typedef uint8 (*pfUDSALProcess)(puint8, uint32, puint8, puint32, uint32); + +typedef enum +{ + UDSAL_enPBLContext, + UDSAL_enSBLContext, + UDSAL_enAppContext +} UDSAL_tenContext; + +typedef BUILD_PACKING struct +{ + uint8 u8Service; + uint8 u8BytesMin; + uint8 u8BytesMax; + uint8 u8BytesResp; + UDSAL_tenContext enContext; + pfUDSALProcess pfProcess; +} UDSAL_tstALProcessInfo; + +typedef struct +{ + COMMONNL_tstRXLargeBuffer* pstSourceBuffer; + uint8* pu8TargetAddress; + uint32 u32AccumulateCount; + uint32 u32WriteCount; + bool boPending; + bool boComplete; +} UDSAL_tstDLControlBlock; + + +#define UDSAL_nALProcessInfo \ +{ \ + { UDSAL_SID_MODE1 , 0, 0, 6, UDSAL_enPBLContext, UDSAL_u8MODE1 }, \ + { UDSAL_SID_MODE2 , 0, 0, 6, UDSAL_enPBLContext, UDSAL_u8MODE2 }, \ + { UDSAL_SID_MODE3 , 0, 0, 6, UDSAL_enPBLContext, UDSAL_u8MODE3 }, \ + { UDSAL_SID_MODE4 , 0, 0, 0, UDSAL_enPBLContext, UDSAL_u8MODE4 }, \ + { UDSAL_SID_MODE6 , 0, 0, 0, UDSAL_enPBLContext, UDSAL_u8MODE6 }, \ + { UDSAL_SID_MODE7 , 0, 0, 0, UDSAL_enPBLContext, UDSAL_u8MODE7 }, \ + { UDSAL_SID_DSC , 0, 0, 0, UDSAL_enPBLContext, UDSAL_u8SESSION }, \ + { UDSAL_SID_ER , 0, 0, 0, UDSAL_enPBLContext, UDSAL_u8RESET }, \ + { UDSAL_SID_RDTCREC , 0, 0, 0, UDSAL_enPBLContext, NULL }, \ + { UDSAL_SID_CLRDTCINF , 0, 0, 0, UDSAL_enPBLContext, NULL }, \ + { UDSAL_SID_RDTCSTAT , 0, 0, 0, UDSAL_enPBLContext, NULL }, \ + { UDSAL_SID_RSTATBYDTC , 0, 0, 0, UDSAL_enPBLContext, NULL }, \ + { UDSAL_SID_RECUID , 0, 0, 0, UDSAL_enPBLContext, NULL }, \ + { UDSAL_SID_STPUDSAL , 0, 0, 0, UDSAL_enPBLContext, NULL }, \ + { UDSAL_SID_RDBI , 0, 0, 0xff, UDSAL_enPBLContext, UDSAL_u8RDBI }, \ + { UDSAL_SID_RMBA , 0, 0, 0xff, UDSAL_enPBLContext, UDSAL_u8RMBA }, \ + { UDSAL_SID_WMBA , 0, 0, 0xff, UDSAL_enPBLContext, UDSAL_u8WMBA }, \ + { UDSAL_SID_SA , 0, 0, 0, UDSAL_enPBLContext, NULL }, \ + { UDSAL_SID_CC , 0, 0, 0, UDSAL_enPBLContext, NULL }, \ + { UDSAL_SID_DDDI , 0, 0, 4, UDSAL_enAppContext, UDSAL_u8DDDI }, \ + { UDSAL_SID_WDBI , 0, 0, 3, UDSAL_enPBLContext, UDSAL_u8WDBI }, \ + { UDSAL_SID_IOBCID , 0, 0, 0, UDSAL_enPBLContext, NULL }, \ + { UDSAL_SID_IOBLID , 0, 0, 0, UDSAL_enPBLContext, NULL }, \ + { UDSAL_SID_RC , 0, 0, 5, UDSAL_enPBLContext, UDSAL_u8RC }, \ + { UDSAL_SID_RD , 0, 0, 4, UDSAL_enPBLContext, UDSAL_u8DLREQ }, \ + { UDSAL_SID_RU , 0, 0, 0, UDSAL_enPBLContext, NULL }, \ + { UDSAL_SID_TD , 0, 0, 2, UDSAL_enPBLContext, UDSAL_u8TFREQ }, \ + { UDSAL_SID_RTE , 0, 0, 3, UDSAL_enPBLContext, UDSAL_u8TFEXREQ }, \ + { UDSAL_SID_TP , 0, 0, 2, UDSAL_enPBLContext, UDSAL_u8TP }, \ + { UDSAL_SID_CNTRDTC , 0, 0, 0, UDSAL_enPBLContext, NULL }, \ + { UDSAL_SID_INSTRSTAT , 0, 0, 0, UDSAL_enPBLContext, NULL }, \ + { UDSAL_SID_INSTRBLID , 0, 0, 0, UDSAL_enPBLContext, NULL }, \ + { UDSAL_SID_RBDYNLID , 0, 0, 0, UDSAL_enPBLContext, NULL }, \ + { UDSAL_SID_INSTRBCID , 0, 0, 0, UDSAL_enPBLContext, NULL } \ +} + +#define UDSAL_nMode1InfoByteOffset \ +{\ + 0,\ + 4,\ + 8,\ + 10,\ + 12,\ + 13,\ + 14,\ + 15,\ + 16,\ + 17,\ + 18,\ + 19,\ + 20,\ + 22,\ + 23,\ + 24,\ + 25,\ + 27,\ + 28,\ + 29,\ + 30,\ + 32,\ + 34,\ + 36,\ + 38,\ + 40,\ + 42,\ + 44,\ + 46,\ + 47,\ + 48,\ + 49,\ + 51,\ + 55,\ + 57,\ + 59,\ + 61,\ + 65,\ + 69,\ + 73,\ + 77,\ + 81,\ + 85,\ + 89,\ + 93,\ + 94,\ + 95,\ + 96,\ + 97,\ + 98,\ + 100,\ + 102,\ + 103,\ + 107\ +} + +#define UDSAL_xCalcBytesFree() \ +u32TXCap - *pu32TXByteCount - u32TransferByteCount + + +//public functions +void UDSAL_vProcessBufferCB(puint8, uint32, puint8, puint32, uint32); +void UDSAL_vStart(puint32 const); +void UDSAL_vRun(puint32 const); +void UDSAL_vTerminate(puint32 const); + +#endif // UDSAL_H + diff --git a/source/Suites/UDS/Include/UDSNL.h b/source/Suites/UDS/Include/UDSNL.h new file mode 100644 index 0000000..65a5b5d --- /dev/null +++ b/source/Suites/UDS/Include/UDSNL.h @@ -0,0 +1,51 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef UDSNL_H +#define UDSNL_H + +#include "COMMONNL.h" +#include "UDSAL.h" + +#define UDSNL_SMALL_BUFF_SIZE 8u +#define UDSNL_RX_BUFF_LARGE_SIZE 1030u +#define UDSNL_TX_BUFF_LARGE_SIZE 258u +#define UDSNL_nActiveResourceTimeout 5000u + + +typedef enum +{ + UDSNL_enSegRXModeSmall, + UDSNL_enSegRXModeLarge, + UDSNL_enSegRXModeInvalid, + USDNL_enSegRXErr +} UDSNL_tenSegRXMode; + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _UDSNL_C + #define EXTERN +#else + #define EXTERN extern +#endif + +EXTERN COMMONNL_tstRXLargeBuffer UDSNL_stRXLargeBuffer; +EXTERN COMMONNL_tstTXLargeBuffer UDSNL_stTXLargeBuffer; +EXTERN COMMONNL_tstRXSmallBuffer UDSNL_stRXSmallBuffer; +EXTERN COMMONNL_tstTXSmallBuffer UDSNL_stTXSmallBuffer; + +void UDSNL_vStart(void); +void UDSNL_vReceiveFrame(IOAPI_tenEHIOResource, puint8, puint8, puint32, uint32); +void UDSNL_vActiveResourceTimeout(void); +uint32 UDSNL_u32GetTransmissionBytesRequired(uint32); + +#endif //UDSNL_H diff --git a/source/Suites/UDS/Include/UDSSL.h b/source/Suites/UDS/Include/UDSSL.h new file mode 100644 index 0000000..8770ca0 --- /dev/null +++ b/source/Suites/UDS/Include/UDSSL.h @@ -0,0 +1,51 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef UDSSL_H +#define UDSSL_H + +#include "COMMONNL.h" +#include "DECLARATIONS.h" +#include "DIAGAPI.h" +#include "DLL.h" +#include "TIMER.h" +#include "TYPES.h" +#include "OS.h" +#include "UDSAL.h" +#include "UDSNL.h" + +//buffer index breakdown +#define UDSSL_IDX_LEN 0x00 +#define UDSSL_IDX_SID 0x01 +#define UDSSL_IDX_SUBSID 0x02 + +//UDS session definitions +#define UDSSL_SESS_DFLT 0x81 +#define UDSSL_SESS_PGM 0x85 +#define UDSSL_SESS_EXT 0x87 + +#define UDSSL_nSessionTimeout 5000u + + +typedef struct +{ + uint32 u32TimerIDX; + DIAGAPI_tenSession enSession; +} UDSSL_tstSessionCB; + +void UDSSL_vStart(void); +void UDSSL_vProcessBufferCB(puint8, uint32, puint8, puint32, uint32); +DIAGAPI_tenSession UDSSL_enGetSession(void); +void UDSSL_vResetSessionTimer(void); +void UDSSL_vSessionTimeout(void); + +#endif //UDSSL_H + diff --git a/source/Suites/UDS/UDSAL.c b/source/Suites/UDS/UDSAL.c new file mode 100644 index 0000000..7ed8227 --- /dev/null +++ b/source/Suites/UDS/UDSAL.c @@ -0,0 +1,1139 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _UDSAL_C +#include +#include "mk64f12.h" +#include +#include "UDSAL.h" + +#if BUILD_PBL +#include "ECUHostA_PBL.h" +#endif + +unsigned char UDSAL_ucActiveSession; +uint8 UDSAL_u8TransferBlock; +DIAGAPI_tstDataTransferCB UDSAL_stReadDataTransferCB; +DIAGAPI_tstDataTransferCB UDSAL_stWriteDataTransferCB; +uint8 UDSAL_au8ReadTransferData[UDSAL_READ_TRANSFER_SIZE]; +uint8 UDSAL_au8WriteTransferData[UDSAL_WRITE_TRANSFER_SIZE]; +MSG_tstMBX* UDSAL_pstMBXReadTransfer; +MSG_tstMBX* UDSAL_pstMBXWriteTransfer; +UDSAL_tstDLControlBlock UDSAL_stDLControlBlock; +CQUEUE_tstQueue UDSAL_astDDDICacheQueue[UDSAL_nDDDICacheCount]; +uint16 UDSAL_au16DDDICacheSIDs[UDSAL_nDDDICacheCount]; +uint8 UDSAL_au8DDDICache[UDSAL_nDDDICacheCount][UDSAL_nDDDICacheSize]; + +bool UDSAL_boRDBICaching; + +static uint8 UDSAL_u8MODE1(puint8, uint32, puint8, puint32, uint32); +static uint8 UDSAL_u8MODE2(puint8, uint32, puint8, puint32, uint32); +static uint8 UDSAL_u8MODE3(puint8, uint32, puint8, puint32, uint32); +static uint8 UDSAL_u8MODE4(puint8, uint32, puint8, puint32, uint32); +static uint8 UDSAL_u8MODE6(puint8, uint32, puint8, puint32, uint32); +static uint8 UDSAL_u8MODE7(puint8, uint32, puint8, puint32, uint32); +static uint8 UDSAL_u8RESET(puint8, uint32, puint8, puint32, uint32); +static uint8 UDSAL_u8RDBI(puint8, uint32, puint8, puint32, uint32); +static uint8 UDSAL_u8RMBA(puint8, uint32, puint8, puint32, uint32); +static uint8 UDSAL_u8WMBA(puint8, uint32, puint8, puint32, uint32); +static uint8 UDSAL_u8WDBI(puint8, uint32, puint8, puint32, uint32); +static uint8 UDSAL_u8DLREQ(puint8, uint32, puint8, puint32, uint32); +static uint8 UDSAL_u8TFREQ(puint8, uint32, puint8, puint32, uint32); +static uint8 UDSAL_u8TP(puint8, uint32, puint8, puint32, uint32); +static uint8 UDSAL_u8SESSION(puint8, uint32, puint8, puint32, uint32); +static uint8 UDSAL_u8DDDI(puint8, uint32, puint8, puint32, uint32); +static uint8 UDSAL_u8RC(puint8, uint32, puint8, puint32, uint32); +static uint8 UDSAL_u8TFEXREQ(puint8, uint32, puint8, puint32, uint32); +static void UDSAL_vResponse(puint8, uint8, uint8, puint32, uint32); +static void UDSAL_vConfigureDDDICache(uint16, uint8); +static sint32 UDSAL_i32GetDDDICacheIndex(uint16); +#if (BUILD_SBL) +static Bool UDSAL_boWriteDLBlock(COMMONNL_tstRXLargeBuffer* const, + uint8* const, + uint32); +#endif +#if (BUILD_SBL) || defined(BUILD_PBL) +static Bool UDSAL_boUpdateDLBlock(uint32); +#endif + +uint8 UDSAL_au8Mode1DataBuffer[256]; +uint8 UDSAL_au8Mode2DataBuffer[256]; +uint8 UDSAL_au8Mode3DataBuffer[256]; +uint8 UDSAL_au8Mode4DataBuffer[256]; +const UDSAL_tstALProcessInfo UDSAL_rastALProcessInfo[UDSAL_SID_COUNT] = UDSAL_nALProcessInfo; +const uint16 UDSAL_ru16Mode1DataOffsets[] = UDSAL_nMode1InfoByteOffset; + +void UDSAL_vProcessBufferCB(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + uint8 u8ServiceIDX; + uint8 u8Response = UDSAL_RSP_SNSIAS; +#ifdef BUILD_PBL + UDSAL_tenContext enContext = UDSAL_enPBLContext; +#endif +#ifdef BUILD_SBL + UDSAL_tenContext enContext = UDSAL_enSBLContext; +#endif +#ifdef BUILD_KERNEL + UDSAL_tenContext enContext = UDSAL_enAppContext; +#endif +#ifdef BUILD_KERNEL_APP + UDSAL_tenContext enContext = UDSAL_enAppContext; +#endif + + for (u8ServiceIDX = 0; u8ServiceIDX < UDSAL_SID_COUNT; u8ServiceIDX++) + { + if ((*(pu8RXBuffer + UDSAL_IDX_SID)) == UDSAL_rastALProcessInfo[u8ServiceIDX].u8Service) + { + if ((NULL != UDSAL_rastALProcessInfo[u8ServiceIDX].pfProcess) && + (enContext >= UDSAL_rastALProcessInfo[u8ServiceIDX].enContext)) + { + /* Copy the RX frame to the TX frame and make + room for response length word */ + memcpy(pu8TXBuffer, pu8RXBuffer, u32RXDataCount + 2); + //u32RXDataCount = 0x100 * *(pu8RXBuffer + UDSAL_IDX_LEN) + *(pu8RXBuffer + UDSAL_IDX_LEN + 1) + u8Response = (*UDSAL_rastALProcessInfo[u8ServiceIDX].pfProcess)(pu8RXBuffer, u32RXDataCount, pu8TXBuffer, pu32TXByteCount, u32TXCap); +#if BUILD_PBL + ECUHOSTAPBL_boLatchDiag = true; +#endif + break; + } + else + { +#if BUILD_PBL + ECUHOSTAPBL_boLatchDiag = true; +#endif + u8Response = UDSAL_RSP_CNC; + break; + } + } + } + + UDSAL_vResponse(pu8TXBuffer, u8Response, u8ServiceIDX, pu32TXByteCount, u32TXCap); + +} + +static uint8 UDSAL_u8MODE1(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + uint8 u8DataBytes = 0; + + //switch (*(pu8RXBuffer + 3)) + //{ + //case 0: + //{ + // *(pu8TXBuffer + 1) = 0x06; + // *(pu8TXBuffer + 4) = 0xff; + // *(pu8TXBuffer + 5) = 0xff; + // *(pu8TXBuffer + 6) = 0xff; + // *(pu8TXBuffer + 7) = 0xff; + // *pu32TXByteCount += 8; + // break; + // } + // default: + // { + u8DataBytes = UDSAL_ru16Mode1DataOffsets[*(pu8RXBuffer + 3) + 1] - UDSAL_ru16Mode1DataOffsets[*(pu8RXBuffer + 3)]; + *(pu8TXBuffer + 1) = u8DataBytes + 2; + memcpy(pu8TXBuffer + 4, &UDSAL_au8Mode1DataBuffer[UDSAL_ru16Mode1DataOffsets[*(pu8RXBuffer + 3)]], u8DataBytes); + *pu32TXByteCount += 8; + //break; + // } + //} + + return UDSAL_RSP_OK; +} + +static uint8 UDSAL_u8MODE2(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + switch (*(pu8RXBuffer + 3)) + { + case 0: + { + *(pu8TXBuffer + 1) = 0x06; + *(pu8TXBuffer + 4) = 0x0; + *(pu8TXBuffer + 5) = 0x0; + *(pu8TXBuffer + 6) = 0x0; + *(pu8TXBuffer + 7) = 0x0; + *pu32TXByteCount += 8; + break; + } + default: + { + break; + } + } + + return UDSAL_RSP_OK; +} + +static uint8 UDSAL_u8MODE3(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + switch (*(pu8RXBuffer + 3)) + { + case 0: + { + *(pu8TXBuffer + 1) = 0x06; + *(pu8TXBuffer + 4) = 0x0; + *(pu8TXBuffer + 5) = 0x0; + *(pu8TXBuffer + 6) = 0x0; + *(pu8TXBuffer + 7) = 0x0; + *pu32TXByteCount += 8; + break; + } + default: + { + break; + } + } + + return UDSAL_RSP_OK; +} + +static uint8 UDSAL_u8MODE4(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + switch (*(pu8RXBuffer + 3)) + { + case 0: + { + *(pu8TXBuffer + 1) = 0x06; + *(pu8TXBuffer + 4) = 0x0; + *(pu8TXBuffer + 5) = 0x0; + *(pu8TXBuffer + 6) = 0x0; + *(pu8TXBuffer + 7) = 0x0; + *pu32TXByteCount += 8; + break; + } + default: + { + break; + } + } + + return UDSAL_RSP_OK; +} + +static uint8 UDSAL_u8MODE6(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + switch (*(pu8RXBuffer + 3)) + { + case 0: + { + *(pu8TXBuffer + 1) = 0x06; + *(pu8TXBuffer + 4) = 0x0; + *(pu8TXBuffer + 5) = 0x0; + *(pu8TXBuffer + 6) = 0x0; + *(pu8TXBuffer + 7) = 0x0; + *pu32TXByteCount += 8; + break; + } + default: + { + break; + } + } + + return UDSAL_RSP_OK; +} + +static uint8 UDSAL_u8MODE7(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + switch (*(pu8RXBuffer + 3)) + { + case 0: + { + *(pu8TXBuffer + 1) = 0x06; + *(pu8TXBuffer + 4) = 0x0; + *(pu8TXBuffer + 5) = 0x0; + *(pu8TXBuffer + 6) = 0x0; + *(pu8TXBuffer + 7) = 0x0; + *pu32TXByteCount += 8; + break; + } + default: + { + break; + } + } + + return UDSAL_RSP_OK; +} + +static uint8 UDSAL_u8RESET(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + uint8 u8Response = UDSAL_RSP_NSUPINSESS; + + if ((DIAGAPI_enProgramming == UDSSL_enGetSession()) || + (DIAGAPI_enExtendedSession == UDSSL_enGetSession())) + { + u8Response = UDSAL_RSP_OK; + } + + return u8Response; +} + + +static uint8 UDSAL_u8RDBI(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + uint8 u8Response = UDSAL_RSP_BRR; + uint8 u8DDDIRecsIDX; + uint8 u8DDDIIDX; + puint8 pu8DDDIData; + puint8 pu8RDBIAddress = 0; + uint32 u32TransferByteCount = 3; + uint32 u32BufferBytesFree; + uint16 u16CID; + uint32 u32Temp; + puint8 pu8DDDIResultBuff; + sint16 s16DDDICacheIndex; + + u32BufferBytesFree = UDSAL_xCalcBytesFree(); + + u16CID = *(pu8RXBuffer + UDSAL_IDX_RW_CID - 1) + 0x100 * *(pu8RXBuffer + UDSAL_IDX_RW_CID); + + if ((UDSAL_DDDI_CID_START <= u16CID) && (UDSAL_DDDI_CID_END >= u16CID)) + { + for (u8DDDIIDX = 0; u8DDDIIDX < DIAG_DDDI_COUNT; u8DDDIIDX++) + { + if (u16CID == DIAG_astDDDI[u8DDDIIDX].u16DDI) + { + pu8DDDIData = (puint8)&DIAG_astDDDI[u8DDDIIDX].u8Data; + pu8TXBuffer += UDSAL_IDX_RW_DATA; + s16DDDICacheIndex = UDSAL_i32GetDDDICacheIndex(u16CID); + + if ((-1 != s16DDDICacheIndex) && (!CQUEUE_xIsEmpty(UDSAL_astDDDICacheQueue + s16DDDICacheIndex)) && (false == UDSAL_boRDBICaching)) + /* Respond from the data cache */ + { + u32Temp = (uint32)UDSAL_astDDDICacheQueue[s16DDDICacheIndex].pvData; + u32Temp += (16 * UDSAL_astDDDICacheQueue[s16DDDICacheIndex].u32Head); + pu8DDDIResultBuff = (puint8)u32Temp; + memcpy(pu8TXBuffer, pu8DDDIResultBuff, DIAG_astDDDI[u8DDDIIDX].u8ByteCount); + CQUEUE_xRemoveItem(UDSAL_astDDDICacheQueue + s16DDDICacheIndex); + u32TransferByteCount += DIAG_astDDDI[u8DDDIIDX].u8ByteCount; + pu8TXBuffer += DIAG_astDDDI[u8DDDIIDX].u8ByteCount; + } + else + /* Respond per live DDDI */ + { + for (u8DDDIRecsIDX = 0; u8DDDIRecsIDX < DIAG_astDDDI[u8DDDIIDX].u8RecsCount; u8DDDIRecsIDX++) + { + if (4 == (DIAG_astDDDI[u8DDDIIDX].u8AddressAndLength & 0x0f)) + { + memcpy(&pu8RDBIAddress, pu8DDDIData, 4); + pu8DDDIData += 4; + } + else if (2 == (DIAG_astDDDI[u8DDDIIDX].u8AddressAndLength & 0x0f)) + { + memcpy(&pu8RDBIAddress, pu8DDDIData, 2); + pu8DDDIData += 2; + } + else if (1 == (DIAG_astDDDI[u8DDDIIDX].u8AddressAndLength & 0x0f)) + { + memcpy(&pu8RDBIAddress, pu8DDDIData, 1); + pu8DDDIData++; + } + + if (*pu8DDDIData < u32BufferBytesFree) + { + if (NULL != pu8RDBIAddress) + { + memcpy(pu8TXBuffer, pu8RDBIAddress, *pu8DDDIData); + } + u32TransferByteCount += (uint32)*pu8DDDIData; + u32BufferBytesFree -= (uint32)*pu8DDDIData; + pu8TXBuffer += (uint8)*pu8DDDIData; + pu8DDDIData++; + } + } + } + + /* Calculate the new TX byte count prior to segmentation */ + *pu32TXByteCount += u32TransferByteCount; + u8Response = UDSAL_RSP_OK; + break; + } + } + } + else + { + if (TRUE == UDSAL_stReadDataTransferCB.boTransferComplete) + { + UDSAL_stReadDataTransferCB.boTransferComplete = FALSE; + UDSAL_stReadDataTransferCB.pu8Data = &UDSAL_au8ReadTransferData[0]; + u16CID = 0x100 * (*(pu8RXBuffer)) + *(pu8RXBuffer + 1); + } + } + + return u8Response; +} + +static uint8 UDSAL_u8RMBA(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + uint8 u8Response; + uint8 u8AddressAndLength; + uint32 u32AddressData = 0; + uint32 u32TransferByteCount = 2; + uint32 u32DataMask; + uint32 u32BufferBytesFree; + uint32 u32BufferBytesRequired = 2; + uint8 u8IDX; + puint8 pu8Source = pu8RXBuffer + 3; + uint32 u8AddressLength = 0; + + u32BufferBytesFree = UDSAL_xCalcBytesFree(); + + u8AddressAndLength = *(pu8Source++); + u32DataMask = 1; + + /* Grab the address data */ + for (u8IDX = 0; u8IDX < (u8AddressAndLength & 0x0f); u8IDX++) + { + u32AddressData += *(pu8Source++) * u32DataMask; + u32DataMask *= 0x100; + u8AddressLength++; + } + + u32DataMask = 1; + + for (u8IDX = 0; u8IDX < (u8AddressAndLength >> 4); u8IDX++) + { + u32TransferByteCount += *(pu8Source++) * u32DataMask; + u32DataMask *= 0x100; + } + + u32TransferByteCount += u8AddressLength; + u32BufferBytesRequired += UDSNL_u32GetTransmissionBytesRequired(u32TransferByteCount); + + if (u32BufferBytesFree >= u32BufferBytesRequired) + { + memcpy(pu8TXBuffer + 3 + u8AddressLength, (void*)u32AddressData, u32TransferByteCount); + + for (u8IDX = 0; u8IDX < u8AddressLength; u8IDX++) + { + *(pu8TXBuffer + 3 + u8IDX) = u32AddressData & 0xff; + u32AddressData = u32AddressData >> 8; + } + + u8Response = UDSAL_RSP_OK; + *pu8TXBuffer = u32TransferByteCount / 0x100; + *(pu8TXBuffer + 1) = u32TransferByteCount % 0x100; + *pu32TXByteCount += u32TransferByteCount; + } + else + { + u8Response = UDSAL_RSP_ROOR; + } + + return u8Response; +} + +static uint8 UDSAL_u8WMBA(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + uint8 u8Response; + uint8 u8AddressAndLength; + uint32 u32AddressData = 0; + uint32 u32LengthData = 0; + uint32 u32DataMask; + uint32 u32BufferBytesFree; + uint32 u32BufferBytesRequired; + uint8 u8IDX; + puint8 pu8Source = pu8RXBuffer + 3; + uint8 u8AddressLength; + + u8AddressAndLength = *(pu8Source++); + u32DataMask = 1; + + /* Grab the address data */ + for (u8IDX = 0; u8IDX < (u8AddressAndLength & 0x0f); u8IDX++) + { + u32AddressData += *(pu8Source++) * u32DataMask; + u32DataMask *= 0x100; + u8AddressLength++; + } + + u32DataMask = 1; + + for (u8IDX = 0; u8IDX < (u8AddressAndLength >> 4); u8IDX++) + { + u32LengthData += *(pu8Source++) * u32DataMask; + u32DataMask *= 0x100; + } + + u32BufferBytesFree = u32TXCap - *pu32TXByteCount; + u32BufferBytesRequired = 2 + + (u8AddressAndLength & 0x0f) + + (u8AddressAndLength >> 4); + + if (u32BufferBytesFree >= u32BufferBytesRequired) + { + memcpy((void*)u32AddressData, pu8Source, u32LengthData); + u8Response = UDSAL_RSP_OK; + *pu8TXBuffer = u32BufferBytesRequired / 0x100; + *(pu8TXBuffer + 1) = u32BufferBytesRequired % 0x100; + *pu32TXByteCount += u32BufferBytesRequired; + + for (u8IDX = 0; u8IDX < u8AddressLength; u8IDX++) + { + *(pu8TXBuffer + 3 + u8IDX) = u32AddressData & 0xff; + u32AddressData = u32AddressData >> 8; + } + } + else + { + u8Response = UDSAL_RSP_ROOR; + } + + return u8Response; +} + +static uint8 UDSAL_u8WDBI(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + uint8 u8Response = UDSAL_RSP_BRR; + MSG_tenMBXErr enMBXErr = MSG_enOK; + tpfClientCB pfClientCB; + CLIENT_tenErr enErr; + +#if defined(BUILD_KERNEL_OR_KERNEL_APP) + if (TRUE == UDSAL_stWriteDataTransferCB.boTransferComplete) + { + UDSAL_stWriteDataTransferCB.boTransferComplete = FALSE; + UDSAL_stWriteDataTransferCB.pu8Data = &UDSAL_au8WriteTransferData[0]; + UDSAL_stWriteDataTransferCB.u8DataCount = u32RXDataCount - 3; + UDSAL_stWriteDataTransferCB.u16CID = 0x100 * (*(pu8RXBuffer + UDSAL_IDX_RW_CID - 1)) + *(pu8RXBuffer + UDSAL_IDX_RW_CID); + memcpy((void*)&UDSAL_au8WriteTransferData[0], + (void*)(pu8RXBuffer + UDSAL_IDX_RW_DATA - 1), + u32RXDataCount - 3); + + /* Check if a mailbox is allocated for diag writes */ + if (NULL == UDSAL_pstMBXWriteTransfer) + { + enMBXErr = MSG_enMBXNew((MSG_tstMBX**)&UDSAL_pstMBXWriteTransfer, + MSG_enDiagDataWrite); + } + + if (MSG_enOK == enMBXErr) + { + MSG_vMBXPost(UDSAL_pstMBXWriteTransfer, (void*)&UDSAL_stWriteDataTransferCB); + pfClientCB = (tpfClientCB)DIAG_DataWriteCB; + + if ((NULL != pfClientCB) && (MSG_boMBXValid(UDSAL_pstMBXWriteTransfer))) + { + enErr = CLIENT_enEnqueueCB(UDSAL_pstMBXWriteTransfer, pfClientCB); + u8Response = (CLIENT_enOK == enErr) ? UDSAL_RSP_OK : UDSAL_RSP_GR; + } + } + else + { + u8Response = UDSAL_RSP_GR; + } + } + else + { + u8Response = UDSAL_RSP_CNC; + } +#endif + + *pu32TXByteCount += 8; + + return u8Response; +} + +static uint8 UDSAL_u8DLREQ(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + uint8 u8Response = 0; + uint32 u32Data; + uint32 u32DataCount; + COMMONNL_tstRXLargeBuffer* pstSourceBuffer; + uint8* pu8TargetAddr; + bool boDLReqErr; + const uint32 ru32AddrMin = BUILD_DL_ADDR_MIN; + const uint32 ru32AddrMax = BUILD_DL_ADDR_MAX; + + u32Data = pu8RXBuffer[5] << 24 + | pu8RXBuffer[6] << 16 + | pu8RXBuffer[7] << 8 + | pu8RXBuffer[8]; + u32DataCount = pu8RXBuffer[9] << 24 + | pu8RXBuffer[10] << 16 + | pu8RXBuffer[11] << 8 + | pu8RXBuffer[12]; + + if ((ru32AddrMin <= u32Data) && + (ru32AddrMax >= (u32Data + u32DataCount - 1))) + { + pu8TargetAddr = (uint8*)u32Data; + pstSourceBuffer = &UDSNL_stRXLargeBuffer; + UDSAL_u8TransferBlock = 0u; + +#if defined(BUILD_KERNEL) + FEE_boWriteControlBlock(pstSourceBuffer, pu8TargetAddr, u32DataCount); + boDLReqErr = FEE_boEraseForDownload(pu8TargetAddr, u32DataCount); +#elif defined(BUILD_KERNEL_APP) + FEE_boWriteControlBlock(pstSourceBuffer, pu8TargetAddr, u32DataCount); + boDLReqErr = FEE_boEraseForDownload(pu8TargetAddr, u32DataCount); +#elif defined(BUILD_SBL) + FEE_boWriteControlBlock(pstSourceBuffer, pu8TargetAddr, u32DataCount); + boDLReqErr = FEE_boEraseForDownload(pu8TargetAddr, u32DataCount); +#elif defined(BUILD_UBL) + FEE_boWriteControlBlock(pstSourceBuffer, pu8TargetAddr, u32DataCount); + boDLReqErr = FEE_boEraseForDownload(pu8TargetAddr, u32DataCount); +#elif defined(BUILD_PBL) + boDLReqErr = UDSAL_boWriteDLBlock(pstSourceBuffer, pu8TargetAddr, u32DataCount); +#endif + + u8Response = (false == boDLReqErr) ? UDSAL_RSP_OK : UDSAL_RSP_ROOR; + } + + *pu32TXByteCount += 8; + return u8Response; +} + +static uint8 UDSAL_u8TFREQ(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + uint8 u8Response = UDSAL_RSP_TDS; + uint8 u8BlockPrev = pu8RXBuffer[3] - 1; + + if (u8BlockPrev != UDSAL_u8TransferBlock) + { +#if defined(BUILD_KERNEL) + FEE_boUpdateControlBlock(0); +#elif defined(BUILD_KERNEL_APP) + FEE_boUpdateControlBlock(0); +#elif defined(BUILD_SBL) + FEE_boUpdateControlBlock(0); +#elif defined(BUILD_UBL) + FEE_boUpdateControlBlock(0); +#elif defined(BUILD_PBL) + UDSAL_boUpdateDLBlock(0); +#endif + + UDSNL_stRXLargeBuffer.biRXErr = true; + u8Response = UDSAL_RSP_WBSC; + } + else + { +#if defined(BUILD_KERNEL) + FEE_boUpdateControlBlock(UDSNL_stRXLargeBuffer.u16RXRequestedCount - 2); +#elif defined(BUILD_KERNEL_APP) + FEE_boUpdateControlBlock(UDSNL_stRXLargeBuffer.u16RXRequestedCount - 2); +#elif defined(BUILD_SBL) + FEE_boUpdateControlBlock(UDSNL_stRXLargeBuffer.u16RXRequestedCount - 2); +#elif defined(BUILD_UBL) + FEE_boUpdateControlBlock(UDSNL_stRXLargeBuffer.u16RXRequestedCount - 2); +#elif defined(BUILD_PBL) + UDSAL_boUpdateDLBlock(UDSNL_stRXLargeBuffer.u16RXRequestedCount - 2); +#endif + + UDSAL_u8TransferBlock++; + u8Response = UDSAL_RSP_OK; + } + + *pu32TXByteCount += 8; + return u8Response; +} + +static uint8 UDSAL_u8SESSION(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + + return 0; +} + +static uint8 UDSAL_u8TP(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + uint8 u8Response; + + switch (*(pu8RXBuffer + UDSAL_IDX_SUBSID)) + { + case 0: + { + u8Response = UDSAL_RSP_OK; + *pu32TXByteCount += 8; + break; + } + case 0x80: + { + u8Response = UDSAL_RSP_SUPPRESS; + break; + } + default: + { + u8Response = UDSAL_RSP_SNSIAS; + *pu32TXByteCount += 8; + break; + } + } + + return u8Response; +} + +static uint8 UDSAL_u8DDDI(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + uint8 u8DDDIIDX; + uint8 u8Response = UDSAL_RSP_SNS; + puint8 pu8Data; + uint16 u16DDDISID; + uint8 u8ResultByteCount = 0; + //sint16 i16RXDataCount = (uint16)u32RXDataCount - 5; + sint16 i16RXDataCount = (uint16)u32RXDataCount; + uint32 u32Temp; + + pu8RXBuffer += 3; + + if (UDSAL_DDDI_SSID_DMBA == *pu8RXBuffer++) + { + u8Response = UDSAL_RSP_CNC; + u16DDDISID = *(pu8RXBuffer++); + u16DDDISID += 0x100 * *(pu8RXBuffer++); + + for (u8DDDIIDX = 0; u8DDDIIDX < DIAG_DDDI_COUNT; u8DDDIIDX++) + { + if ((u16DDDISID == DIAG_astDDDI[u8DDDIIDX].u16DDI) || (0 == DIAG_astDDDI[u8DDDIIDX].u16DDI)) + { + DIAG_astDDDI[u8DDDIIDX].u16DDI = u16DDDISID; + i16RXDataCount -= 5; + DIAG_astDDDI[u8DDDIIDX].u8AddressAndLength = *(pu8RXBuffer++); + DIAG_astDDDI[u8DDDIIDX].u8RecsCount = 0; + pu8Data = &DIAG_astDDDI[u8DDDIIDX].u8Data[0]; + *pu32TXByteCount += 5; + + if ((0 < (DIAG_astDDDI[u8DDDIIDX].u8AddressAndLength >> 4)) && + (0 < (DIAG_astDDDI[u8DDDIIDX].u8AddressAndLength & 0x0f))) + { + memset((void*)pu8Data, 0, DIAG_DDDI_DATA_COUNT); + + while (0 < i16RXDataCount) + { + if (0 != *(pu8RXBuffer + 4)) + { + if ((RAM_START_ADDR < (*(uint32*)pu8RXBuffer)) && (RAM_END_ADDR > (*(uint32*)pu8RXBuffer))) + { + memcpy(pu8Data, pu8RXBuffer, DIAG_astDDDI[u8DDDIIDX].u8AddressAndLength & 0x0f); + } + else + { + memset(pu8Data, 0, DIAG_astDDDI[u8DDDIIDX].u8AddressAndLength & 0x0f); + } + + + u32Temp = DIAG_astDDDI[u8DDDIIDX].u8AddressAndLength & 0x0f; + u32Temp += (uint32)pu8RXBuffer; + u8ResultByteCount += *((puint8)u32Temp); + pu8Data += (DIAG_astDDDI[u8DDDIIDX].u8AddressAndLength & 0x0f); + pu8RXBuffer += (DIAG_astDDDI[u8DDDIIDX].u8AddressAndLength & 0x0f); + memcpy(pu8Data, pu8RXBuffer, DIAG_astDDDI[u8DDDIIDX].u8AddressAndLength >> 4); + + pu8Data += (DIAG_astDDDI[u8DDDIIDX].u8AddressAndLength >> 4); + pu8RXBuffer += (DIAG_astDDDI[u8DDDIIDX].u8AddressAndLength >> 4); + i16RXDataCount -= ((DIAG_astDDDI[u8DDDIIDX].u8AddressAndLength & 0x0f) + + (DIAG_astDDDI[u8DDDIIDX].u8AddressAndLength >> 4)); + DIAG_astDDDI[u8DDDIIDX].u8RecsCount++; + + } + else + { + /* Kill the loop because we have found trailing zeros */ + i16RXDataCount = 0; + } + } + + DIAG_astDDDI[u8DDDIIDX].u8ByteCount = u8ResultByteCount; + + if (0x9000 == (u16DDDISID & 0xff00)) + { + UDSAL_vConfigureDDDICache(u16DDDISID, u8ResultByteCount); + } + + u8Response = UDSAL_RSP_OK; + break; + } + else + { + /* The DDDI install failed */ + DIAG_astDDDI[u8DDDIIDX].u16DDI = 0; + } + } + else + { + + } + } + } + + return u8Response; +} + +static uint8 UDSAL_u8RC(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + uint8 u8Response = UDSAL_RSP_OK; + uint16 u16RoutineID; + bool boRetCode = FALSE; + + u16RoutineID = 0x100 * *(pu8RXBuffer + 4); + u16RoutineID += *(pu8RXBuffer + 5); + + switch (*(pu8RXBuffer + 3)) + { + case UDSAL_SSID_RC_STR: + { + switch (u16RoutineID) + { + case UDSAL_RCUID_RUN_DL: + { + + + } + break; + + case UDSAL_RCUID_PARTITION: + { +#ifdef BUILD_SBL + FEE_boPartition(); +#endif + } + break; + + case UDSAL_RCUID_WORK_TO_NVM: + { +#ifdef BUILD_SBL + boRetCode = FEE_boNVMWorkingCopy(FALSE, TRUE); +#endif +#ifdef BUILD_KERNEL + boRetCode = FEE_boNVMWorkingCopy(FALSE, TRUE); +#endif +#ifdef BUILD_KERNEL_APP + boRetCode = FEE_boNVMWorkingCopy(FALSE, TRUE); +#endif + if (FALSE == boRetCode) + { + u8Response = UDSAL_RSP_CNC; + } + *pu32TXByteCount += 8; + } + break; + + case UDSAL_RCUID_CLEAR_NVM: + { +#ifdef BUILD_SBL + boRetCode = FEE_boNVMClear(); +#endif +#ifdef BUILD_KERNEL + boRetCode = FEE_boNVMClear(); +#endif +#ifdef BUILD_KERNEL_APP + boRetCode = FEE_boNVMClear(); +#endif + if (FALSE == boRetCode) + { + u8Response = UDSAL_RSP_CNC; + } + *pu32TXByteCount += 8; + } + break; + + case UDSAL_RCUID_BCKP_ADCCAL: + { +#if defined(BUILD_SBL) + boRetCode = ADC_boBackupCalibrations(); +#endif +#if defined(BUILD_KERNEL) + boRetCode = ADC_boBackupCalibrations(); +#endif +#if defined(BUILD_KERNEL_APP) + /* TODO + boRetCode = ADC_boBackupCalibrations(); + */ +#endif + + if (FALSE == boRetCode) + { + u8Response = UDSAL_RSP_CNC; + } + *pu32TXByteCount += 8; + } + break; + + default: + { + break; + } + } + break; + } + default: + { + u8Response = UDSAL_RSP_SFNS; + break; + } + } + + return u8Response; +} + +static void UDSAL_vResponse(puint8 pu8TXBuffer, uint8 u8ResponseCode, uint8 u8ServiceIDX, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + uint8 u8BytesResp; + + switch (u8ResponseCode) + { + case UDSAL_RSP_OK: + { + u8BytesResp = UDSAL_rastALProcessInfo[u8ServiceIDX].u8BytesResp; + + switch (UDSAL_rastALProcessInfo[u8ServiceIDX].u8Service) + { + case UDSAL_SID_RD: + { + *pu8TXBuffer = 0; + *(pu8TXBuffer + 1) = u8BytesResp; + *(pu8TXBuffer + 3) = 0x20; + *(pu8TXBuffer + 4) = (COMMONNL_RX_BUFF_LARGE_SIZE - 2) / 0x100; + *(pu8TXBuffer + 5) = (COMMONNL_RX_BUFF_LARGE_SIZE - 2) % 0x100; + break; + } + case UDSAL_SID_MODE1: + { + break; + } + default: + { + if (0xff != u8BytesResp) + { + *(pu8TXBuffer + 1) = u8BytesResp; + } + } + } + + *(pu8TXBuffer + 2) += 0x40; + break; + } + case UDSAL_RSP_FLOW: + { + *(pu8TXBuffer + 0) = 0x30; + *(pu8TXBuffer + 1) = 0x0; + *(pu8TXBuffer + 2) = 0x0; + *(pu8TXBuffer + 3) = 0x0; + *(pu8TXBuffer + 4) = 0x0; + *(pu8TXBuffer + 5) = 0x0; + *(pu8TXBuffer + 6) = 0x0; + *(pu8TXBuffer + 7) = 0x0; + *pu32TXByteCount += 8; + break; + } + case UDSAL_RSP_SUPPRESS: + { + break; + } + default: + { + *(pu8TXBuffer + 0) = 3; + *(pu8TXBuffer + 2) = *(pu8TXBuffer + 1); + *(pu8TXBuffer + 1) = UDSAL_RSP_SNSIAS; + *(pu8TXBuffer + 3) = u8ResponseCode; + *pu32TXByteCount += 8; + break; + } + } +} + +static sint32 UDSAL_i32GetDDDICacheIndex(uint16 u16CacheDDDISID) +{ + /* TODO uint32 u32DDDICacheIDX = 0; */ + sint32 s32DDDICacheIndex = -1; + + /* TODO + while (UDSAL_nDDDICacheCount > u32DDDICacheIDX) + { + if (u16CacheDDDISID == UDSAL_au16DDDICacheSIDs[u32DDDICacheIDX]) + { + s32DDDICacheIndex = u32DDDICacheIDX; + break; + } + u32DDDICacheIDX++; + } + */ + + return s32DDDICacheIndex; +} + + +static void UDSAL_vConfigureDDDICache(uint16 u16CacheDDDISID, uint8 u8ByteCount) +{ + uint32 u32DDDICacheIDX = 0; + + while (UDSAL_nDDDICacheCount > u32DDDICacheIDX) + { + if (0 == UDSAL_au16DDDICacheSIDs[u32DDDICacheIDX]) + { + UDSAL_astDDDICacheQueue[u32DDDICacheIDX].u32Size = UDSAL_nDDDICacheSize / u8ByteCount; + UDSAL_astDDDICacheQueue[u32DDDICacheIDX].pvData = + (void*)&UDSAL_au8DDDICache[u32DDDICacheIDX][0]; + UDSAL_au16DDDICacheSIDs[u32DDDICacheIDX] = u16CacheDDDISID; + break; + } + u32DDDICacheIDX++; + } +} + +void UDSAL_vStart(uint32* const u32Stat) +{ + uint32 u32DDDICacheIDX; + + UDSSL_vStart(); + DIAG_vStart(); + + UDSAL_stReadDataTransferCB.boTransferComplete = TRUE; + UDSAL_stWriteDataTransferCB.boTransferComplete = TRUE; + UDSAL_boRDBICaching = false; + + for (u32DDDICacheIDX = 0; u32DDDICacheIDX < UDSAL_nDDDICacheCount; u32DDDICacheIDX++) + { + memset((void*)&UDSAL_astDDDICacheQueue[u32DDDICacheIDX], 0, sizeof(CQUEUE_tstQueue)); + UDSAL_au16DDDICacheSIDs[u32DDDICacheIDX] = 0; + } + + UDSAL_au8Mode1DataBuffer[28] = 1; + UDSAL_au8Mode1DataBuffer[29] = 1; + + + OS_xModuleStartOK(*u32Stat); +} + +void UDSAL_vRun(uint32* const u32Stat) +{ + uint8 au8UDSPrompt[5]; + puint8 pu8DDDIResultBuff; + uint32 u32DummyTXCount; + uint8 u8DDDIIDX; + uint32 u32Temp; + + au8UDSPrompt[0] = 0x00; + au8UDSPrompt[1] = 0x03; + au8UDSPrompt[2] = 0x22; + + for (u8DDDIIDX = 0; u8DDDIIDX < DIAG_DDDI_COUNT; u8DDDIIDX++) + { + + if (0x9000 == (DIAG_astDDDI[u8DDDIIDX].u16DDI & 0xff00)) + /* If DDDI active and rate = 1 ms */ + { + au8UDSPrompt[3] = DIAG_astDDDI[u8DDDIIDX].u16DDI & 0xff; + au8UDSPrompt[4] = (DIAG_astDDDI[u8DDDIIDX].u16DDI >> 8) & 0xff; + + CPU_xEnterCritical(); + + u32Temp = (uint32)UDSAL_astDDDICacheQueue[0].pvData; + u32Temp += (16 * UDSAL_astDDDICacheQueue[0].u32Tail); + u32Temp -= 5; + pu8DDDIResultBuff = (puint8)u32Temp; + + if (!CQUEUE_xIsFull(UDSAL_astDDDICacheQueue)) + { + CQUEUE_xAddItem(UDSAL_astDDDICacheQueue); + UDSAL_boRDBICaching = true; + (void)UDSAL_u8RDBI(&au8UDSPrompt[0], 5u, pu8DDDIResultBuff, &u32DummyTXCount, 20); + UDSAL_boRDBICaching = false; + } + CPU_xExitCritical(); + } + } +} + +void UDSAL_vTerminate(uint32* const u32Stat) +{ + +} + +#if (BUILD_SBL) || (BUILD_PBL) +static Bool UDSAL_boWriteDLBlock(COMMONNL_tstRXLargeBuffer* const pstSourceBuffer, + uint8* const pu8TargetAddress, + uint32 u32DataCount) +{ + Bool boRetVal = FALSE; + + if (false == UDSAL_stDLControlBlock.boPending) + { + UDSAL_stDLControlBlock.pstSourceBuffer = pstSourceBuffer; + UDSAL_stDLControlBlock.pu8TargetAddress = pu8TargetAddress; + UDSAL_stDLControlBlock.u32WriteCount = u32DataCount; + UDSAL_stDLControlBlock.u32AccumulateCount = 0; + UDSAL_stDLControlBlock.boPending = true; + UDSAL_stDLControlBlock.boComplete = false; + boRetVal = TRUE; + } + + return boRetVal; +} +#endif + +#if (BUILD_SBL) +static Bool UDSAL_boUpdateDLBlock(uint32 u32BlockWriteCount) +{ + puint8 pu8SourceData; + puint8 pu8BufferData; + + if (UDSAL_stDLControlBlock.boPending == true) + { + if ((UDSAL_DL_BUFF_SIZE >= + (u32BlockWriteCount + UDSAL_stDLControlBlock.u32AccumulateCount)) && + (0 != u32BlockWriteCount)) + { + pu8SourceData = (puint8)&UDSAL_stDLControlBlock.pstSourceBuffer->u8Data[0]; + pu8BufferData = (puint8)((uint32)UDSAL_stDLControlBlock.pu8TargetAddress + UDSAL_stDLControlBlock.u32AccumulateCount); + + memcpy((void*)pu8BufferData, (void*)pu8SourceData, u32BlockWriteCount); + + UDSAL_stDLControlBlock.u32AccumulateCount += u32BlockWriteCount; + + if (UDSAL_stDLControlBlock.u32WriteCount == UDSAL_stDLControlBlock.u32AccumulateCount) + { + UDSAL_stDLControlBlock.boComplete = true; + UDSAL_stDLControlBlock.boPending = false; + } + else if (UDSAL_DL_BUFF_SIZE < UDSAL_stDLControlBlock.u32AccumulateCount) + { + /* Uh oh too many bytes received - ran past the executable section size */ + /* TODO matthew deal with this */ + UDSAL_stDLControlBlock.boPending = false; + } + } + else + { + UDSAL_stDLControlBlock.boPending = false; + } + } + + return UDSAL_stDLControlBlock.boPending; +} +#endif + +static uint8 UDSAL_u8TFEXREQ(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + uint8 u8Response = UDSAL_RSP_RSE; + uint32 u32EntryAddress; + uint16 u16EntryOffset; +#if (BUILD_PBL) + puint32 pu32TargetAddress; +#endif + + if (true == UDSAL_stDLControlBlock.boComplete) + { + u32EntryAddress = (uint32)(UDSAL_stDLControlBlock.pu8TargetAddress) & 0xffff0000; + u16EntryOffset = 0x100 * pu8RXBuffer[5] + pu8RXBuffer[6]; + u32EntryAddress += (uint32)u16EntryOffset; +#if (BUILD_PBL) + pu32TargetAddress = (puint32)((uint32)UDSAL_stDLControlBlock.pu8TargetAddress & 0xffff0000); + *pu32TargetAddress = 0; + PBL_vExecuteDL(u32EntryAddress); +#endif + u8Response = UDSAL_RSP_OK; + } + + return u8Response; +} + + diff --git a/source/Suites/UDS/UDSNL.c b/source/Suites/UDS/UDSNL.c new file mode 100644 index 0000000..e09b529 --- /dev/null +++ b/source/Suites/UDS/UDSNL.c @@ -0,0 +1,307 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _UDSNL_C +#include "types.h" +#include "declarations.h" +#include "IOAPI.h" +#include "DIAGAPI.h" +#include "OS.h" +#include "DLL.h" +#include "COMMONNL.h" +#include "UDSNL.h" +#include "UDSSL.h" +#include "UDSAL.h" + + +UDSNL_tenSegRXMode UDSNL_enSegRXMode = UDSNL_enSegRXModeInvalid; +IOAPI_tenEHIOResource UDSNL_enActiveEHIOResource; +sint32 UDSNL_i32ResourceTimerIDX; + +static bool UDSNL_boCheckActiveResource(IOAPI_tenEHIOResource); +static void UDSNL_vSegmentTXBuffer(puint8, uint32, puint32, uint32); + +void +UDSNL_vStart(void) +{ + UDSNL_enActiveEHIOResource = EH_IO_Invalid; + UDSNL_i32ResourceTimerIDX = -1; +} + +void +UDSNL_vReceiveFrame(IOAPI_tenEHIOResource enEHIOResource, puint8 pu8RXData, puint8 pu8TXData, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + static uint32 u32TXCountMax = 0; + uint32 u32EntryTXByteCount = *pu32TXByteCount; + + if (false == UDSNL_boCheckActiveResource(enEHIOResource)) + { + return; + } + + switch(*pu8RXData & 0xf0) + { + { + case RX_SEG_FRAME_UNSEG: + { + /* High byte of count word is 0 for an unsegmented message */ + UDSNL_stRXSmallBuffer.u8Data[0] = 0; + memcpy(&UDSNL_stRXSmallBuffer.u8Data[1], pu8RXData, 8); + UDSNL_stRXSmallBuffer.u8RXReceivedCount = 1 + (UDSNL_stRXSmallBuffer.u8Data[1] & 0x07); + UDSSL_vProcessBufferCB(&UDSNL_stRXSmallBuffer.u8Data[0], + UDSNL_stRXSmallBuffer.u8RXReceivedCount, pu8TXData, pu32TXByteCount, u32TXCap); + + // UDSNL_stRXSmallBuffer.u8RXReceivedCount = 8; +// UDSSL_vProcessBufferCB(&UDSNL_stRXSmallBuffer.u8Data[0], 8, pu8TXData, pu32TXByteCount, u32TXCap); + + if (0 != (*pu32TXByteCount - u32EntryTXByteCount)) + { + UDSNL_vSegmentTXBuffer(pu8TXData, *pu32TXByteCount - u32EntryTXByteCount, pu32TXByteCount, u32TXCap); + } + break; + } + case RX_SEG_FRAME_ONE: + { + switch(*(pu8RXData+2)) + { + case UDSAL_SID_RD: + UDSNL_stRXSmallBuffer.pu8RX = (uint8*)&UDSNL_stRXSmallBuffer.u8Data[0]; + UDSNL_stRXLargeBuffer.u8SeqNumber = 0x20; + UDSNL_stRXSmallBuffer.u8RXRequestedCount = 0x100 * (*pu8RXData & 0x0f) + + *(pu8RXData + 1); + memcpy(UDSNL_stRXSmallBuffer.pu8RX, pu8RXData, 8); + UDSNL_stRXSmallBuffer.pu8RX += 8; + UDSNL_stRXSmallBuffer.u8RXReceivedCount = 6; + UDSNL_enSegRXMode = UDSNL_enSegRXModeSmall; + break; + + case UDSAL_SID_TD: + UDSNL_stRXLargeBuffer.pu8RX = (uint8*)&UDSNL_stRXLargeBuffer.u8Data[0]; + UDSNL_stRXLargeBuffer.u8SeqNumber = 0x20; + UDSNL_stRXLargeBuffer.u16RXRequestedCount = 0x100 * (*pu8RXData & 0x0f) + + *(pu8RXData + 1); + UDSNL_stRXLargeBuffer.u8RXBlock = *(pu8RXData + 3); + UDSNL_stRXLargeBuffer.biRXErr = false; + UDSNL_stRXLargeBuffer.biRXOK = false; + memcpy(UDSNL_stRXLargeBuffer.pu8RX, pu8RXData + 4, 4); + UDSNL_stRXLargeBuffer.pu8RX += 4; + UDSNL_stRXLargeBuffer.u16RXReceivedCount = 6; + UDSNL_enSegRXMode = UDSNL_enSegRXModeLarge; + + //memcpy(&DIAG_u8DiagBuff, &pRXBytes->u8Data[1], RX_BUFF_SIZE); + //UDSSL_vProcessBufferCB(&UDSNL_stRXLargeBuffer.u8Data[0], UDSNL_stRXLargeBuffer.u8RXReceivedCount); + break; + + default: + UDSNL_stRXSmallBuffer.pu8RX = (uint8*)&UDSNL_stRXSmallBuffer.u8Data[0]; + UDSNL_stRXSmallBuffer.u8RXRequestedCount = 0x100 * (*pu8RXData & 0x0f) + + *(pu8RXData + 1); + memcpy(UDSNL_stRXSmallBuffer.pu8RX, pu8RXData, 8); + + /* Mask the byte count high byte */ + *(UDSNL_stRXSmallBuffer.pu8RX) &= 0x0f; + UDSNL_stRXSmallBuffer.pu8RX += 8; + UDSNL_stRXSmallBuffer.u8RXReceivedCount = 6; + UDSNL_enSegRXMode = UDSNL_enSegRXModeSmall; + break; + } + break; + } + case RX_SEG_FRAME_SEQ: + { + switch(UDSNL_enSegRXMode) + { + case UDSNL_enSegRXModeSmall: + if (UDSNL_stRXSmallBuffer.u8RXRequestedCount > UDSNL_stRXSmallBuffer.u8RXReceivedCount) + { + if ((COMMONNL_RX_BUFF_SMALL_SIZE - 7) >= UDSNL_stRXSmallBuffer.u8RXReceivedCount) + { + memcpy(UDSNL_stRXSmallBuffer.pu8RX, &pu8RXData[1], 7); + UDSNL_stRXSmallBuffer.pu8RX += 7; + UDSNL_stRXSmallBuffer.u8RXReceivedCount += 7; + if(UDSNL_stRXSmallBuffer.u8RXReceivedCount >= UDSNL_stRXSmallBuffer.u8RXRequestedCount) + { + //if(UDSNL_stRXSmallBuffer.u8RXRequestedCount <= DIAG_COMMON_BUFF_SIZE) + { + UDSSL_vProcessBufferCB(&UDSNL_stRXSmallBuffer.u8Data[0], UDSNL_stRXSmallBuffer.u8RXReceivedCount, pu8TXData, pu32TXByteCount, u32TXCap); + UDSNL_vSegmentTXBuffer(pu8TXData, *pu32TXByteCount - u32EntryTXByteCount, pu32TXByteCount, u32TXCap); + UDSNL_enSegRXMode = UDSNL_enSegRXModeInvalid; + } + } + } + else + { + UDSNL_enSegRXMode = USDNL_enSegRXErr; + //UDSSL_vProcessErrorCB(&UDSNL_stRXSmallBuffer.u8Data[0], UDSNL_stRXSmallBuffer.u8RXReceivedCount, pu8TXData, pu32TXByteCount, u32TXCap); + } + } + else + { + UDSNL_enSegRXMode = USDNL_enSegRXErr; + //UDSSL_vProcessErrorCB(&UDSNL_stRXSmallBuffer.u8Data[0], UDSNL_stRXSmallBuffer.u8RXReceivedCount, pu8TXData, pu32TXByteCount, u32TXCap); + } + break; + + case UDSNL_enSegRXModeLarge: + if((((UDSNL_stRXLargeBuffer.u8SeqNumber + 1) & 0x0f) == + (pu8RXData[0] & 0x0f)) && + (UDSNL_stRXLargeBuffer.u16RXRequestedCount > UDSNL_stRXLargeBuffer.u16RXReceivedCount)) + { + memcpy(UDSNL_stRXLargeBuffer.pu8RX, &pu8RXData[1], 7); + UDSNL_stRXLargeBuffer.pu8RX += 7; + UDSNL_stRXLargeBuffer.u16RXReceivedCount += 7; + UDSNL_stRXLargeBuffer.u8SeqNumber = pu8RXData[0]; + if(UDSNL_stRXLargeBuffer.u16RXReceivedCount >= UDSNL_stRXLargeBuffer.u16RXRequestedCount) + { + UDSNL_stRXLargeBuffer.biRXOK = true; + UDSNL_enSegRXMode = UDSNL_enSegRXModeInvalid; + + /* Re-create the request to initiate a response */ + UDSNL_stRXSmallBuffer.u8Data[0] = 0; + UDSNL_stRXSmallBuffer.u8Data[1] = 4; + UDSNL_stRXSmallBuffer.u8Data[2] = UDSAL_SID_TD; + UDSNL_stRXSmallBuffer.u8Data[3] = UDSNL_stRXLargeBuffer.u8RXBlock; + + UDSSL_vProcessBufferCB(&UDSNL_stRXSmallBuffer.u8Data[0], + UDSNL_stRXSmallBuffer.u8RXReceivedCount, pu8TXData, pu32TXByteCount, u32TXCap); + UDSNL_vSegmentTXBuffer(pu8TXData, *pu32TXByteCount - u32EntryTXByteCount, pu32TXByteCount, u32TXCap); + break; + } + } + else + { + UDSNL_stRXLargeBuffer.biRXErr = true; + UDSNL_stRXLargeBuffer.biRXOK = false; + } + break; + + default: + break; + } + break; + } + default: + { + break; + } + } + } + + u32TXCountMax = *pu32TXByteCount > u32TXCountMax ? *pu32TXByteCount : u32TXCountMax; +} + +static bool +UDSNL_boCheckActiveResource(IOAPI_tenEHIOResource enEHIOResource) +{ + bool boResourceOK = false; + + if ((EH_IO_Invalid == UDSNL_enActiveEHIOResource) + || (UDSNL_enActiveEHIOResource == enEHIOResource)) + { + UDSNL_enActiveEHIOResource = enEHIOResource; + boResourceOK = true; + if (-1 == UDSNL_i32ResourceTimerIDX) + { + UDSNL_i32ResourceTimerIDX = TIMER_vConfigureAlarm(UDSNL_nActiveResourceTimeout, UDSNL_vActiveResourceTimeout); + } + else + { + TIMER_vSetAlarm(UDSNL_nActiveResourceTimeout, UDSNL_i32ResourceTimerIDX); + } + } + + return boResourceOK; +} + +void UDSNL_vActiveResourceTimeout(void) +{ + UDSNL_enActiveEHIOResource = EH_IO_Invalid; +} + +static void UDSNL_vSegmentTXBuffer(puint8 pu8TXData, uint32 u32TransferByteCount, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + uint32 u32TXBytesRequired; + uint16 u16FrameIDX; + uint8 u8ByteIDX; + uint8 u8Seq; + puint8 pu8Dest; + puint8 pu8Source; + uint8 u8Data[7]; + + u32TXBytesRequired = UDSNL_u32GetTransmissionBytesRequired(u32TransferByteCount); + + if (0x8 >= u32TransferByteCount)//matthew210915 + { + for (u8ByteIDX = 0; u8ByteIDX < 8; u8ByteIDX++) + { + *(pu8TXData + u8ByteIDX) = *(pu8TXData + u8ByteIDX + 1); + } + if (8 > *pu8TXData) + { + for (u8ByteIDX = *pu8TXData + 1; u8ByteIDX < 8; u8ByteIDX++) + { + *(pu8TXData + u8ByteIDX) = 0; + } + } + } + else + { + /* Segment the TX data buffer */ + u16FrameIDX = u32TransferByteCount / 7; + pu8Dest = pu8TXData + 9 + 8 * (u16FrameIDX - 1); + pu8Source = pu8TXData + 8 + 7 * (u16FrameIDX - 1); + + /* Copy data */ + for (; u16FrameIDX >= 1; u16FrameIDX--) + { + memcpy(&u8Data, pu8Source, 7); + memcpy(pu8Dest, &u8Data, 7); + pu8Dest -= 8; + pu8Source -= 7; + } + memcpy(pu8Dest + 1, pu8Source + 1, 6); + + /* Write sequence numbers */ + u16FrameIDX = u32TransferByteCount / 7; + u8Seq = (u16FrameIDX - 1) & 0x0f; + pu8Dest = pu8TXData + 8 + 8 * (u16FrameIDX - 1); + for (; u16FrameIDX >= 1; u16FrameIDX--) + { + *pu8Dest = 0x20 + u8Seq--; + u8Seq &= 0x0f; + pu8Dest -= 8; + } + + *pu8TXData |= 0x10; + *(pu8TXData + 1) = (uint8)(u32TransferByteCount) & 0xff; + *pu8TXData = 0x10 + (((u32TransferByteCount) & 0xf00) >> 8); + + /* Add in the additional bytes required for segmentation */ + *pu32TXByteCount += (u32TXBytesRequired - u32TransferByteCount); + } +} + +uint32 UDSNL_u32GetTransmissionBytesRequired(uint32 u32TransferByteCount) +{ + uint32 u32TransmissionBytesRequired; + + if (8 > u32TransferByteCount) + { + u32TransmissionBytesRequired = 8; + } + else + { + u32TransmissionBytesRequired = + 8 + (8 * (((u32TransferByteCount - 7) / 7) + 1)); + } + + return u32TransmissionBytesRequired; +} diff --git a/source/Suites/UDS/UDSSL.c b/source/Suites/UDS/UDSSL.c new file mode 100644 index 0000000..88919b8 --- /dev/null +++ b/source/Suites/UDS/UDSSL.c @@ -0,0 +1,100 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#include +#include "OS.h" +#include "DLL.h" +#include "DIAGAPI.h" +#include "COMMONNL.h" + +#include "UDSSL.h" +#include "UDSAL.h" + +static void UDSSL_vSessionControl(puint8 pu8Buffer); + +DIAGAPI_tenSession UDSSL_enSession; +sint32 UDSSL_i32ResourceTimerIDX; + +void UDSSL_vStart(void) +{ + UDSNL_vStart(); + UDSSL_i32ResourceTimerIDX = -1; +} + +void UDSSL_vProcessBufferCB(puint8 pu8RXBuffer, uint32 u32RXDataCount, puint8 pu8TXBuffer, puint32 pu32TXByteCount, uint32 u32TXCap) +{ + UDSSL_vSessionControl(pu8RXBuffer); + UDSAL_vProcessBufferCB(pu8RXBuffer, u32RXDataCount, pu8TXBuffer, pu32TXByteCount, u32TXCap); +} + +DIAGAPI_tenSession UDSSL_enGetSession(void) +{ + return UDSSL_enSession; +} + +void UDSSL_vResetSessionTimer(void) +{ + if (-1 == UDSSL_i32ResourceTimerIDX) + { + UDSSL_i32ResourceTimerIDX = TIMER_vConfigureAlarm(UDSSL_nSessionTimeout, UDSSL_vSessionTimeout); + } + else + { + TIMER_vSetAlarm(UDSSL_nSessionTimeout, UDSSL_i32ResourceTimerIDX); + } +} + +static void UDSSL_vSessionControl(puint8 pu8Buffer) +{ + if (UDSAL_SID_DSC == pu8Buffer[UDSSL_IDX_SUBSID]) + { + switch(pu8Buffer[UDSSL_IDX_SID]) + { +// case UDSSL_SESS_DFLT: +// UDSSL_enSession = UDSSL_enSessionDefault; +// break; +// +// case UDSSL_SESS_PGM: +// if ((UDSSL_enSecurityLevel == UDSSL_enSecLevelOEM) || +// (UDSSL_enSecurityLevel == UDSSL_enSecLevelMDAC)) +// { +// UDSSL_enSession = UDSSL_enSessionProgramming; +// UDSSL_vResponse(UDS_RSP_OK); +// } +// else +// { +// UDSSL_enSession = UDSSL_enSessionInactive; +// UDSSL_vResponse(UDS_RSP_SECRQRD); +// } +// break; +// +// case UDS_SESS_EXT: +// if ((UDSSL_enSecurityLevel == UDSSL_enSecLevelOEM) || +// (UDSSL_enSecurityLevel == UDSSL_enSecLevelMDAC)) +// { +// UDSSL_enSession = UDSSL_enSessionProgramming; +// UDSSL_vResponse(UDS_RSP_OK); +// } +// else +// { +// UDSSL_enSession = UDSSL_enSessionInactive; +// UDSSL_vResponse(UDS_RSP_SECRQRD); +// } +// break; + } + } +} + +void UDSSL_vSessionTimeout(void) +{ + UDSSL_enSession = DIAGAPI_enNoSession; +} \ No newline at end of file diff --git a/source/Support/BUILD.h b/source/Support/BUILD.h new file mode 100644 index 0000000..4ec799d --- /dev/null +++ b/source/Support/BUILD.h @@ -0,0 +1,85 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. */ +/* All rights reserved. */ +/******************************************************************************/ +/* */ +/* PACKAGE TITLE: Build Header File */ +/* DESCRIPTION: This code module provides build options for compiling */ +/* the project to PBL, SBL, Flash Kernel, RAM Kernel+APP */ +/* Debugging or Flash User APP and WIFI/ETHERNET switch */ +/* FILE NAME: BUILD.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#ifndef BUILD_H +#define BUILD_H + +#ifndef BUILD_MK64 +#define BUILD_MK64 +#endif + +//#define BUILD_SPARKDOG_TEENSY_ADAPT +#define BUILD_SPARKDOG_PF + +#define BUILD_USER +//#define BUILD_BSP_IAC_STEPPER +#define BUILD_FME +#define BUILD_BSP_AFM_FREQ +#define BUILD_KERNEL_APP +#define BUILD_PACKING __attribute__((packed)) +#define BUILD_PACKING_ETHERNET __attribute__((packed)) +#define USB_DATA_ALIGNMENT __attribute__ ((aligned (8))) +#define USB_DATA_BUFF_SIZE 256 + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#ifdef BUILD_PBL +/* Build the Primary BootLoader to be resident in FLASH @ 0x00000000 */ + #define BUILD_DL_ADDR_MIN 0x20000000 + #define BUILD_DL_ADDR_MAX 0x2000ffff +#endif + +#ifdef BUILD_SBL +/* Build the Secondary BootLoader to be resident in RAM @ 0x20000000 */ + #define BUILD_DL_ADDR_MIN 0x00010000 + #define BUILD_DL_ADDR_MAX 0x0007ffff +#endif + +#ifdef BUILD_UBL +/* Build the User BootLoader to be resident in RAM @ 0x20000000 */ + #define BUILD_DL_ADDR_MIN 0x00020000 + #define BUILD_DL_ADDR_MAX 0x0002ffff +#endif + +#ifdef BUILD_KERNEL +/* Build the KERNEL for release to be resident in FLASH @ 0x00010000 */ + #define BUILD_DL_ADDR_MIN 0x00070000 + #define BUILD_DL_ADDR_MAX 0x0007ffff + #define BUILD_KERNEL_OR_KERNEL_APP +#endif + +#ifdef BUILD_KERNEL_APP +/* Build the KERNEL and APP for testing to be resident in FLASH @ 0x00070000 */ + #define BUILD_DL_ADDR_MIN 0x00070000 + #define BUILD_DL_ADDR_MAX 0x0007ffff + #define BUILD_KERNEL_OR_KERNEL_APP + #define BUILD_USER +#endif + +#ifdef BUILD_USER_APP +/* Build the User APP for release be resident in FLASH @ 0x00070000 */ + #define BUILD_DL_ADDR_MIN 0x00070000 + #define BUILD_DL_ADDR_MAX 0x0007ffff + #define BUILD_KERNEL_OR_KERNEL_APP + #define BUILD_USER +#endif + +#define PBL_WORD_ADDR 0x2000fffc +#define RAM_START_ADDR 0x20000000 +#define RAM_END_ADDR 0x2008ffff +#define LSU_DEVICE_COUNT 1u + +#endif // BUILD_H + diff --git a/source/Support/CQUEUE.h b/source/Support/CQUEUE.h new file mode 100644 index 0000000..7508605 --- /dev/null +++ b/source/Support/CQUEUE.h @@ -0,0 +1,112 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef CQUEUE_H +#define CQUEUE_H + +#include +#include +#include "CPUAbstract.h" + +typedef struct { + uint32 u32Head; + uint32 u32Tail; + uint32 u32Size; + void* pvData; +} CQUEUE_tstQueue; + +#define CQUEUE_vInit(x,y,z) \ +x##.u32Head = 0; \ +x##.u32Tail = 0; \ +x##.u32Size = y; \ +x##.pvData = (void*)&##z; + +#define CQUEUE_xInit(x,y,z) \ +(x)->u32Head = 0; \ +(x)->u32Tail = 0; \ +(x)->u32Size = (y); \ +(x)->pvData = (void*)(z); + +#define CQUEUE_boIsEmpty(x) (x##.u32Head == x##.u32Tail) ? true : false + +#define CQUEUE_xIsEmpty(x) ((x)->u32Head == (x)->u32Tail) ? true : false + +#define CQUEUE_boIsStaticActive(x) (x##.u32Tail != 0) ? true : false + +#define CQUEUE_xIsStaticActive(x) ((x)->u32Tail != 0) ? true : false + +#define CQUEUE_boIsAtStaticHead(x) (x##.u32Head == 0) ? true : false + +#define CQUEUE_xIsAtStaticHead(x) ((x)->u32Head == 0) ? true : false + +#define CQUEUE_vResetStaticHead(x) (x##.u32Head = 0) + +#define CQUEUE_xResetStaticHead(x) (x)->u32Head = 0 + +#define CQUEUE_xComplete(x) (x)->u32Head = (x)->u32Tail + +#define CQUEUE_boIsFull(x) (x##.u32Head == ((x##.u32Tail + 1) % x##.u32Size)) ? true : false + +#define CQUEUE_xIsFull(x) ((x)->u32Head == ((x)->u32Tail + 1) % (x)->u32Size ? true : false) + +#define CQUEUE_vAddItem(x) \ + CPU_xEnterCritical(); \ + x##.u32Tail = (x##.u32Tail + 1) % x##.u32Size; \ + CPU_xExitCritical() + +#define CQUEUE_xAddItem(x) \ +CPU_xEnterCritical(); \ +(x)->u32Tail = ((x)->u32Tail + 1) % (x)->u32Size; \ +CPU_xExitCritical() + + +#define CQUEUE_xAddItemUnsafe(x) \ +(x)->u32Tail = ((x)->u32Tail + 1) % (x)->u32Size; + + +#define CQUEUE_vRemoveItem(x) \ +CPU_xEnterCritical(); \ +if (!CQUEUE_boIsEmpty(x)) \ +{ \ + x##.u32Head = (x##.u32Head + 1) % x##.u32Size; \ +} \ +CPU_xExitCritical() + +#define CQUEUE_xRemoveItem(x) \ +CPU_xEnterCritical(); \ +if (false == (CQUEUE_xIsEmpty(x))) \ +{ \ + (x)->u32Head = ((x)->u32Head + 1) % (x)->u32Size; \ +} \ +CPU_xExitCritical() + +#define CQUEUE_xRemoveItemUnsafe(x) \ +if (false == (CQUEUE_xIsEmpty(x))) \ +{ \ + (x)->u32Head = ((x)->u32Head + 1) % (x)->u32Size; \ +} + +#define CQUEUE_xSetHead(x, y) \ +CPU_xEnterCritical(); \ +(x)->u32Head = y; \ +CPU_xExitCritical() + +#define CQUEUE_vClearCount(x) \ +x##.u32Head = 0; \ +x##.u32Tail = 0 + +#define CQUEUE_xClearCount(x) \ +(x)->u32Head = 0; \ +(x)->u32Tail = 0 + + +#endif //CQUEUE_H + diff --git a/source/Support/DECLARATIONS.h b/source/Support/DECLARATIONS.h new file mode 100644 index 0000000..3a163ff --- /dev/null +++ b/source/Support/DECLARATIONS.h @@ -0,0 +1,56 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. */ +/* All rights reserved. */ +/******************************************************************************/ +/* */ +/* PACKAGE TITLE: Declarations Header File */ +/* DESCRIPTION: This code various required misc declarations */ +/* */ +/* FILE NAME: declarations.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#ifndef DECLARATIONS_H +#define DECLARATIONS_H + + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#ifndef NULL + #define NULL 0 +#endif +/*CR1_98*/ + +#ifndef true + #define true 1 +#endif +/*CR1_99*/ + +#ifndef false + #define false 0 +#endif +/*CR1_99*/ + +#ifndef TRUE + #define TRUE 1 +#endif + +#ifndef FALSE + #define FALSE 0 +#endif + +#define nASCII_CR 0x0d +#define nASCII_LF 0x0a + +#ifndef MIN + #define MIN(a,b) ((a > b) ? (b) : (a)) +#endif + +#ifndef MAX + #define MAX(a,b) ((a < b) ? (b) : (a)) +#endif + +#endif // DECLARATIONS_H + diff --git a/source/Support/MACROS.h b/source/Support/MACROS.h new file mode 100644 index 0000000..93bdd99 --- /dev/null +++ b/source/Support/MACROS.h @@ -0,0 +1,42 @@ +/******************************************************************************/ +/* macros header file */ +/******************************************************************************/ +/* */ +/* Copyright (c) 2013 MD Automotive Controls. All rights reserved. */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#ifndef MACROS_H +#define MACROS_H + +#include + +//TODO porting does not belong here +#define PORT_HOSTNETWORK_ENDIANSWITCH + +#define U32TOBYTE3(x) (uint8)(((uint32)(x ) >> 24 ) & 0xff ) +#define U32TOBYTE2(x) (uint8)(((uint32)(x ) >> 16 ) & 0xff ) +#define U32TOBYTE1(x) (uint8)(((uint32)(x ) >> 8 ) & 0xff ) +#define U32TOBYTE0(x) (uint8)(((uint32)(x ) >> 0 ) & 0xff ) + +#define U16TOBYTE1(x) (uint8)(((uint16)(x ) >> 8 ) & 0xff ) +#define U16TOBYTE0(x) (uint8)(((uint16)(x ) >> 0 ) & 0xff ) + +#ifdef PORT_HOSTNETWORK_ENDIANSWITCH + #define HTONS(x ) ((((x ) & 0xff ) << 8 ) | (((x ) & 0xff00 ) >> 8 ) ) + #define NTOHS(x ) HTONS(x) + #define HTONL(x ) ((((x ) & 0xff ) << 24 ) | \ + (((x ) & 0xff00 ) << 8 ) | \ + (((x ) & 0xff0000UL ) >> 8 ) | \ + (((x ) & 0xff000000UL ) >> 24 ) ) + #define NTOHL(x ) HTONL(x ) +#else + #define HTONS(x ) (x ) + #define NTOHS(x ) (x ) + #define HTONL(x ) (x ) + #define NTOHL(x ) (x ) +#endif // PORT_HOSTNETWORK_ENDIANSWITCH + +#endif // MACROS_H + diff --git a/source/Support/MATH.c b/source/Support/MATH.c new file mode 100644 index 0000000..5e53214 --- /dev/null +++ b/source/Support/MATH.c @@ -0,0 +1,75 @@ +/******************************************************************************/ +/* MATH c file */ +/******************************************************************************/ +/* */ +/* Copyright (c) 2013 MD Automotive Controls. All rights reserved. */ +/* This file provides data link layer functions for message segmentation/ */ +/* desegmentation and error checking */ +/* */ +/******************************************************************************/ + +#include "MATH.h" + +const uint32 MATH_rau32B[ ] = +{ 0xAAAAAAAA, + 0xCCCCCCCC, + 0xF0F0F0F0, + 0xFF00FF00, + 0xFFFF0000 }; + +const uint32 MATH_rauIDXToMask[ ] = +{ + 0x00000001, + 0x00000002, + 0x00000004, + 0x00000008, + 0x00000010, + 0x00000020, + 0x00000040, + 0x00000080, + 0x00000100, + 0x00000200, + 0x00000400, + 0x00000800, + 0x00001000, + 0x00002000, + 0x00004000, + 0x00008000, + 0x00010000, + 0x00020000, + 0x00040000, + 0x00080000, + 0x00100000, + 0x00200000, + 0x00400000, + 0x00800000, + 0x01000000, + 0x02000000, + 0x04000000, + 0x08000000, + 0x10000000, + 0x20000000, + 0x40000000, + 0x80000000 +}; + +uint32 MATH_u32MaskToIDX(uint32 u32Mask ) +{ + uint32 u32R = ( u32Mask & MATH_rau32B[ 0 ] ) != 0; + + u32R |= ((u32Mask & MATH_rau32B[ 4 ] ) != 0 ) << 4; + u32R |= ((u32Mask & MATH_rau32B[ 3 ] ) != 0 ) << 3; + u32R |= ((u32Mask & MATH_rau32B[ 2 ] ) != 0 ) << 2; + u32R |= ((u32Mask & MATH_rau32B[ 1 ] ) != 0 ) << 1; + + return u32R; +} + +uint32 MATH_u32IDXToMask(uint32 u32IDX ) +{ + return MATH_rauIDXToMask[ u32IDX ]; +} + + + + diff --git a/source/Support/MATH.h b/source/Support/MATH.h new file mode 100644 index 0000000..80b75d8 --- /dev/null +++ b/source/Support/MATH.h @@ -0,0 +1,18 @@ +/******************************************************************************/ +/* MATH header file */ +/******************************************************************************/ +/* */ +/* Copyright (c) 2013 MD Automotive Controls. All rights reserved. */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#ifndef MATH_H +#define MATH_H + +#include + +uint32 MATH_u32MaskToIDX(uint32); +uint32 MATH_u32IDXToMask(uint32); +#endif // MATH_H + diff --git a/source/System/CPUAbstract.c b/source/System/CPUAbstract.c new file mode 100644 index 0000000..0124203 --- /dev/null +++ b/source/System/CPUAbstract.c @@ -0,0 +1,45 @@ +/******************************************************************************/ +/* CPU abstraction c file */ +/******************************************************************************/ +/* */ +/* Copyright (c) 2013 MD Automotive Controls. All rights reserved. */ +/* */ +/* */ +/* */ +/******************************************************************************/ + +#include +#include "CPUAbstract.h" + +bool CPU_boCriticalNestCounter; + +void CPU_vStart(void) +{ + CPU_boCriticalNestCounter = 0; +} + +void CPU_vEnterCritical(void) +{ + CPU_xEnterCritical(); + //CPU_boCriticalNestCounter++; +} + +void CPU_vExitCritical(void) +{ + //if (1 == CPU_boCriticalNestCounter) + //{ + CPU_xExitCritical(); + // CPU_boCriticalNestCounter = 0; + //} + //else + //{ + // CPU_boCriticalNestCounter--; + //} +} + +void CPU_vDisableMPROT(void) +{ + SYSMPU->CESR = 0; +} + + diff --git a/source/System/CPUAbstract.h b/source/System/CPUAbstract.h new file mode 100644 index 0000000..016fe0f --- /dev/null +++ b/source/System/CPUAbstract.h @@ -0,0 +1,29 @@ +/******************************************************************************/ +/* CPU general hardware abstraction header file */ +/******************************************************************************/ +/* */ +/* Copyright (c) 2013 MD Automotive Controls. All rights reserved. */ +/* This file contains macros that are invoked in hardware independent files */ +/* */ +/* */ +/******************************************************************************/ +#include +#ifdef KERNEL + +#ifndef HARDABSTRACT_H +#define HARDABSTRACT_H + +#include "mk64f12.h" + +#define CPUA_OS_u32GetSysTimeStamp() 0xFFFFFF; + +#define CPU_xEnterCritical() __disable_irq() +#define CPU_xExitCritical() __enable_irq() + +void CPU_vStart(void); +void CPU_vEnterCritical(void); +void CPU_vExitCritical(void); +void CPU_vDisableMPROT(void); + +#endif // HARDABSTRACT_H +#endif // KERNEL diff --git a/source/System/ECUHostMain.c b/source/System/ECUHostMain.c new file mode 100644 index 0000000..22dd4a6 --- /dev/null +++ b/source/System/ECUHostMain.c @@ -0,0 +1,45 @@ +/*---------------------------------------------------------------------------- + * Name: DisplayMain.c + * Purpose: Freescale MK60X256VMD100 LED Flasher + *----------------------------------------------------------------------------*/ +#include +#include "TQUEUE.h" +#include +#include "mk64f12.h" +#include "OS.h" +#include "CPUAbstract.h" +#include "fsl_clock.h" + +bool boGlobalTickFlag; +volatile uint32_t msTicks; /* counts 1ms timeTicks */ +extern uint32 OS_u32SysTickInterval; + +/*---------------------------------------------------------------------------- + MAIN function + *----------------------------------------------------------------------------*/ +int ECUHostMain(void){ + uint32 u32Stat; + puint32 pu32PBLWord = (puint32)0x1ffffffc; + + if (0xAA550001 != *pu32PBLWord) + { + SystemCoreClockUpdate(); /* Get Core Clock Frequency */ + SysTick_Config(SystemCoreClock / 1000); /* Generate interrupt each 1 ms */ + } + else + { + CPU_xExitCritical(); + } + + CLOCK_SetXtal0Freq(16000000); + OS_u32SysTickInterval = SystemCoreClock / 1000; + OS_vStart(&u32Stat); + + *pu32PBLWord = 0x55aa0001; + + while(1) + { + OS_vRun((uint32*)&u32Stat); + } +} + diff --git a/source/System/IRQ.c b/source/System/IRQ.c new file mode 100644 index 0000000..b673ddd --- /dev/null +++ b/source/System/IRQ.c @@ -0,0 +1,660 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: IRQ */ +/* DESCRIPTION: This code is interrupt service routines */ +/* */ +/* FILE NAME: IRQ.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include "BUILD.h" + +#ifdef BUILD_MK60 +#include "mk60f12.h" +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +#include "mk64f12.h" +#endif //BUILD_MK64 + +#include +#include +#include +#include +#include "PERUART.h" +#include "IOAPI.h" +#include "MSG.h" +#include "irq.h" +#include "OS.h" +#include "dll.h" +#include "PERCAN.h" +#include "math.h" +#include "UDSAL.h" +#include "timer.h" +#include "tqueue.h" +#include "SYSAPI.h" +#include "PERADC.h" +#include "TEPM.h" +#include "IIC.h" + +#ifdef BUILD_PBL +#include "ECUHostA_PBL.h" +#endif //BUILD_PBL + + +SYSMPU_Type IRQ_stMPU; +#ifdef BUILD_MK60 +IRQRXCallBack IRQ_apfRXCallBack[100]; +IRQTXCallBack IRQ_apfTXCallBack[100]; +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +IRQRXCallBack IRQ_apfRXCallBack[100]; +IRQTXCallBack IRQ_apfTXCallBack[100]; +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +IRQRXCallBack IRQ_apfRXCallBack[PERIPH_COUNT_IRQn]; +IRQTXCallBack IRQ_apfTXCallBack[PERIPH_COUNT_IRQn]; +#endif //BUILD_SAM3X8E + +#ifdef BUILD_KERNEL_OR_KERNEL_APP +extern uint32 OS_u32SysTickInterval; +extern uint32 OS_u32SysRunTimeHigh; +extern uint32 OS_u32SysRunTimeLow; +extern tq_struct* OS_pstBackgroundDispatcherTask; +extern void BlinkyTick(void); +extern void SDHC1_Interrupt(void); +extern void OS_vBackgroundDispatcher(void); +#endif + +extern void NVIC_EnableIRQ(IRQn_Type IRQn); +extern void SYS_vAPISVC(void); +DLL_tstRXDLLData CAN_stRXDLLData; +bool IRQ_boEnableRTOS = TRUE; +static void IRQ_vCommonUART(tstUARTModule*, IOAPI_tenEHIOResource, IRQn_Type enIRQType); +static void IRQ_vCommonCAN(tstCANModule*, IOAPI_tenEHIOResource, IRQn_Type enIRQType); +static void SVC_Handler_Main(void); + +#if defined(BUILD_MK60) || defined(BUILD_SAM3X8E) || defined(BUILD_MK64) +void IRQ_vEnableIRQ(IRQn_Type enIRQType, IRQ_tenPRIO enPRIO, IRQRXCallBack pfRXCallBack, IRQTXCallBack pfTXCallBack) +{ + IRQ_apfRXCallBack[enIRQType] = pfRXCallBack; + IRQ_apfTXCallBack[enIRQType] = pfTXCallBack; + NVIC_ClearPendingIRQ(enIRQType); + + if (enIRQType == MK6X_FTM_PRIO_IRQ) enPRIO = 4; + + NVIC_SetPriority(enIRQType, enPRIO); + NVIC_EnableIRQ(enIRQType); +} +#endif + +#if defined(BUILD_MK60) || defined(BUILD_SAM3X8E) || defined (BUILD_MK64) +void IRQ_vDisableIRQ(IRQn_Type enIRQType) +{ + IRQ_apfRXCallBack[enIRQType] = NULL; + IRQ_apfTXCallBack[enIRQType] = NULL; + NVIC_DisableIRQ(enIRQType); +} +#endif + +#ifdef BUILD_KERNEL_OR_KERNEL_APP +task_queue IRQ_vSuspendThread(task_queue* stTaskQueueToSuspend) +{ + __asm(".EQU TASK_PC_OFFSET, 22"); + __asm(".EQU TASK_SP_OFFSET, 18"); + __asm(".EQU STACK_FRAME_BASE_OFFSET, 8"); + __asm(".EQU STACK_FRAME_SIZE, 32"); + __asm(".EQU FRAME_R0_OFFSET, 0"); + __asm(".EQU FRAME_R1_OFFSET, 4"); + __asm(".EQU FRAME_R2_OFFSET, 8"); + __asm(".EQU FRAME_R3_OFFSET, 12"); + __asm(".EQU FRAME_R12_OFFSET, 16"); + __asm(".EQU FRAME_LR_OFFSET, 20"); + __asm(".EQU FRAME_PC_OFFSET, 24"); + __asm(".EQU FRAME_XPSR_OFFSET, 28"); + __asm(".EQU MASK_XPSR_THUMB, 16777216"); + + // + // + // + // get first task in R1 + __asm("LDR R1, [R0]"); + + // get next task in R2 + __asm("LDR R2, [R1]"); + __asm("B TestQueueLast"); + __asm("FindQueueEndLoop:"); + __asm("MOV R3, R2"); + __asm("LDR R2, [R2]"); + __asm("TestQueueLast:"); + __asm("CMP R2, #0"); + __asm("BNE FindQueueEndLoop"); + // queue pointer is in R0, current task R1, end task R3 + + // change queue pointer to current task->next + __asm("LDR R2, [R1]"); + __asm("CMP R1, R2"); + __asm("BEQ ThreadSwapAbort"); + __asm("STR R2, [R0]"); + + // set end task->next to current task + __asm("STR R1, [R3]"); + + // set current task->next to NULL + __asm("MOV R3, #0"); + __asm("STR R3, [R1]"); + + // get thread address in R4 MATTHEW + // MOV R4, #255 + + // store current task program counter in task structure program counter + // STR R4, [R1, #TASK_PC_OFFSET] MATTHEW + + // update the task saved stack pointer + __asm("MRS R0, PSP"); + // MATTHEW for R4 PUSH NO!!!!!!! + // ADD R0, #4 + __asm("STR R0, [R1, #TASK_SP_OFFSET]"); + + // get background dispatcher task stack pointer + __asm("LDR R1, =OS_pstBackgroundDispatcherTask"); + __asm("LDR R1, [R1]"); + __asm("LDR R1, [R1, #TASK_SP_OFFSET]"); + + // set background dispatcher stack frame return address to + // dispatcher entry point always + __asm("LDR R2, =OS_vBackgroundDispatcher"); + __asm("ORR R2, #1"); + __asm("STR R2, [R1, #FRAME_PC_OFFSET]"); + + // set XPSR thumb bit always + //LDR R2, [R1, #FRAME_XPSR_OFFSET] + __asm("MOV R2, #0"); + __asm("ORR R2, #MASK_XPSR_THUMB"); + __asm("STR R2, [R1, #FRAME_XPSR_OFFSET]"); + + // store dispatcher stack pointer to PSP + __asm("MSR PSP, R1"); + + __asm("ThreadSwapAbort:"); +} +#endif //BUILD_KERNEL + +void IRQ_vReset(void) +{ + uint32 u32IDX; + + for (u32IDX = 0; u32IDX < (sizeof(IRQ_apfRXCallBack) / sizeof(IRQRXCallBack)); u32IDX++) + { + IRQ_apfRXCallBack[u32IDX] = NULL; + IRQ_apfRXCallBack[u32IDX] = NULL; + } +} + + +/*---------------------------------------------------------------------------- + SVC_Handler + *----------------------------------------------------------------------------*/ +#ifdef BUILD_PBL +__asm void SVC_Handler(void) +{} +#endif +#ifdef BUILD_SBL +__asm void SVC_Handler(void) +{} +#endif +#if defined(BUILD_PBL) || defined (BUILD_SBL) +void SVC_Handler(void) +{} +#endif +#ifdef BUILD_KERNEL_OR_KERNEL_APP +void SVC_Handler(void) +{ + //IMPORT SVC_Handler_Main + //IMPORT OS_stSVCDataStruct + __asm("TST lr, #4"); + __asm("ITE NE"); + __asm("MRSNE r0, PSP"); + __asm("MRSEQ r0, MSP"); + + // load the link register containing user module return address into R0 + // module return address will be used as module call handle - UID which + // infers privilege and is also unique COMPILER DEPENDENT STACK FRAME OFFSET??? + __asm("LDR R0, [R0, #28]"); + __asm("PUSH {R1}"); + __asm("LDR R1, =OS_stSVCDataStruct"); + __asm("STR R0, [R1, #4]"); + __asm("POP {R1}"); + + __asm("TST lr, #4"); + __asm("ITE NE"); + __asm("MRSNE r0, PSP"); + __asm("MRSEQ r0, MSP"); + SVC_Handler_Main(); +} +#endif //BUILD_KERNEL + +#ifdef BUILD_KERNEL_OR_KERNEL_APP +static void SVC_Handler_Main(void) +{ + SYS_vAPISVC(); +} +#endif + +/*---------------------------------------------------------------------------- + SysTick_Handler + *----------------------------------------------------------------------------*/ +void SysTick_Handler(void) +{ +#ifdef BUILD_PBL + PBL_vCyclicTask(); +#endif +#ifdef BUILD_SBL + SBL_vCyclicTask(); +#endif +#ifdef BUILD_KERNEL_OR_KERNEL_APP + /* declare data static because are usually consuming + a thread stack here for temp data! */ + static uint32 u32SysRunTimeLowOld; + static OS_tenOSState enOSState; + static uint32 u32Stat; + static task_queue* pstTaskQueue; + static task_queue* pstTaskQueueToSuspend; + static task_queue stTaskQueue; + + stTaskQueue = NULL; + pstTaskQueueToSuspend = NULL; + + OS_u32SysRunTimeLow += OS_u32SysTickInterval; + OS_u32SysRunTimeHigh = (u32SysRunTimeLowOld > OS_u32SysRunTimeLow) ? + OS_u32SysRunTimeHigh + 1 : OS_u32SysRunTimeHigh; + u32SysRunTimeLowOld = OS_u32SysRunTimeLow; + + /* call this OS module run function from the interrupt context although + normally OS module runs are called in co-operative multitask context */ + TIMER_vRun(&u32Stat); + + enOSState = OS_enGetState(); + + if (OS_enOSStateOSStarted == enOSState) + //if ((OS_enOSStateOSStarted == enOSState) && + // (TRUE == IRQ_boEnableRTOS)) + { + /* check if kernel cyclic queue is active */ + if(NULL == stTaskQueue) + { + pstTaskQueue = OS_stGetOSQueue(OS_enKERNELQueueCyclic); + stTaskQueue = *pstTaskQueue; + if (NULL != stTaskQueue) + { + OS_vOverrunTaskReport(OS_enKERNELQueueCyclic); + /* call schedule - no thread to swap out we are still co-op tasking */ + //OS_vSchedule(OS_enOSSchedulerTick); + } + } + + /* check if client cyclic queue is active */ + if(NULL == stTaskQueue) + { + pstTaskQueue = OS_stGetOSQueue(OS_enCLIENTQueueCyclic); + stTaskQueue = *pstTaskQueue; + if(NULL != stTaskQueue) + { + OS_vOverrunTaskReport(OS_enCLIENTQueueCyclic); + /* call schedule - no thread to swap out we are still co-op tasking */ + //OS_vSchedule(OS_enOSSchedulerTick); + } + } + + /* check if kernel thread queue is active */ + if(NULL == stTaskQueue) + { + pstTaskQueue = OS_stGetOSQueue(OS_enKERNELQueueThread); + stTaskQueue = *pstTaskQueue; + if(NULL != stTaskQueue) + { + /* swap out thread before calling schedule */ + pstTaskQueueToSuspend = pstTaskQueue; + OS_vSchedule(OS_enOSSchedulerTick); + } + } + + /* check if client thread queue is active */ + if(NULL == stTaskQueue) + { + pstTaskQueue = OS_stGetOSQueue(OS_enCLIENTQueueThread); + stTaskQueue = *pstTaskQueue; + if(NULL != stTaskQueue) + { + /* swap out thread before calling schedule */ + pstTaskQueueToSuspend = pstTaskQueue; + OS_vSchedule(OS_enOSSchedulerTick); + } + } + + if(NULL != pstTaskQueueToSuspend) + { + stTaskQueue = IRQ_vSuspendThread(pstTaskQueueToSuspend); + } + + stTaskQueue = NULL; + } + else if (OS_enOSStartRequest == enOSState) + { + OS_vSetState(OS_enOSStateOSStarted); + } +#endif +} + + +/*---------------------------------------------------------------------------- + MemManage_Handler + *----------------------------------------------------------------------------*/ +void MemManage_Handler(void) +{ + memcpy((void*)&IRQ_stMPU, (void*)SYSMPU_BASE, sizeof(SYSMPU_Type)); + while(1); +} + +/*---------------------------------------------------------------------------- + ENET_TX_Handlers + *----------------------------------------------------------------------------*/ +void ENET_Transmit_IRQHandler(void) +{ + +} + +/*---------------------------------------------------------------------------- + ENET_RX_Handlers + *----------------------------------------------------------------------------*/ +void ENET_Receive_IRQHandler(void) +{ +// ENET_EIMR_BABT_MASK +// ENET_EIMR_GRA_MASK +// ENET_EIMR_EBERR_MASK +// ENET_EIMR_LC_MASK +// ENET_EIMR_RL_MASK +// ENET_EIMR_UN_MASK +#ifdef BUILD_ENET + if(ENE_xIntActivated(ENET_EIMR_BABR_MASK)) + { + ENE_xIntClearFlag(ENET_EIMR_BABR_MASK); + } + + if(ENE_xIntActivated(ENET_EIMR_RXF_MASK)) + { + ENE_xIntClearFlag(ENET_EIMR_RXF_MASK); + ENE_vReceiveFrame(); + } +#endif +} + +/*---------------------------------------------------------------------------- + ENET_ERR_Handlers + *----------------------------------------------------------------------------*/ +void ENET_Error_IRQHandler(void) +{ + + +} + + + + + + + + + +/*---------------------------------------------------------------------------- + UART0_Handlers + *----------------------------------------------------------------------------*/ +void UART0_RX_TX_IRQHandler(void) +{ + UART_Type* pstUART = UART0; + IRQ_vCommonUART(pstUART, EH_VIO_UART1, UART0_RX_TX_IRQn); +} + +void UART0_ERR_IRQHandler(void){} + +/*---------------------------------------------------------------------------- + UART1_Handlers + *----------------------------------------------------------------------------*/ +void UART1_RX_TX_IRQHandler(void) +{ + UART_Type* pstUART = UART1; + IRQ_vCommonUART(pstUART, EH_VIO_UART2, UART1_RX_TX_IRQn); +} + +void UART1_ERR_IRQHandler(void){} + +/*---------------------------------------------------------------------------- + UART2_Handlers + *----------------------------------------------------------------------------*/ +void UART2_RX_TX_IRQHandler(void) +{ + UART_Type* pstUART = UART2; + IRQ_vCommonUART(pstUART, EH_VIO_UART3, UART2_RX_TX_IRQn); +} + +void UART2_ERR_IRQHandler(void){} + +/*---------------------------------------------------------------------------- + UART5_Handlers + *----------------------------------------------------------------------------*/ +void UART3_RX_TX_IRQHandler(void) +{ + UART_Type* pstUART = UART3; + IRQ_vCommonUART(pstUART, EH_VIO_UART4, UART3_RX_TX_IRQn); +} + +void UART3_ERR_IRQHandler(void){} + +/*---------------------------------------------------------------------------- + UART4_Handlers + *----------------------------------------------------------------------------*/ +void UART4_RX_TX_IRQHandler(void) +{ + UART_Type* pstUART = UART4; + IRQ_vCommonUART(pstUART, EH_VIO_UART5, UART4_RX_TX_IRQn); +} + +void UART4_ERR_IRQHandler(void){} + +/*---------------------------------------------------------------------------- + UART5_Handlers + *----------------------------------------------------------------------------*/ +void UART5_RX_TX_IRQHandler(void) +{ + UART_Type* pstUART = UART5; + IRQ_vCommonUART(pstUART, EH_VIO_UART6, UART5_RX_TX_IRQn); +} + +void UART5_ERR_IRQHandler(void){} + + +/*---------------------------------------------------------------------------- + SDHC_Handler + *----------------------------------------------------------------------------*/ +void SDHC_IRQHandler(void) +{ +#ifdef BUILD_KERNEL_OR_KERNEL_APP + //SDHC1_Interrupt(); +#endif +} + +/*---------------------------------------------------------------------------- + ADCX_Handlers + *----------------------------------------------------------------------------*/ +void ADC0_IRQHandler(void) +{ +#ifdef BUILD_KERNEL_OR_KERNEL_APP + IRQ_apfRXCallBack[ADC0_IRQn](EH_VIO_ADC0, NULL); +#endif +} + +void ADC1_IRQHandler(void) +{ +#ifdef BUILD_KERNEL_OR_KERNEL_APP + IRQ_apfRXCallBack[ADC1_IRQn](EH_VIO_ADC1, NULL); +#endif +} + +void ADC2_IRQHandler(void) +{ +#if defined(BUILD_KERNEL_OR_KERNEL_APP) && defined(BUILD_MK60) + IRQ_apfRXCallBack[ADC2_IRQn](NULL, NULL); + #endif +} + +void ADC3_IRQHandler(void) +{ +#if defined(BUILD_KERNEL_OR_KERNEL_APP) && defined(BUILD_MK60) + IRQ_apfRXCallBack[ADC3_IRQn](NULL, NULL); +#endif +} + + +/*---------------------------------------------------------------------------- + FTMX_Handlers + *----------------------------------------------------------------------------*/ +void FTM0_IRQHandler(void) +{ +#ifdef BUILD_KERNEL_OR_KERNEL_APP + uint32 u32Prio = 1; + IRQ_apfRXCallBack[FTM0_IRQn]((IOAPI_tenEHIOResource)EH_VIO_FTM0, (void*)&u32Prio); +#endif +} + +void FTM1_IRQHandler(void) +{ +#ifdef BUILD_KERNEL_OR_KERNEL_APP + uint32 u32Prio = 1; + IRQ_apfRXCallBack[FTM1_IRQn]((IOAPI_tenEHIOResource)EH_VIO_FTM1, (void*)&u32Prio); +#endif +} + +void FTM2_IRQHandler(void) +{ +#ifdef BUILD_KERNEL_OR_KERNEL_APP + uint32 u32Prio = 1; + IRQ_apfRXCallBack[FTM2_IRQn]((IOAPI_tenEHIOResource)EH_VIO_FTM2, (void*)&u32Prio); +#endif +} + +void FTM3_IRQHandler(void) +{ +#ifdef BUILD_KERNEL_OR_KERNEL_APP + uint32 u32Prio = 1; + IRQ_apfRXCallBack[FTM3_IRQn]((IOAPI_tenEHIOResource)EH_VIO_FTM3, (void*)&u32Prio); +#endif +} + +/*---------------------------------------------------------------------------- + IICX_Handlers + *----------------------------------------------------------------------------*/ +void I2C0_IRQHandler(void) +{ +#ifdef BUILD_KERNEL_OR_KERNEL_APP + IRQ_apfRXCallBack[I2C0_IRQn](NULL, NULL); +#endif +} + +void I2C1_IRQHandler(void) +{ +#ifdef BUILD_KERNEL_OR_KERNEL_APP + IRQ_apfRXCallBack[I2C1_IRQn](NULL, NULL); +#endif +} + +#ifdef BUILD_MK64 +void CAN0_ORed_Message_buffer_IRQHandler(void) +{ + tstCANModule* pstCAN = CAN0; + + IRQ_vCommonCAN(pstCAN, EH_VIO_CAN1, CAN0_ORed_Message_buffer_IRQn); +} +#endif //BUILD_MK64 + +#ifdef BUILD_MK60 +void CAN1_ORed_Message_buffer_IRQHandler(void) +{ + CAN_Type* pstCAN = CAN1; + + IRQ_vCommonCAN(pstCAN, EH_VIO_CAN2, CAN0_ORed_Message_buffer_IRQn); +} +#endif + +static void IRQ_vCommonCAN(tstCANModule* pstCAN, IOAPI_tenEHIOResource enEHIOResource, IRQn_Type enIRQType) +{ +#if defined(BUILD_MK60) || defined(BUILD_MK64) + CANHA_tstCANMB* pstCANMB; + uint32 u32IMask = 1; + uint32 u32MBIDX; + uint32 u32IMaskMax = MATH_u32IDXToMask(CAN_nCANMailboxCount); + + while(u32IMask < u32IMaskMax) + { + if((u32IMask & (pstCAN -> IFLAG1)) == u32IMask) + { + pstCANMB = (CANHA_tstCANMB*)&pstCAN -> MB[0]; + u32MBIDX = MATH_u32MaskToIDX(u32IMask); + pstCANMB += u32MBIDX; + + while(((pstCANMB -> u32CS & CAN_CS_CODE_MASK) + >> CAN_CS_CODE_SHIFT) == CAN_nCANMBXBusy); + + IRQ_apfRXCallBack[enIRQType](enEHIOResource, (void*)pstCANMB); + pstCAN -> IFLAG1 |= u32IMask; + } + u32IMask <<= 1; + /* abort loop if all flags clear */ + if (pstCAN -> IFLAG1 == 0) + { + u32IMask = u32IMaskMax; + } + } +#endif +} + +void IRQ_vCommonUART(UART_Type* pstUART, IOAPI_tenEHIOResource enEHIOResource, IRQn_Type enIRQType) +{ + DLL_tstRXDLLData stRXDLLData; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + if(((pstUART -> S1) & UART_S1_TDRE_MASK) == UART_S1_TDRE_MASK) + { + if(((pstUART -> C2) & UART_C2_TIE_MASK) == UART_C2_TIE_MASK) + + IRQ_apfTXCallBack[enIRQType](enEHIOResource, NULL); + } + + if(((pstUART -> S1) & UART_S1_RDRF_MASK) == UART_S1_RDRF_MASK) + { + stRXDLLData.u8Data[0] = UART_u8GetChar(enEHIOResource); + stRXDLLData.u8DataCount = 1; + stRXDLLData.u8RXByteIDX = 0; + IRQ_apfRXCallBack[enIRQType](enEHIOResource, (void*)&stRXDLLData); + } + + if(((pstUART -> S1) & UART_S1_FE_MASK) == UART_S1_FE_MASK) + { + (void)UART_u8GetChar(enEHIOResource); + } +#endif //BUILD_MK6X +} + +void IRQ_vEnableRTOS(bool boEnable) +{ + IRQ_boEnableRTOS = boEnable; +} + + + + diff --git a/source/System/IRQ.h b/source/System/IRQ.h new file mode 100644 index 0000000..30e9180 --- /dev/null +++ b/source/System/IRQ.h @@ -0,0 +1,71 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: IRQ Header File */ +/* DESCRIPTION: This code is interrupt common function definitions */ +/* */ +/* FILE NAME: IRQ.h */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#ifdef KERNEL + +#ifndef IRQ_H +#define IRQ_H + +#include "mk64f12.h" +#include "CANHA.h" +#include "CPUAbstract.h" +#include "declarations.h" +#include "dll.h" +#include "IOAPI.h" +#include "math.h" +#include "PERCAN.h" +#include "SYSAPI.h" +#include "UARTHA.h" + +#ifdef BUILD_SAM3X8E +#include "uotghs_device.h" +#endif + +#if defined(BUILD_MK60) || defined(BUILD_MK64) +#define MK6X_FTM_PRIO_IRQ FTM3_IRQn +#endif + +#include "dll.h" + +typedef void (*IRQRXCallBack)(IOAPI_tenEHIOResource, void*); +typedef void (*IRQTXCallBack)(IOAPI_tenEHIOResource, void*); + +typedef enum +{ + IRQ_enPRIO_0, + IRQ_enPRIO_1, + IRQ_enPRIO_2, + IRQ_enPRIO_3, + IRQ_enPRIO_4, + IRQ_enPRIO_5, + IRQ_enPRIO_6, + IRQ_enPRIO_7, + IRQ_enPRIO_8, + IRQ_enPRIO_9, + IRQ_enPRIO_10, + IRQ_enPRIO_11, + IRQ_enPRIO_12, + IRQ_enPRIO_13, + IRQ_enPRIO_14, + IRQ_enPRIO_15 +} IRQ_tenPRIO; + +void IRQ_vEnableIRQ(IRQn_Type, IRQ_tenPRIO, IRQRXCallBack, IRQTXCallBack); +void IRQ_vDisableIRQ(IRQn_Type); +void IRQ_vReset(void); +void IRQ_vEnableRTOS(bool boEnable); + +#endif // IRQ_H + +#endif // KERNEL + diff --git a/source/System/SYS.h b/source/System/SYS.h new file mode 100644 index 0000000..4bfd9cd --- /dev/null +++ b/source/System/SYS.h @@ -0,0 +1,57 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. */ +/* All rights reserved. */ +/******************************************************************************/ +/* */ +/* PACKAGE TITLE: System Header File */ +/* DESCRIPTION: This code various system for oscillator and bus */ +/* frequencies, kernel thread memory usage etc */ +/* */ +/* FILE NAME: sys.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#ifndef SYS_H +#define SYS_H + +#include + + +/* GLOBAL MACRO DEFINITIONS ***************************************************/ +#define KERNEL + +#ifndef DEBUG +#define DEBUG +#endif // DEBUG +#define SYS_TASK_PRIORITISE + +#define SYS_FREQ_OSC (16000000u) +#define SYS_FREQ_OSCER (50000000u) +#define SYS_FREQ_PLL (120000000u) +#define SYS_FREQ_NS_IN_1S (1000000000u) + +#define SYS_CORE_CLK_DIV (1u) +#define SYS_BUS_CLK_DIV (2u) +#define SYS_FLEXBUS_CLK_DIV (2u) +#define SYS_FLASH_CLK_DIV (4u) + +#define SYS_FREQ_CORE (SYS_FREQ_PLL / SYS_CORE_CLK_DIV) +#define SYS_FREQ_BUS (SYS_FREQ_PLL / SYS_BUS_CLK_DIV) +#define SYS_FREQ_FLEXBUS (SYS_FREQ_PLL / SYS_FLEXBUS_CLK_DIV) +#define SYS_FREQ_FLASH (SYS_FREQ_PLL / SYS_FLASH_CLK_DIV) + +#define SYS_PERIOD_OSC_nS (SYS_FREQ_NS_IN_1S / SYS_FREQ_OSC) +#define SYS_PERIOD_PLL_nS (SYS_FREQ_NS_IN_1S / SYS_FREQ_PLL) +#define SYS_PERIOD_RTI_nS (1000000u) +/*CR1_113*/ + +#define SYS_THREAD_STACK_SIZE (512u) +#define SYS_THREAD_MAX (5u) +#define SYS_CLIENT_MODULES_MAX (10u) +/*CR1_114*/ + +#endif // SYS_H + diff --git a/source/System/SYSAPI.c b/source/System/SYSAPI.c new file mode 100644 index 0000000..6c29a04 --- /dev/null +++ b/source/System/SYSAPI.c @@ -0,0 +1,488 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: SYSAPI */ +/* DESCRIPTION: This code provides functions for running system calls */ +/* */ +/* FILE NAME: SYSAPI.c */ +/* REVISION HISTORY: 28-03-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ + +#include +#ifdef KERNEL + +#include "SYSAPI.h" +#include "CEM.h" +#include "CEMAPI.h" +#include "DLL.h" +#include "PROTAPI.h" +#include "IOAPI.h" +#include "DACAPI.h" +#include +#include "MSG.h" +#include "PERADC.h" +#include "PERWDT.h" +#include "DAC.h" +#include +#include "os.h" +#include "RESM.h" +#include "TEPM.h" +#include "ADCAPI.h" +#include "DACAPI.h" +#include "MAPSAPI.h" +#include +#include "SPREADSAPI.h" +#include "TABLESAPI.h" +#include "DIAGAPI.h" +#include "CQUEUE.h" +#include "SRLTFR.h" +#include "TEPM.h" +#include "CTRL.h" +#include +#include +#include "PERUART.h" +#include "FEE.h" +#include "KERNELDIAG.h" +#include "MAPS.h" + +extern uint8 UDSAL_au8Mode1DataBuffer[]; +extern uint8 UDSAL_au8Mode2DataBuffer[]; +extern uint8 UDSAL_au8Mode3DataBuffer[]; +extern uint8 UDSAL_au8Mode4DataBuffer[]; + +void SYS_vAPISVC(void) +{ + static uint32 u32Temp; + static puint16 pu16Temp; + static CTRLAPI_ttPIDIDX PIDIDX; + static SPREADAPI_ttSpreadIDX tSpreadIDX; + static TABLEAPI_ttTableIDX tTableIDX; + static MAPSAPI_ttMapIDX tMapIDX; + static bool boResult; + + + switch (OS_stSVCDataStruct.enSVCID) + { + case SYSAPI_enSetClientStartTask: + { + OS_stSVCDataStruct.enSVCResult = + CLIENT_vAddTask(OS_enCLIENTQueueStart, *(SYSAPI_tpfUserTaskFunction*)OS_stSVCDataStruct.pvArg1, *(TASKAPI_tenPriority*)OS_stSVCDataStruct.pvArg2, *(TASKAPI_tenRateMs*)OS_stSVCDataStruct.pvArg3); + break; + } + + case SYSAPI_enSetClientCyclicTask: + { + OS_stSVCDataStruct.enSVCResult = + CLIENT_vAddTask(OS_enCLIENTQueueCyclic, *(SYSAPI_tpfUserTaskFunction*)OS_stSVCDataStruct.pvArg1, *(TASKAPI_tenPriority*)OS_stSVCDataStruct.pvArg2, *(TASKAPI_tenRateMs*)OS_stSVCDataStruct.pvArg3); + break; + } + + case SYSAPI_enSetClientTerminateTask: + { + OS_stSVCDataStruct.enSVCResult = + CLIENT_vAddTask(OS_enCLIENTQueueTerminate, *(SYSAPI_tpfUserTaskFunction*)OS_stSVCDataStruct.pvArg1, *(TASKAPI_tenPriority*)OS_stSVCDataStruct.pvArg2, *(TASKAPI_tenRateMs*)OS_stSVCDataStruct.pvArg3); + break; + } + + case SYSAPI_enRequestIOResource: + { + u32Temp = (SYSAPI_ttClientHandle)RESM_u32RequestEHIOResource(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1, OS_stSVCDataStruct.tClientHandle); + OS_stSVCDataStruct.enSVCResult = (u32Temp == OS_stSVCDataStruct.tClientHandle) ? SYSAPI_enOK : SYSAPI_enFail; + break; + } + + case SYSAPI_enInitialiseIOResource: + { + if ((IOAPI_enDIOOutput == *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2) || (IOAPI_enDIOOutput == *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2)) + { + IO_vInitDIOResource(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1, *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2, *(IOAPI_tenDriveStrength*)OS_stSVCDataStruct.pvArg3); + } + + else if ((IOAPI_enDIOInput == *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2) || (IOAPI_enDIOInput == *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2)) + { + IO_vInitDIOResource(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1, *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2, *(IOAPI_tenDriveStrength*)OS_stSVCDataStruct.pvArg3); + } + + else if ((IOAPI_enADSE == *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2) || (IOAPI_enADD == *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2)) + { + IO_vInitADCResource(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1, *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2, (ADCAPI_tstADCCB*)OS_stSVCDataStruct.pvArg3); + } + + else if (IOAPI_enDAC == *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2) + { + IO_vInitDACResource(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1, *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2, (DACAPI_tstDACCB*)OS_stSVCDataStruct.pvArg3); + } + + else if ((IOAPI_enIICBus == *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2) + || (IOAPI_enUARTBus == *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2) + || (IOAPI_enSPIBus == *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2) + || (IOAPI_enCANBus == *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2) + || (IOAPI_enUSBChannel == *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2) + || (IOAPI_enENETChannel == *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2)) + { + OS_stSVCDataStruct.enSVCResult = IO_enInitCommsResource(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1, (IOAPI_tstPortConfigCB*)OS_stSVCDataStruct.pvArg3); + } + + else if (IOAPI_enTEPM == *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2) + { + OS_stSVCDataStruct.enSVCResult = TEPM_vInitTEPMResource(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1, (TEPMAPI_tstTEPMResourceCB*)OS_stSVCDataStruct.pvArg3); + } + + else if (IOAPI_enCaptureCompare == *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2) + { + OS_stSVCDataStruct.enSVCResult = IO_enInitTEPMChannel(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1, (TEPMAPI_tstTEPMChannelCB*)OS_stSVCDataStruct.pvArg3, FALSE); + } + + else if (IOAPI_enPWM == *(IOAPI_tenEHIOType*)OS_stSVCDataStruct.pvArg2) + { + OS_stSVCDataStruct.enSVCResult = IO_enInitTEPMChannel(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1, (TEPMAPI_tstTEPMChannelCB*)OS_stSVCDataStruct.pvArg3, TRUE); + } + + else + { + OS_stSVCDataStruct.enSVCResult = SYSAPI_enResourceUnavailable; + } + + break; + } + + case SYSAPI_enInitialiseCTRLResource: + { + if (CTRLAPI_enPID == *(CTRLAPI_tenCTRLType*)OS_stSVCDataStruct.pvArg1) + { + PIDIDX = CTRL_tRequestKernelPIDController((CTRLAPI_tstPIDCB*)OS_stSVCDataStruct.pvArg2); + OS_stSVCDataStruct.tClientHandle = (uint32)PIDIDX; + OS_stSVCDataStruct.enSVCResult = (-1 < PIDIDX) ? SYSAPI_enOK : SYSAPI_enResourceUnavailable; + break; + } + + break; + } + + case SYSAPI_enIterateCTRLResource: + { + if (CTRLAPI_enPID == *(CTRLAPI_tenCTRLType*)OS_stSVCDataStruct.pvArg1) + { + PIDIDX = *(CTRLAPI_tenCTRLType*)OS_stSVCDataStruct.pvArg2; + CTRL_vIteratePID(PIDIDX); + OS_stSVCDataStruct.enSVCResult = (-1 < PIDIDX) ? SYSAPI_enOK : SYSAPI_enResourceUnavailable; + break; + } + + break; + } + + case SYSAPI_enInitialiseSpreadResource: + { + tSpreadIDX = SPREAD_tRequestKernelSpread((SPREADAPI_tstSpreadCB*)OS_stSVCDataStruct.pvArg1); + OS_stSVCDataStruct.tClientHandle = (uint32)tSpreadIDX; + OS_stSVCDataStruct.enSVCResult = (-1 < tSpreadIDX) ? SYSAPI_enOK : SYSAPI_enResourceUnavailable; + break; + } + + case SYSAPI_enInitialiseTableResource: + { + tTableIDX = TABLE_tRequestKernelTable((TABLEAPI_tstTableCB*)OS_stSVCDataStruct.pvArg1); + OS_stSVCDataStruct.tClientHandle = (uint32)tTableIDX; + OS_stSVCDataStruct.enSVCResult = (-1 < tSpreadIDX) ? SYSAPI_enOK : SYSAPI_enResourceUnavailable; + break; + } + + case SYSAPI_enInitialiseMapResource: + { + tMapIDX = MAP_tRequestKernelMap((MAPSAPI_tstMapCB*)OS_stSVCDataStruct.pvArg1); + OS_stSVCDataStruct.tClientHandle = (uint32)tMapIDX; + OS_stSVCDataStruct.enSVCResult = (-1 < tSpreadIDX) ? SYSAPI_enOK : SYSAPI_enResourceUnavailable; + break; + } + + case SYSAPI_enAssertDIOResource: + { + IO_vAssertDIOResource(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1, *(IOAPI_tenTriState*)OS_stSVCDataStruct.pvArg2); + break; + } + + case SYSAPI_enGetDIOResource: + { + boResult = IO_boGetDIOResource(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1); + OS_stSVCDataStruct.pvArg1 = (void*)&boResult; + break; + } + + case SYSAPI_enTriggerADQueue: + { + boResult = ADC_vTriggerQueue(*(ADCAPI_tenTrigger*)OS_stSVCDataStruct.pvArg1); + OS_stSVCDataStruct.enSVCResult = (TRUE == boResult) ? SYSAPI_enOK : SYSAPI_enBadArgument; + break; + } + + case SYSAPI_enRequestIOBusTransfer: + { + switch ((IOAPI_tenEHIOResource)OS_stSVCDataStruct.pvArg1) + { + case EH_VIO_IIC1: + case EH_VIO_IIC2: + case EH_VIO_SPI1: + case EH_VIO_SPI2: + { + OS_stSVCDataStruct.enSVCResult = SRLTFR_enEnqueue((IOAPI_tstTransferCB*)OS_stSVCDataStruct.pvArg2); + break; + } + default: + { + OS_stSVCDataStruct.enSVCResult = SYSAPI_enBadResource; + break; + } + } + break; + } + + case SYSAPI_enAppendTEPMQueue: + { + TEPM_vAppendTEPMQueue(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1, (TEPMAPI_tstTimedUserEvent*)OS_stSVCDataStruct.pvArg2, *(TEPMAPI_ttEventCount*)OS_stSVCDataStruct.pvArg3); + break; + } + + case SYSAPI_enConfigureUserTEPMInput: + { + TEPM_vConfigureUserTEPMInput(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1, (TEPMAPI_tstTimedUserEvent*)OS_stSVCDataStruct.pvArg2); + break; + } + + case SYSAPI_enConfigureKernelTEPMOutput: + { + TEPM_vConfigureKernelTEPMOutput(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1, (TEPMAPI_tstTimedKernelEvent*)OS_stSVCDataStruct.pvArg2, *(TEPMAPI_ttEventCount*)OS_stSVCDataStruct.pvArg3); + break; + } + + case SYSAPI_enWriteDACQueue: + { + DAC_vWriteDACQueue(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1, (DACAPI_ttOutputVoltage*)OS_stSVCDataStruct.pvArg2); + break; + } + + case SYSAPI_enCalculateSpread: + { + boResult = SPREAD_vCalculate(*(SPREADAPI_ttSpreadIDX*)OS_stSVCDataStruct.pvArg1); + OS_stSVCDataStruct.enSVCResult = (TRUE == boResult) ? SYSAPI_enOK : SYSAPI_enBadArgument; + break; + } + + case SYSAPI_enCalculateTable: + { + boResult = TABLE_vCalculate(*(TABLEAPI_ttTableIDX*)OS_stSVCDataStruct.pvArg1); + OS_stSVCDataStruct.enSVCResult = (TRUE == boResult) ? SYSAPI_enOK : SYSAPI_enBadArgument; + break; + } + + case SYSAPI_enCalculateMap: + { + boResult = MAP_vCalculate(*(MAPSAPI_ttMapIDX*)OS_stSVCDataStruct.pvArg1); + OS_stSVCDataStruct.enSVCResult = (TRUE == boResult) ? SYSAPI_enOK : SYSAPI_enBadArgument; + break; + } + + case SYSAPI_enSetDiagCallback: + { + DIAG_vSetCallBack(*(DIAGAPI_tenCallBackType*)OS_stSVCDataStruct.pvArg1, OS_stSVCDataStruct.pvArg2); + break; + } + + case SYSAPI_enGetTimerValue: + { + if ((EH_VIO_FTM0 <= *(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1) && + (EH_VIO_FTM3 >= *(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1)) + { + TEPM_u32GetTimerVal(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1, OS_stSVCDataStruct.pvArg2); + } + break; + } + + case SYSAPI_enGetCRC16: + { + pu16Temp = (puint16)CRC16_pu16CalcCRC(*(uint16*)OS_stSVCDataStruct.pvArg1, (uint8*)OS_stSVCDataStruct.pvArg2, *(uint16*)OS_stSVCDataStruct.pvArg3); + OS_stSVCDataStruct.pvData = (void*)pu16Temp; + OS_stSVCDataStruct.enSVCResult = SYSAPI_enOK; + break; + } + + case SYSAPI_enCheckPartition: + { + boResult = FEE_boCheckPartition(); + OS_stSVCDataStruct.enSVCResult = (TRUE == boResult) ? SYSAPI_enOK : SYSAPI_enBadPartition; + break; + } + + case SYSAPI_enNVMWorkingCopy: + { + boResult = FEE_boNVMWorkingCopy(*(bool*)OS_stSVCDataStruct.pvArg1, *(bool*)OS_stSVCDataStruct.pvArg2); + OS_stSVCDataStruct.enSVCResult = (TRUE == boResult) ? SYSAPI_enOK : SYSAPI_enBadNVMWorkingCopy; + break; + } + + case SYSAPI_enSetupWorkingPage: + { + boResult = FEE_boSetWorkingData((uint8*)*(uint32*)OS_stSVCDataStruct.pvArg1, *(uint16*)OS_stSVCDataStruct.pvArg2); + OS_stSVCDataStruct.enSVCResult = (TRUE == boResult) ? SYSAPI_enOK : SYSAPI_enBadArgument; + break; + } + + case SYSAPI_enQueueCANMessage: + { + boResult = DLL_vQueueCANMessage(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1, (PROTAPI_tstCANMsg*)OS_stSVCDataStruct.pvArg2); + break; + } + + case SYSAPI_enSetupCrankTriggerEdgePattern: + { + CEM_tstPatternSetupCB* pstPatternSetupCB = (CEM_tstPatternSetupCB*)OS_stSVCDataStruct.pvArg2; + + IOAPI_tenEdgePolarity enEdgePolarity = pstPatternSetupCB->enEdgePolarity; + bool boFirstEdgeRising = pstPatternSetupCB->boFirstEdgeRising; + uint32 u32TriggerType = pstPatternSetupCB->u32TriggerType; + + boResult = CEM_boPopulateCrankEdgeArrays((puint16)OS_stSVCDataStruct.pvArg1, boFirstEdgeRising, enEdgePolarity, u32TriggerType); + OS_stSVCDataStruct.enSVCResult = (TRUE == boResult) ? SYSAPI_enOK : SYSAPI_enBadArgument; + break; + } + + case SYSAPI_enSetupSyncPointsPattern: + { + CEM_vSetSyncPhaseRepeats(*(uint32*)OS_stSVCDataStruct.pvArg2); + boResult = CEM_boPopulateSyncPointsArray((puint16)OS_stSVCDataStruct.pvArg1); + OS_stSVCDataStruct.enSVCResult = (TRUE == boResult) ? SYSAPI_enOK : SYSAPI_enBadArgument; + break; + } + + case SYSAPI_enResetWatchdog: + { + //boResult = WDT_boReset(0); + OS_stSVCDataStruct.enSVCResult = (TRUE == boResult) ? SYSAPI_enOK : SYSAPI_enBadArgument; + break; + } + + case SYSAPI_enGetSpreadResult: + { + SPREADAPI_tstSpreadResult* pstSpreadResult = SPREAD_pstGetSpread(*(TABLEAPI_ttTableIDX*)OS_stSVCDataStruct.pvArg1); + OS_stSVCDataStruct.enSVCResult = SYSAPI_enOK; + OS_stSVCDataStruct.pvArg1 = (void*)pstSpreadResult; + break; + } + + case SYSAPI_enGetRawCommsBuffer: + { + OS_stSVCDataStruct.enSVCResult = SYSAPI_enOK; + OS_stSVCDataStruct.pvArg1 = DLL_pvGetBuffered(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1); + break; + } + + case SYSAPI_enTEPMAsyncRequest: + { + TEPM_vAsyncRequest(); + OS_stSVCDataStruct.enSVCResult = SYSAPI_enOK; + break; + } + + case SYSAPI_enSetupSimpleCamSync: + { + CEM_vSetupSimpleCamSync(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1, *(bool*)OS_stSVCDataStruct.pvArg2, *(uint32*)OS_stSVCDataStruct.pvArg3); + break; + } + + case SYSAPI_enSetupWatchdog: + { + WDT_vStart(*(uint16*)OS_stSVCDataStruct.pvArg1, *(uint16*)OS_stSVCDataStruct.pvArg2); + break; + } + + case SYSAPI_enGetMode1Buffer: + { + OS_stSVCDataStruct.enSVCResult = SYSAPI_enOK; + OS_stSVCDataStruct.pvArg1 = UDSAL_au8Mode1DataBuffer; + break; + } + + case SYSAPI_enGetMode2Buffer: + { + OS_stSVCDataStruct.enSVCResult = SYSAPI_enOK; + OS_stSVCDataStruct.pvArg1 = UDSAL_au8Mode2DataBuffer; + break; + } + + case SYSAPI_enGetMode3Buffer: + { + OS_stSVCDataStruct.enSVCResult = SYSAPI_enOK; + OS_stSVCDataStruct.pvArg1 = UDSAL_au8Mode3DataBuffer; + break; + } + + case SYSAPI_enGetMode4Buffer: + { + OS_stSVCDataStruct.enSVCResult = SYSAPI_enOK; + OS_stSVCDataStruct.pvArg1 = UDSAL_au8Mode4DataBuffer; + break; + } + + case SYSAPI_enGetByteQueue: + { + switch (*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1) + { + case EH_VIO_UART1: + case EH_VIO_UART2: + { + OS_stSVCDataStruct.pvArg1 = (void*)UART_pstGetQueue(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1); + OS_stSVCDataStruct.enSVCResult = SYSAPI_enOK; + break; + } + default: + { + OS_stSVCDataStruct.enSVCResult = SYSAPI_enFail; + } + } + break; + } + + case SYSAPI_enGetByteQueueBuffer: + { + switch (*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1) + { + case EH_VIO_UART1: + case EH_VIO_UART2: + { + OS_stSVCDataStruct.pvArg1 = (void*)UART_pu8GetQueueBuffer(*(IOAPI_tenEHIOResource*)OS_stSVCDataStruct.pvArg1); + OS_stSVCDataStruct.enSVCResult = SYSAPI_enOK; + break; + } + default: + { + OS_stSVCDataStruct.enSVCResult = SYSAPI_enFail; + } + } + } + + case SYSAPI_enSetFuelCuts: + { + TEPM_vSetFuelCutsMask(*(uint32*)OS_stSVCDataStruct.pvArg1, *(uint32*)OS_stSVCDataStruct.pvArg2, *(uint32*)OS_stSVCDataStruct.pvArg3); + break; + } + + case SYSAPI_enSetSparkCuts: + { + TEPM_vSetSparkCutsMask(*(uint32*)OS_stSVCDataStruct.pvArg1, *(uint32*)OS_stSVCDataStruct.pvArg2, *(uint32*)OS_stSVCDataStruct.pvArg3); + break; + } + + default: + { + OS_stSVCDataStruct.enSVCResult = SYSAPI_enFail; + break; + } + } +} + + + +#endif // KERNEL diff --git a/source/System/SYSAbstract.h b/source/System/SYSAbstract.h new file mode 100644 index 0000000..81ca0c1 --- /dev/null +++ b/source/System/SYSAbstract.h @@ -0,0 +1,23 @@ +/******************************************************************************/ +/* System abstraction header file */ +/******************************************************************************/ +/* */ +/* Copyright (c) 2013 MD Automotive Controls. All rights reserved. */ +/* This file contains macros that are invoked in hardware independent files */ +/* */ +/* */ +/******************************************************************************/ +#include +#include "time.h" +#ifdef KERNEL + +#ifndef SYSABSTRACT_H +#define SYSABSTRACT_H + +#include "mk64f12.h" +#define get_fattime TIME_u32GetFATTime + + +#endif // SYSABSTRACT_H + +#endif // KERNEL diff --git a/source/System/TYPES.h b/source/System/TYPES.h new file mode 100644 index 0000000..99de0c8 --- /dev/null +++ b/source/System/TYPES.h @@ -0,0 +1,57 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. */ +/* All rights reserved. */ +/******************************************************************************/ +/* */ +/* PACKAGE TITLE: Types Header File */ +/* DESCRIPTION: This code various required types declarations */ +/* */ +/* FILE NAME: types.h */ +/* REVISION HISTORY: 07-03-2016 | 1.0 | Initial revision */ +/* */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#ifndef TYPES_H +#define TYPES_H + +#include + +/* GLOBAL TYPE DEFINITIONS ****************************************************/ +typedef unsigned int uint32; +typedef unsigned short uint16; +typedef unsigned char uint8; + +typedef unsigned int* puint32; +typedef unsigned short* puint16; +typedef unsigned char* puint8; + +typedef int* psint32; +typedef short* psint16; +typedef char* psint8; + +typedef volatile unsigned int* vpuint32; +typedef volatile unsigned short* vpuint16; +typedef volatile unsigned char* vpuint8; + +#ifndef bool +typedef unsigned char bool; +#endif + +typedef signed char sint8; +typedef short sint16; +typedef int sint32; + + +typedef enum { + TYPE_enUInt8, + TYPE_enUInt16, + TYPE_enUInt32, + TYPE_enInt8, + TYPE_enInt16, + TYPE_enInt32 +} TYPE_tenDataType; + +#endif // TYPES_H + diff --git a/source/UserServices/CEM.c b/source/UserServices/CEM.c new file mode 100644 index 0000000..238682e --- /dev/null +++ b/source/UserServices/CEM.c @@ -0,0 +1,1025 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _CEM_C + +#include "CEM.h" +#include "declarations.h" +#include "EST.h"//matthew breaking layers +#include "SETUP.h"//matthew breaking layers +#include "os.h" +#include "tepmha.h" +#include "KERNELIO.h" + +uint16 CEM_au16RisingCrankEdge[80]; +uint16 CEM_au16FallingCrankEdge[80]; +uint16 CEM_au16AllEdge[160]; +bool CEM_aboSyncEdge[160]; +uint16 CEM_au16SyncPoints[36]; +uint8 CEM_u8RisingEdgesCount; +uint8 CEM_u8FallingEdgesCount; +uint32 CEM_u8CrankEdgeCounter; +bool CEM_boCrankEdgeFirstRising; +uint32 CEM_u32CrankEdgeTimeoutCount; +uint8 CEM_au8AutocorrPeak[4]; +uint8 CEM_au8ConfirmedAutocorrPeak[4]; +IOAPI_tenEdgePolarity CEM_enEdgePolarity; +TEPMAPI_tstTimerMeasurements CEM_stTimerMeasurements[TEPMHA_nEventChannels]; +bool CEM_boEdgesReady; +uint32 CEM_au32TimerOffsets[9]; +CEM_tenTriggerType CEM_enTriggerType; +uint8 CEM_u8SimpleMissingSync; +TEPMAPI_tstSimpleCamSync stSimpleCamSync; +extern IOAPI_tenEHIOResource TEPM_astTEPMVVTInputs[]; +TEPMAPI_ttEventTime CEM_atLastVVTTimer[4]; +TEPMAPI_ttEventTime CEM_atLastVVTHighTime[4]; +TEPMAPI_ttEventTime CEM_atLastVVTLowTime[4]; + +static void CEM_vSequenceReset(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime, uint32 u32OriginGlobalCycleFraction, bool boLatePhase); +static TEPMAPI_ttEventTime CEM_tCalculateGlobalTime(TEPMAPI_ttEventTime tEventTime, uint16 u16LastGapFraction, bool boGlobalTimeEnable); +static void CEM_vProcessAllEdges(void); +static void CEM_vPhaseError(int); +static bool CEM_boGetLatePhaseSimpleCamSync(void); + +void CEM_vStart(uint32* const u32Stat) +{ + CEM_u32GlobalCycleFraction = 0; + CEM_u32GlobalCycleTime = 0x0000ffff; + CEM_u32GlobalCycleOriginCount = 0; + CEM_u32CrankEdgeTimeoutCount = 0; + CEM_tEventTimeLast = ~0; + CEM_u8CrankEdgeCounter = 0xff; + CEM_boEdgesReady = FALSE; + CTS_boCTSReady = FALSE; + CEM_u8SimpleMissingSync = 0; + CEM_u32CrankErrorCounts = 0; + //CEM_u8PhaseRepeats = 1;//matthew must be dynamic!!! + + memset((void*)&CEM_au16RisingCrankEdge, 0, sizeof(CEM_au16RisingCrankEdge)); + memset((void*)&CEM_au16FallingCrankEdge, 0, sizeof(CEM_au16FallingCrankEdge)); + CEM_u8RisingEdgesCount = 0; + CEM_u8FallingEdgesCount = 0; + CEM_u32SyncPoints = 0; + CEM_boCrankEdgeFirstRising = FALSE; + CEM_au8AutocorrPeak[0] = 128; + CEM_au8AutocorrPeak[1] = 128; + CEM_au8AutocorrPeak[2] = 128; + CEM_au8AutocorrPeak[3] = 128; + CEM_au8ConfirmedAutocorrPeak[0] = 128; + CEM_au8ConfirmedAutocorrPeak[1] = 128; + CEM_au8ConfirmedAutocorrPeak[2] = 128; + CEM_au8ConfirmedAutocorrPeak[3] = 128; +} + +void CEM_vRun(uint32* const u32Stat) +{ + if (10 < CEM_u32CrankEdgeTimeoutCount) + { + CEM_tEventTimeLast = ~0; + CEM_u32GlobalCycleOriginCount = 0; + } + else + { + CEM_u32CrankEdgeTimeoutCount++; + } +} + +void CEM_vTerminate(uint32* const u32Stat) +{ + +} + +bool CEM_boPopulateSyncPointsArray(puint16 const pu16EdgeFractionArray) +{ + bool boRetVal = true; + + CEM_u32SyncPoints = 0; + + while (((0 != *(pu16EdgeFractionArray + CEM_u32SyncPoints)) && (36 > CEM_u32SyncPoints)) | (0 == CEM_u32SyncPoints)) + { + CEM_au16SyncPoints[CEM_u32SyncPoints] = *(pu16EdgeFractionArray + CEM_u32SyncPoints); + CEM_u32SyncPoints++; + } + + CEM_u32SequenceFraction = 0x2000ul / CEM_u32SyncPoints; + + return boRetVal; +} + + +bool CEM_boPopulateCrankEdgeArrays(puint16 const pu16EdgeFractionArray, const bool boFirstRising, IOAPI_tenEdgePolarity enEdgePolarity, uint32_t u32TriggerType) +{ + uint32 u32EdgeCount = 0; + bool boStat = FALSE; + uint8 u8EdgeCount = 0; + CEM_u8RisingEdgesCount = 0; + CEM_u8FallingEdgesCount = 0; + + CEM_boCrankEdgeFirstRising = boFirstRising; + CEM_enEdgePolarity = enEdgePolarity; + + while (((0 != *(pu16EdgeFractionArray + u32EdgeCount)) && (80 > u8EdgeCount)) | (0 == u32EdgeCount)) + { + if (IOAPI_enEdgeBoth == enEdgePolarity) + { + if (TRUE == boFirstRising) + { + CEM_au16RisingCrankEdge[u32EdgeCount / 2] = *(pu16EdgeFractionArray + u32EdgeCount); + } + else + { + CEM_au16FallingCrankEdge[u32EdgeCount / 2] = *(pu16EdgeFractionArray + u32EdgeCount); + } + CEM_au16AllEdge[u32EdgeCount] = *(pu16EdgeFractionArray + u32EdgeCount); + u32EdgeCount++; + + if (TRUE == boFirstRising) + { + CEM_au16FallingCrankEdge[u32EdgeCount / 2] = *(pu16EdgeFractionArray + u32EdgeCount); + } + else + { + CEM_au16RisingCrankEdge[u32EdgeCount / 2] = *(pu16EdgeFractionArray + u32EdgeCount); + } + CEM_au16AllEdge[u32EdgeCount] = *(pu16EdgeFractionArray + u32EdgeCount); + u32EdgeCount++; + CEM_u8RisingEdgesCount++; + CEM_u8FallingEdgesCount++; + } + if (IOAPI_enEdgeFalling == enEdgePolarity) + { + CEM_au16FallingCrankEdge[u32EdgeCount] = *(pu16EdgeFractionArray + u32EdgeCount); + CEM_au16AllEdge[u32EdgeCount] = *(pu16EdgeFractionArray + u32EdgeCount); + u32EdgeCount++; + CEM_u8FallingEdgesCount++; + } + if (IOAPI_enEdgeRising == enEdgePolarity) + { + CEM_au16RisingCrankEdge[u32EdgeCount] = *(pu16EdgeFractionArray + u32EdgeCount); + CEM_au16AllEdge[u32EdgeCount] = *(pu16EdgeFractionArray + u32EdgeCount); + u32EdgeCount++; + CEM_u8RisingEdgesCount++; + } + } + + CEM_enTriggerType = (0 != u32TriggerType) ? CEM_enTypeSuzukiM15A + u32TriggerType - 1 : 0; + + CEM_vProcessAllEdges(); + boStat = TRUE; + CEM_boEdgesReady = TRUE; + + return boStat; +} + +static void CEM_vProcessAllEdges(void) +{ + uint32 u32OldData; + uint32 u32DeltaCount = 0; + sint32 s32Temp; + + for (uint32 u32ArrayIDX = 0; u32ArrayIDX < (CEM_xEdgesCount - 1); u32ArrayIDX++) + { + u32OldData = CEM_au16AllEdge[u32ArrayIDX]; + CEM_au16AllEdge[u32ArrayIDX] = CEM_au16AllEdge[u32ArrayIDX + 1] - u32OldData; + } + + CEM_au16AllEdge[CEM_xEdgesCount - 1] = ~CEM_au16AllEdge[CEM_xEdgesCount - 1] + 1; + + CEM_aboSyncEdge[0] = TRUE; + + for (uint32 u32ArrayIDX = 1; u32ArrayIDX < CEM_xEdgesCount; u32ArrayIDX++) + { + s32Temp = CEM_au16AllEdge[u32ArrayIDX] - CEM_au16AllEdge[u32ArrayIDX - 1]; + + if (1 < s32Temp) + { + u32DeltaCount++; + CEM_u8SimpleMissingSync = (u32ArrayIDX + 1) % CEM_xEdgesCount; + } + + CEM_aboSyncEdge[u32ArrayIDX] = TRUE; + } + + if (CEM_enTriggerType < CEM_enTypeSuzukiM15A) + { + CEM_enTriggerType = (1 == u32DeltaCount) && (8 < CEM_xEdgesCount) ? CEM_enOneGroupMissing : CEM_enAutocorrelationMode; + } + + if (CEM_enTriggerType == CEM_enOneGroupMissing) + { + CEM_aboSyncEdge[CEM_u8SimpleMissingSync] = FALSE; + CEM_aboSyncEdge[CEM_u8SimpleMissingSync - 1] = FALSE; + } +} + +void CEM_vSetSyncPhaseRepeats(uint32 u32SyncPhaseRepeats) +{ + CEM_u8PhaseRepeats = (uint8)u32SyncPhaseRepeats; +} + + +TEPMAPI_ttEventTime CEM_ttGetModulePhase(uint32 u32ChannelIDX) +{ + TEPMAPI_ttEventTime tPhaseOffset = 0; + + tPhaseOffset = CEM_au32TimerOffsets[u32ChannelIDX]; + + return tPhaseOffset; +} + +void CEM_vPrimaryEventCB(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime) +{ + uint16 u16LastGapFraction; + TEPMAPI_ttEventTime tLastGapTime; + static uint32 au32AutoCorr[CEM_nEdgesMax]; + static uint32 au32InputArray[CEM_nEdgesMax]; + static bool aboConfirmedFlags[4] = {0, 0, 0, 0}; + static uint8 au8ErrorCount[4]; + uint8 u8PhasePrev; + uint32 u32Temp; + static uint32 u32EdgeCount = 0; + bool boPhaseLocked = FALSE; + static bool boLatePhase; + static uint8 u8SameGapCount; + + if (FALSE == CEM_boEdgesReady) return; + + u8PhasePrev = CEM_u8CrankEdgeCounter; + + /* Sanity check the edges count */ + if (CEM_xEdgesCount > CEM_nEdgesMax) return; + + u32EdgeCount++; + +#ifdef CEM_CHECK_POL + /* Sanity check edge polarity */ + if (IOAPI_enEdgeFalling == CEM_enEdgePolarity) + { + enTriState = TEPM_enGetTimerDigitalState(enEHIOResource); + + /* Invert the polarity because the circuit inverts */ + if (IOAPI_enLow == enTriState) + { + u32EdgePolAbortCount++; + return; + } + } + else if (IOAPI_enEdgeRising == CEM_enEdgePolarity) + { + enTriState = TEPM_enGetTimerDigitalState(enEHIOResource); + + /* Invert the polarity because the circuit inverts */ + if (IOAPI_enHigh == enTriState) + { + u32EdgePolAbortCount++; + return; + } + } +#endif //CEM_CHECK_POL + +#ifdef BUILD_SAM3X8E + CEM_au32TimerOffsets[8] = ((tstTimerModule*)TC2)->TC_CHANNEL[2].TC_CV - ((tstTimerModule*)TC0)->TC_CHANNEL[0].TC_CV; + CEM_au32TimerOffsets[7] = ((tstTimerModule*)TC2)->TC_CHANNEL[1].TC_CV - ((tstTimerModule*)TC0)->TC_CHANNEL[0].TC_CV; + CEM_au32TimerOffsets[6] = ((tstTimerModule*)TC2)->TC_CHANNEL[0].TC_CV - ((tstTimerModule*)TC0)->TC_CHANNEL[0].TC_CV; + CEM_au32TimerOffsets[5] = ((tstTimerModule*)TC1)->TC_CHANNEL[2].TC_CV - ((tstTimerModule*)TC0)->TC_CHANNEL[0].TC_CV; + CEM_au32TimerOffsets[4] = ((tstTimerModule*)TC1)->TC_CHANNEL[1].TC_CV - ((tstTimerModule*)TC0)->TC_CHANNEL[0].TC_CV; + CEM_au32TimerOffsets[3] = ((tstTimerModule*)TC1)->TC_CHANNEL[0].TC_CV - ((tstTimerModule*)TC0)->TC_CHANNEL[0].TC_CV; + CEM_au32TimerOffsets[2] = ((tstTimerModule*)TC0)->TC_CHANNEL[2].TC_CV - ((tstTimerModule*)TC0)->TC_CHANNEL[0].TC_CV; + CEM_au32TimerOffsets[1] = ((tstTimerModule*)TC0)->TC_CHANNEL[1].TC_CV - ((tstTimerModule*)TC0)->TC_CHANNEL[0].TC_CV; + CEM_au32TimerOffsets[0] = 0; +#endif //BUILD_SAM3X8E + + /* Increment the confirmed channels */ + uint32 u32PhaseMin = 0; + uint32 u32PhaseMax = (CEM_xEdgesCount / CEM_u8PhaseRepeats) - 1; + + + if (CEM_enAutocorrelationMode == CEM_enTriggerType) + { + for (uint8 u8ArrayIDX = 0; u8ArrayIDX < 4; u8ArrayIDX++) + { + if (TRUE == aboConfirmedFlags[u8ArrayIDX]) + { + CEM_au8ConfirmedAutocorrPeak[u8ArrayIDX]++; + + if (u32PhaseMax < CEM_au8ConfirmedAutocorrPeak[u8ArrayIDX]) + { + CEM_au8ConfirmedAutocorrPeak[u8ArrayIDX] -= (CEM_xEdgesCount / CEM_u8PhaseRepeats); + } + } + else + { + CEM_au8ConfirmedAutocorrPeak[u8ArrayIDX] = 128; + } + + u32PhaseMin += (CEM_xEdgesCount / CEM_u8PhaseRepeats); + u32PhaseMax += (CEM_xEdgesCount / CEM_u8PhaseRepeats); + u32PhaseMin = u32PhaseMin % CEM_xEdgesCount; + u32PhaseMax = u32PhaseMax % CEM_xEdgesCount; + } + } + + u16LastGapFraction = CEM_au16AllEdge[(CEM_u8CrankEdgeCounter - 1) % CEM_xEdgesCount] / CEM_u8PhaseRepeats; + tLastGapTime = CEM_tCalculateGlobalTime(tEventTime, u16LastGapFraction, CEM_aboSyncEdge[CEM_u8CrankEdgeCounter]); + + if (CEM_enAutocorrelationMode == CEM_enTriggerType) + { + /* Increment the edge counter if possible */ + for (uint8 u8ArrayIDX = 0; u8ArrayIDX < 4; u8ArrayIDX++) + { + if (TRUE == aboConfirmedFlags[u8ArrayIDX]) + { + CEM_u8CrankEdgeCounter = (CEM_u8CrankEdgeCounter + 1) % CEM_xEdgesCount; + break; + } + } + } + + CEM_tEventTimeLast = tEventTime; + CEM_u32CrankEdgeTimeoutCount = 0; + + /* Shift the input array */ + puint32 pu32 = au32InputArray; + pu32 += (CEM_nEdgesMax - CEM_xEdgesCount); + memcpy(pu32, pu32 + 1, sizeof(uint32) * CEM_xEdgesCount); + + /* Buffer the new gap time */ + au32InputArray[CEM_nEdgesMax - 1] = tLastGapTime; + + /* If enough edges have arrived to proceed */ + if ((5 / CEM_u8PhaseRepeats) <= u32EdgeCount)//matthew + { + switch (CEM_enTriggerType) + { + case CEM_enAutocorrelationMode: + { + CEM_au8AutocorrPeak[0] = 0x80; + CEM_au8AutocorrPeak[1] = 0x80; + CEM_au8AutocorrPeak[2] = 0x80; + CEM_au8AutocorrPeak[3] = 0x80; + + /* Calculate the autocorrelation array */ + memset((void*)&au32AutoCorr, 0, CEM_nEdgesMax * sizeof(uint32)); + uint32 u32ControlArrayIDX = 0; + + for (uint32 u32AutocorrPhase = 0; u32AutocorrPhase < CEM_xEdgesCount; u32AutocorrPhase++) + { + uint32 u32InputArrayIDX = CEM_nEdgesMax - CEM_xEdgesCount; + + for (uint32 u32ShiftCount = 0; u32ShiftCount < CEM_xEdgesCount; u32ShiftCount++) + { + u32Temp = (au32InputArray[u32InputArrayIDX] * (uint32)CEM_au16AllEdge[u32ControlArrayIDX]); + u32Temp /= 0x100u; + au32AutoCorr[u32AutocorrPhase] += u32Temp; + u32ControlArrayIDX = (u32ControlArrayIDX + 1) % CEM_xEdgesCount; + u32InputArrayIDX++; + } + u32ControlArrayIDX++; + } + + /* Find the autocorrelation peak */ + uint32 u32AutoPeak = 0; + + for (uint32 u32ArrayIDX = 0; u32ArrayIDX < CEM_xEdgesCount; u32ArrayIDX++) + { + if (u32AutoPeak < au32AutoCorr[u32ArrayIDX]) + { + u32AutoPeak = au32AutoCorr[u32ArrayIDX]; + } + } + + /* Set the auto-peaks indices array */ + for (uint8 u8ArrayIDX = 0; u8ArrayIDX < CEM_xEdgesCount; u8ArrayIDX++) + { + if (u32AutoPeak == au32AutoCorr[u8ArrayIDX]) + { + if (128u == CEM_au8AutocorrPeak[0]) + { + CEM_au8AutocorrPeak[0] = u8ArrayIDX; + } + else if (128u == CEM_au8AutocorrPeak[1]) + { + CEM_au8AutocorrPeak[1] = u8ArrayIDX; + } + else if (128u == CEM_au8AutocorrPeak[2]) + { + CEM_au8AutocorrPeak[2] = u8ArrayIDX; + } + else if (128u == CEM_au8AutocorrPeak[3]) + { + CEM_au8AutocorrPeak[3] = u8ArrayIDX; + } + } + } + + u32PhaseMin = 0; + u32PhaseMax = (CEM_xEdgesCount / CEM_u8PhaseRepeats) - 1; + + /* Buffer the confirmed array if is not initialized */ + for (uint8 u8ArrayIDX = 0; u8ArrayIDX < 4; u8ArrayIDX++) + { + if (128u > CEM_au8AutocorrPeak[u8ArrayIDX]) + { + if (127 < CEM_au8ConfirmedAutocorrPeak[u8ArrayIDX]) + { + if ((u32PhaseMin <= CEM_au8AutocorrPeak[u8ArrayIDX]) && + (u32PhaseMax >= CEM_au8AutocorrPeak[u8ArrayIDX])) + { + CEM_au8ConfirmedAutocorrPeak[u8ArrayIDX] = CEM_au8AutocorrPeak[u8ArrayIDX]; + + if (0xff == CEM_u8CrankEdgeCounter) + { + CEM_u8CrankEdgeCounter = CEM_au8AutocorrPeak[u8ArrayIDX]; + } + } + } + } + + u32PhaseMin += (CEM_xEdgesCount / CEM_u8PhaseRepeats); + u32PhaseMax += (CEM_xEdgesCount / CEM_u8PhaseRepeats); + u32PhaseMin = u32PhaseMin % CEM_xEdgesCount; + u32PhaseMax = u32PhaseMax % CEM_xEdgesCount; + } + + /* Clear the confirmed flags */ + for (uint8 u8ArrayIDX = 0; u8ArrayIDX < 4; u8ArrayIDX++) + { + aboConfirmedFlags[u8ArrayIDX] = FALSE; + } + + /* Check if the confirmed array is still confirmed */ + for (uint8 u8ArrayIDX = 0; u8ArrayIDX < 4; u8ArrayIDX++) + { + for (uint8 u8ConfirmedArrayIDX = 0; u8ConfirmedArrayIDX < 4; u8ConfirmedArrayIDX++) + { + if (CEM_au8ConfirmedAutocorrPeak[u8ConfirmedArrayIDX] == CEM_au8AutocorrPeak[u8ArrayIDX]) + { + aboConfirmedFlags[u8ConfirmedArrayIDX] = TRUE; + au8ErrorCount[u8ConfirmedArrayIDX] = 0; + } + } + } + + /* Increment error counter of unconfirmed */ + for (uint8 u8ArrayIDX = 0; u8ArrayIDX < 4; u8ArrayIDX++) + { + if (FALSE == aboConfirmedFlags[u8ArrayIDX]) + { + au8ErrorCount[u8ArrayIDX] = (au8ErrorCount[u8ArrayIDX] + 1) % 0x80; + } + } + + /* Check for phase lock on any index */ + for (uint8 u8ArrayIDX = 0; u8ArrayIDX < 4; u8ArrayIDX++) + { + if (CEM_u8CrankEdgeCounter == CEM_au8ConfirmedAutocorrPeak[u8ArrayIDX]) {boPhaseLocked = TRUE;} + } + + /* Buffer and edge count if we are phase locked */ + if (FALSE == boPhaseLocked) + { + for (uint8 u8ArrayIDX = 0; u8ArrayIDX < 4; u8ArrayIDX++) + { + if (TRUE == aboConfirmedFlags[u8ArrayIDX]) + { + CEM_u8CrankEdgeCounter = CEM_au8ConfirmedAutocorrPeak[u8ArrayIDX]; + } + } + } + + CEM_u32GlobalCycleFraction += CEM_au16AllEdge[(CEM_u8CrankEdgeCounter - 1) % CEM_xEdgesCount]; + + /* Are we at a calculation edge? */ + if (0 == CEM_u8CrankEdgeCounter) + { + CEM_vSequenceReset(enEHIOResource, tEventTime, 0, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + } + + if (1 == CEM_u8PhaseRepeats) + { + if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[1]) + { + CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + } + if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[2]) + { + CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + } + if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[3]) + { + CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + } + } + break; + } + case CEM_enOneGroupMissing: + case CEM_enTypeWVEA888: + { + CEM_u32GlobalCycleFraction += CEM_au16AllEdge[(CEM_u8CrankEdgeCounter - 1) % CEM_xEdgesCount]; + + if (au32InputArray[CEM_nEdgesMax - 1] > au32InputArray[CEM_nEdgesMax - 2] * 2) + { + if ((CEM_u8CrankEdgeCounter != CEM_u8SimpleMissingSync) && + (100 < u32EdgeCount)) + { + CEM_vPhaseError(CEM_u8CrankEdgeCounter); + } + + CEM_u8CrankEdgeCounter = CEM_u8SimpleMissingSync; + } + + /* Sync over 720 degrees */ + if (CEM_enTypeWVEA888 == CEM_enTriggerType) + { + if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[1]) + { + if (0x10000 <= CEM_u32GlobalCycleFraction) + { + if ((CEM_atLastVVTHighTime[0] < (CEM_u32GlobalCycleTime / 8)) + && (CEM_atLastVVTHighTime[0] > (CEM_u32GlobalCycleTime / 32))) + { + boLatePhase = false; + } + else if ((CEM_atLastVVTLowTime[0] < (CEM_u32GlobalCycleTime / 8)) + && (CEM_atLastVVTLowTime[0] > (CEM_u32GlobalCycleTime / 32))) + { + boLatePhase = true; + } + else + { + boLatePhase = !boLatePhase; + } + } + else + { + if (CEM_atLastVVTHighTime[0] < (CEM_u32GlobalCycleTime / 8)) + { + boLatePhase = false; + } + else if (CEM_atLastVVTLowTime[0] < (CEM_u32GlobalCycleTime / 8)) + { + boLatePhase = true; + } + else + { + boLatePhase = !boLatePhase; + } + } + } + } + else if (CEM_u8CrankEdgeCounter == stSimpleCamSync.u32CamSyncSampleToothCount) + { + boLatePhase = CEM_boGetLatePhaseSimpleCamSync(); + } + + if (0 == CEM_u8CrankEdgeCounter) + { + CEM_vSequenceReset(enEHIOResource, tEventTime, 0, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + } + + if (1 == CEM_u8PhaseRepeats) + { + if (CEM_u32GlobalCycleFraction == CEM_au16SyncPoints[1]) + { + CEM_vSequenceReset(enEHIOResource, tEventTime, 0x4000, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + } + if (CEM_u32GlobalCycleFraction == CEM_au16SyncPoints[2]) + { + CEM_vSequenceReset(enEHIOResource, tEventTime, 0x8000, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + } + if (CEM_u32GlobalCycleFraction == CEM_au16SyncPoints[3]) + { + CEM_vSequenceReset(enEHIOResource, tEventTime, 0xc000, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + } + } + else if (2 == CEM_u8PhaseRepeats) + { + if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[1]) + { + CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + } + if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[2]) + { + CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + } + if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[3]) + { + CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + } + } + + if ((25 == CEM_u8CrankEdgeCounter) || (53 == CEM_u8CrankEdgeCounter)) + { + TEPM_vStartEventProgramKernelQueues(FALSE, 0x80); + } + + CEM_u8CrankEdgeCounter = (CEM_u8CrankEdgeCounter + 1) % CEM_xEdgesCount; + + break; + } + case CEM_enTypeSuzukiM15A: + { + CEM_u32GlobalCycleFraction += CEM_au16AllEdge[(CEM_u8CrankEdgeCounter - 1) % CEM_xEdgesCount]; + + if (au32InputArray[CEM_nEdgesMax - 1] > (au32InputArray[CEM_nEdgesMax - 2] * 2)) + { + /* Crank sensor gap */ + if (((CEM_u8CrankEdgeCounter != 21) && (CEM_u8CrankEdgeCounter != 7)) && + (100 < u32EdgeCount)) + { + CEM_vPhaseError(CEM_u8CrankEdgeCounter); + } + + CEM_u8CrankEdgeCounter++; + + u8SameGapCount = 0; + + CEM_u8CrankEdgeCounter = 30 <= CEM_u8CrankEdgeCounter ? 1 : CEM_u8CrankEdgeCounter; + } + else if (au32InputArray[CEM_nEdgesMax - 1] < (au32InputArray[CEM_nEdgesMax - 2] / 2)) + /* Crank sensor end gap */ + { + if (((CEM_u8CrankEdgeCounter != 22) && (CEM_u8CrankEdgeCounter != 9)) && + (100 < u32EdgeCount)) + { + CEM_vPhaseError(CEM_u8CrankEdgeCounter); + } + + if (0 < u8SameGapCount) + { + CEM_u8CrankEdgeCounter = 10; + } + else + { + CEM_u8CrankEdgeCounter = 23; + CEM_u32GlobalCycleFraction = CEM_au16AllEdge[0] + CEM_au16AllEdge[1]; + } + + u8SameGapCount = 0; + } + else + { + /* Crank sensor same gap */ + u8SameGapCount++; + CEM_u8CrankEdgeCounter++; + } + + + if (31 == CEM_u8CrankEdgeCounter) + { + CEM_u32GlobalCycleFraction &= 0x10000; + CEM_vSequenceReset(enEHIOResource, tEventTime, 0, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + CEM_u8CrankEdgeCounter = 1; + } + + if (1 == CEM_u8PhaseRepeats) + { + if (CEM_u32GlobalCycleFraction == CEM_au16SyncPoints[1]) + { + CEM_vSequenceReset(enEHIOResource, tEventTime, 0x4000, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + } + if (CEM_u32GlobalCycleFraction == CEM_au16SyncPoints[2]) + { + CEM_vSequenceReset(enEHIOResource, tEventTime, 0x8000, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + } + if (CEM_u32GlobalCycleFraction == CEM_au16SyncPoints[3]) + { + CEM_vSequenceReset(enEHIOResource, tEventTime, 0xc000, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + } + } + else if (2 == CEM_u8PhaseRepeats) + { + if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[1]) + { + CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + } + if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[2]) + { + CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + } + if ((0xffff & CEM_u32GlobalCycleFraction) == CEM_au16SyncPoints[3]) + { + CEM_vSequenceReset(enEHIOResource, tEventTime, CEM_u32GlobalCycleFraction, boLatePhase); + TEPM_vSynchroniseEventProgramKernelQueues(); + } + } + + break; + } + default: + { + break; + } + } + + + if ((1u != ((CEM_u8CrankEdgeCounter - u8PhasePrev) % CEM_xEdgesCount)) && (TRUE == boPhaseLocked)) + { + CEM_vPhaseError(0); + } + } +} + +static bool CEM_boGetLatePhaseSimpleCamSync(void) +{ + bool boLatePhase; + IOAPI_tenTriState enTriState; + + enTriState = IO_enGetDIOResourceState(stSimpleCamSync.enEHIOResource); + + if (true == stSimpleCamSync.boCamSyncHighLate) + { + boLatePhase = (IOAPI_enHigh == enTriState); + } + else + { + boLatePhase = (IOAPI_enLow == enTriState); + } + + return boLatePhase; +} + +static void CEM_vPhaseError(int code_in) +{ + /* TODO + volatile static int code; + code = code_in; + */ + CEM_u32CrankErrorCounts++; +} + + +static TEPMAPI_ttEventTime CEM_tCalculateGlobalTime(TEPMAPI_ttEventTime tEventTime, uint16 u16LastGapFraction, bool boGlobalTimeEnable) +{ + TEPMAPI_ttEventTime tTemp; + TEPMAPI_ttEventTime tGlobalTimeNew = 0; + uint32 u32Temp; + + tTemp = (tEventTime - CEM_tEventTimeLast) & TEPMHA_nCounterMask; + + if (0xffff >= tTemp) + { + tGlobalTimeNew = (0x10000u * tTemp) / (uint32)u16LastGapFraction; + //tGlobalTimeNew = 220000; + } + else if (0xfffff >= tTemp) + { + u16LastGapFraction = u16LastGapFraction >> 4; + tGlobalTimeNew = (0x1000u * tTemp) / (uint32)u16LastGapFraction; + } + else if (0xffffff >= tTemp) + { + u16LastGapFraction = u16LastGapFraction >> 8; + tGlobalTimeNew = (0x100u * tTemp) / (uint32)u16LastGapFraction; + } + else if (0xfffffff >= tTemp) + { + u16LastGapFraction = u16LastGapFraction >> 12; + tGlobalTimeNew = (0x10u * tTemp) / (uint32)u16LastGapFraction; + } + else + { + CEM_u32GlobalCycleTime = ~0u; + } + + if (TRUE == boGlobalTimeEnable) + { + if (TRUE == TPS_boThrottleClosed) + { + u32Temp = USERCAL_stRAMCAL.u16ESTFilterClosed * CEM_u32GlobalCycleTime; + u32Temp += ((0x100 - USERCAL_stRAMCAL.u16ESTFilterClosed) * tGlobalTimeNew); + u32Temp /= 0x100; + } + else + { + u32Temp = USERCAL_stRAMCAL.u16ESTFilterOpen * tGlobalTimeNew; + u32Temp += ((0x100 - (uint8)USERCAL_stRAMCAL.u16ESTFilterOpen) * CEM_u32GlobalCycleTime); + u32Temp /= 0x100; + } + + CEM_u32GlobalCycleTime = u32Temp; + + if (tGlobalTimeNew < CEM_u32GlobalCycleTime) + { + CEM_u32GlobalCycleTime--; + } + else if (tGlobalTimeNew > CEM_u32GlobalCycleTime) + { + CEM_u32GlobalCycleTime++; + } + } + + return tTemp; +} + +static void CEM_vSequenceReset(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime, uint32 u32OriginGlobalCycleFraction, bool boLatePhase) +{ + uint32 u32Temp; + static uint32 u32SequenceIDX; + static IOAPI_tenTriState enTriState; + IOAPI_tenEHIOResource enLinkedResource; + + CEM_tSyncTimeLast = tEventTime; + + u32SequenceIDX++; + u32Temp = CEM_u32GlobalCycleTime / (4 * CEM_u8PhaseRepeats); + u32Temp = 0x10000 > u32Temp ? u32Temp : 0xffff; + + if (1 == CEM_u8PhaseRepeats) + { + if (0 == u32OriginGlobalCycleFraction) + { + u32SequenceIDX = 0; + + CEM_u32GlobalCycleFraction = u32OriginGlobalCycleFraction; + CEM_u32GlobalCycleOriginCount++; + } + } + else + { + if (0 == u32OriginGlobalCycleFraction) + { + if (((0x10000 <= CEM_u32GlobalCycleFraction) && (false == boLatePhase)) || + ((0x10000 > CEM_u32GlobalCycleFraction) && (true == boLatePhase))) + { + CEM_u32CamErrorCounts++; + CEM_u32CamRunningErrorCounts = 5 > CEM_u32CamRunningErrorCounts ? CEM_u32CamRunningErrorCounts + 1 : 5; + } + + + if (5 == CEM_u32CamRunningErrorCounts) + /* Many cam errors */ + { + //if (0 == (CEM_u32GlobalCycleOriginCount % 8)) + if (true) + /* Try swap phase */ + { + if (0x10000 > CEM_u32GlobalCycleFraction) + { + u32SequenceIDX = 4; + CEM_u32GlobalCycleFraction = 0x10000 + u32OriginGlobalCycleFraction; + } + else + { + u32SequenceIDX = 0; + CEM_u32GlobalCycleFraction = u32OriginGlobalCycleFraction; + } + + CEM_u32CamRunningErrorCounts = 0; + } + else + /* Keep phase and reset */ + { + if (0x10000 <= CEM_u32GlobalCycleFraction) + { + u32SequenceIDX = 0; + CEM_u32GlobalCycleFraction = u32OriginGlobalCycleFraction; + } + else + { + u32SequenceIDX = 4; + CEM_u32GlobalCycleFraction = 0x10000 + u32OriginGlobalCycleFraction; + } + } + } + else if ((0x10000 <= CEM_u32GlobalCycleFraction) && (true == boLatePhase)) + { + u32SequenceIDX = 0; + CEM_u32GlobalCycleFraction = u32OriginGlobalCycleFraction; + } + else + { + CEM_u32GlobalCycleFraction = 0x10000 + u32OriginGlobalCycleFraction; + } + + CEM_u32GlobalCycleOriginCount++; + + if (0 == (CEM_u32GlobalCycleOriginCount % 8)) + { + CEM_u32CamRunningErrorCounts = 0 < CEM_u32CamRunningErrorCounts ? CEM_u32CamRunningErrorCounts - 1 : 0; + } + + /* grab the primary linked resource for the phase tell-tale to slave uP */ + enLinkedResource = TEPM_enGetPrimaryLinkedResource(); + + /* set the phase tell-tale */ + enTriState = true == boLatePhase ? IOAPI_enHigh : IOAPI_enLow; + IO_vAssertDIOResource(enLinkedResource, enTriState); + } + } + + + if (1 < CEM_u32GlobalCycleOriginCount)//matthew + { + TEPM_vStartEventProgramKernelQueues(FALSE, u32SequenceIDX); + } + + if ((0 == (0xffff & CEM_u32GlobalCycleFraction)) || (0x8000 == (0xffff & CEM_u32GlobalCycleFraction))) + { + TEPM_vInitiateUserCallBack(enEHIOResource, (uint16)u32Temp); + } +} + +void CEM_vPhaseEventCB(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime) +{ + IOAPI_tenTriState enTriState; + + + if (enEHIOResource == TEPM_astTEPMVVTInputs[0]) + { + enTriState = IO_enGetDIOResourceState(enEHIOResource); + + if (IOAPI_enLow == enTriState) + { + CEM_atLastVVTLowTime[0] = TEPMHA_nCounterMask & (tEventTime - CEM_atLastVVTTimer[0]); + } + else + { + CEM_atLastVVTHighTime[0] = TEPMHA_nCounterMask & (tEventTime - CEM_atLastVVTTimer[0]); + } + + CEM_atLastVVTTimer[0] = tEventTime; + } + else if (enEHIOResource == TEPM_astTEPMVVTInputs[1]) + { + + } + else if (enEHIOResource == TEPM_astTEPMVVTInputs[2]) + { + + } + else if (enEHIOResource == TEPM_astTEPMVVTInputs[3]) + { + + } +} + + +void CEM_vSetupSimpleCamSync(IOAPI_tenEHIOResource enEHIOResource, bool boCamSyncHighLate, uint32 u32CamSyncSampletoothCount) +{ + stSimpleCamSync.enEHIOResource = enEHIOResource; + stSimpleCamSync.boCamSyncHighLate = boCamSyncHighLate; + stSimpleCamSync.u32CamSyncSampleToothCount = u32CamSyncSampletoothCount; +} + +void CEM_vFreqEventCB(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime) +{ + static uint32 u32OldOSTick; + volatile static uint32 samples[100]; + static uint32 counter; + static uint32 u32TimeOld; + static uint32 u32Temp; + static uint32 u32ErrCount; + + samples[counter] = (tEventTime - u32TimeOld) & TEPMHA_nCounterMask; + + u32Temp -= 5; + u32Temp *= 2; + + if ((u32Temp < samples[counter]) && + (2 > u32ErrCount)) + { + samples[counter] /= 2; + u32ErrCount++; + } + else + { + u32ErrCount = 0; + } + + u32Temp = samples[counter]; + + if (OS_u32TickCounter > (u32OldOSTick + 1)) + { + TEPM_vInitiateUserCallBack(enEHIOResource, samples[counter]); + u32OldOSTick = OS_u32TickCounter; + } + + counter = (counter + 1) % 100; + u32TimeOld = tEventTime; +} diff --git a/source/UserServices/CEM.h b/source/UserServices/CEM.h new file mode 100644 index 0000000..c858c3b --- /dev/null +++ b/source/UserServices/CEM.h @@ -0,0 +1,82 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef CEM_H +#define CEM_H + +#include "types.h" +#include "kernelio.h" +#include "IOAPI.h" +#include "TEPM.h" +#include "TEPMAPI.h" +#include "declarations.h" + +#define CEM_xEdgesCount (CEM_u8FallingEdgesCount + CEM_u8RisingEdgesCount) +#define CEM_nEdgesMax 80u +#define CEM_nSeqGroupCount 2 +#define CEM_nSeqcount 4 + +#ifdef EXTERN + #undef EXTERN +#endif +#ifdef _CEM_C + #define EXTERN +#else + #define EXTERN extern +#endif + +typedef enum +{ + CEM_enAutocorrelationMode, + CEM_enOneGroupMissing, + CEM_enTypeSuzukiM15A, + CEM_enTypeWVEA888, + CEM_enModeCount +} CEM_tenTriggerType; + +typedef enum +{ + CEM_enStartGap, + CEM_enEndGap, + CEM_enSameGap +} CEM_enGapStatus; + +EXTERN uint32 CEM_u32GlobalCycleFraction; +EXTERN uint8 CEM_u32SyncPoints; +EXTERN uint8 CEM_u8PhaseRepeats; +EXTERN uint32 CEM_u32GlobalCycleTime; +EXTERN uint32 CEM_u32GlobalCycleOriginCount; +EXTERN TEPMAPI_ttEventTime CEM_tEventTimeLast; +EXTERN TEPMAPI_ttEventTime CEM_tSyncTimeLast; +EXTERN uint32 CEM_u32SequenceFraction; +EXTERN uint32 CEM_u32CrankErrorCounts; +//ASAM mode=readvalue name="Crank Error Counts" type=uint32 offset=0 min=0 max=65535 m=1 b=0 units="counts" format=5.3 help="Crank Error Counts" +EXTERN uint32 CEM_u32CamErrorCounts; +//ASAM mode=readvalue name="Cam Error Counts" type=uint32 offset=0 min=0 max=65535 m=1 b=0 units="counts" format=5.3 help="Cam Error Counts" +EXTERN uint32 CEM_u32CrankRunningErrorCounts; +//ASAM mode=readvalue name="Crank Running Error Counts" type=uint32 offset=0 min=0 max=65535 m=1 b=0 units="counts" format=5.3 help="Crank Running Error Counts" +EXTERN uint32 CEM_u32CamRunningErrorCounts; +//ASAM mode=readvalue name="Cam Running Error Counts" type=uint32 offset=0 min=0 max=65535 m=1 b=0 units="counts" format=5.3 help="Cam Running Error Counts" + +void CEM_vStart(uint32* const); +void CEM_vRun(uint32* const); +void CEM_vTerminate(uint32* const); +bool CEM_boPopulateCrankEdgeArrays(puint16 const pu16EdgeFractionArray, const bool boFirstRising, IOAPI_tenEdgePolarity enEdgePolarity, uint32_t u32TriggerType); +bool CEM_boPopulateSyncPointsArray(puint16 const); +void CEM_vPrimaryEventCB(IOAPI_tenEHIOResource, TEPMAPI_ttEventTime); +void CEM_vPhaseEventCB(IOAPI_tenEHIOResource, TEPMAPI_ttEventTime); +TEPMAPI_ttEventTime CEM_ttGetModulePhase(uint32 u32ChannelIDX); +void CEM_vFreqEventCB(IOAPI_tenEHIOResource, TEPMAPI_ttEventTime); +void CEM_vSetupSimpleCamSync(IOAPI_tenEHIOResource, bool, uint32); +void CEM_vSetSyncPhaseRepeats(uint32 u32SyncPhaseRepeats); + +#endif //CEM_H + diff --git a/source/UserServices/CTRL.c b/source/UserServices/CTRL.c new file mode 100644 index 0000000..3e43d40 --- /dev/null +++ b/source/UserServices/CTRL.c @@ -0,0 +1,184 @@ +/******************************************************************************/ +/* CTRL c file */ +/******************************************************************************/ +/* */ +/* Copyright (c) 2013 MD Automotive Controls. All rights reserved. */ +/* This file provides port access functions */ +/* */ +/* */ +/******************************************************************************/ +#include +#include +#include +#include "mk64f12.h" +#include "OS.h" +#include "MATH.h" +#include "CTRL.h" + +CTRLAPI_tstPIDCB CTRLAPI_astPIDCB[CTRL_nPIDCTRLCount]; +CTRLAPI_tstPIDCB* CTRLAPI_apstPIDCB[CTRL_nPIDCTRLCount + CTRL_nPIDUserCount]; +uint32 CTRLAPI_au32Counter[CTRL_nPIDCTRLCount + CTRL_nPIDUserCount]; + + +void CTRL_vStart(puint32 const pu32Stat) +{ + uint32 u32IDX; + + for (u32IDX = 0; u32IDX < (CTRL_nPIDCTRLCount + CTRL_nPIDUserCount); u32IDX++) + { + CTRLAPI_apstPIDCB[u32IDX] = NULL; + } +} + +void CTRL_vRun(puint32 const pu32Stat) +{ + CTRLAPI_tstPIDCB* pstPIDCB = NULL; + uint32 u32PIDIDX; + uint32 u32CountTerminal; + + for (u32PIDIDX = 0; u32PIDIDX < (CTRL_nPIDCTRLCount + CTRL_nPIDUserCount); u32PIDIDX++) + { + pstPIDCB = CTRLAPI_apstPIDCB[u32PIDIDX]; + + if ((NULL != pstPIDCB) && (TRUE == pstPIDCB->boRun)) + { + u32CountTerminal = MATH_u32IDXToMask(pstPIDCB->enPIDRate); + + if (1024u >= u32CountTerminal) + /* If terminal count is > 1024 then must be a call iterate controller */ + { + if (u32CountTerminal <= ++CTRLAPI_au32Counter[u32PIDIDX]) + { + CTRLAPI_au32Counter[u32PIDIDX] = 0; + CTRL_vIteratePIDCB(pstPIDCB); + } + } + } + } +} + +void CTRL_vTerminate(puint32 const pu32Stat) +{ + + +} + +CTRLAPI_ttPIDIDX CTRL_tRequestKernelPIDController(CTRLAPI_tstPIDCB* pstPIDCBReq) +{ + CTRLAPI_tstPIDCB* pstPIDCB; + uint32 u32PIDIDX; + CTRLAPI_ttPIDIDX tPIDIDX = -1; + + + /* Request a Kernel managed PID controller */ + for (u32PIDIDX = 0; CTRL_nPIDCTRLCount > u32PIDIDX; u32PIDIDX++) + { + if (NULL == CTRLAPI_apstPIDCB[u32PIDIDX]) + { + pstPIDCB = &CTRLAPI_astPIDCB[u32PIDIDX]; + CTRLAPI_apstPIDCB[u32PIDIDX] = pstPIDCB; + memcpy((void*)pstPIDCB, (void*)pstPIDCBReq, sizeof(CTRLAPI_tstPIDCB)); + pstPIDCB->i32Error = 0; + pstPIDCB->i32Integral = 0; + pstPIDCB->i32IntegralInput = 0; + tPIDIDX = u32PIDIDX; + break; + } + } + + return tPIDIDX; +} + + + +void CTRL_vIteratePIDCB(CTRLAPI_tstPIDCB* pstPIDCB) +{ + sint32 i32ErrorDerivative; + sint32 i32Result = 0; + sint32 i32ResultTerm; + sint32 i32Temp; + + pstPIDCB->i32Error = *(pstPIDCB->pi32Target) - *(pstPIDCB->pi32Feedback); + + /* Calculate the integral */ + if (FALSE == pstPIDCB->boResetIntegrator) + { + CTRL_xAddSigned32(pstPIDCB->i32Integral, pstPIDCB->i32Error); + } + else + { + pstPIDCB->i32Integral = 0; + pstPIDCB->boResetIntegrator = FALSE; + } + + /* Calculate the error derivative */ + i32ErrorDerivative = pstPIDCB->i32Error - pstPIDCB->i32OldError; + + /* Calculate the proportional output */ + CTRL_xCalcTermResult(pstPIDCB->i32Error, pstPIDCB->u8PTerm); + + /* Accumulate the output */ + CTRL_xAddSigned32(i32Result, i32ResultTerm); + + /* Calculate the derivative output */ + CTRL_xCalcTermResult(i32ErrorDerivative, pstPIDCB->u8DTerm); + + /* Accumulate the output */ + CTRL_xAddSigned32(i32Result, i32ResultTerm); + + /* Calculate the integral output */ + CTRL_xCalcTermResult(pstPIDCB->i32Integral, pstPIDCB->u8ITerm); + + /* Accumulate the output */ + CTRL_xAddSigned32(i32Result, i32ResultTerm); + + + /* Check for out of range and wind-up */ + if (pstPIDCB->i32OutputMax < i32Result) + { + i32Temp = i32Result - pstPIDCB->i32OutputMax; + i32Result = pstPIDCB->i32OutputMax; + if (pstPIDCB->boNoWindUp) + { + /* Remove the P component */ + i32Temp -= (pstPIDCB->i32Error * pstPIDCB->u8PTerm); + i32Temp = (0 < i32Temp) ? i32Temp : 0; + i32Temp = (0 < pstPIDCB->i32Integral) ? (i32Temp / pstPIDCB->u8ITerm) : 0; + pstPIDCB->i32Integral -= i32Temp; + } + } + else if (pstPIDCB->i32OutputMin > i32Result) + { + i32Temp = pstPIDCB->i32OutputMin - i32Result; + i32Result = pstPIDCB->i32OutputMin; + if (pstPIDCB->boNoWindUp) + { + /* Remove the P component */ + i32Temp += (pstPIDCB->i32Error * pstPIDCB->u8PTerm); + i32Temp = (0 < i32Temp) ? i32Temp : 0; + i32Temp = (0 > pstPIDCB->i32Integral) ? (i32Temp / pstPIDCB->u8ITerm) : 0; + pstPIDCB->i32Integral += i32Temp; + } + } + + + /* Buffer the output result */ + *(pstPIDCB->pi32Output) = i32Result; + + /* Copy old variables */ + pstPIDCB->i32OldError = pstPIDCB->i32Error; +} + + +void CTRL_vIteratePID(CTRLAPI_ttPIDIDX tPIDIDX) +{ + CTRLAPI_tstPIDCB* pstPIDCB; + + pstPIDCB = CTRLAPI_apstPIDCB[tPIDIDX]; + + CTRL_vIteratePIDCB(pstPIDCB); +} + + + + diff --git a/source/UserServices/CTRL.h b/source/UserServices/CTRL.h new file mode 100644 index 0000000..c4282e7 --- /dev/null +++ b/source/UserServices/CTRL.h @@ -0,0 +1,69 @@ +/******************************************************************************/ +/* CTRL header file */ +/******************************************************************************/ +/* */ +/* Copyright (c) 2013 MD Automotive Controls. All rights reserved. */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#ifndef CTRL_H +#define CTRL_H + +#include +#include "CTRLAPI.h" + +#define CTRL_nPIDCTRLCount 10u +#define CTRL_nPIDUserCount 10u + +#define CTRL_xAddSigned32(x, y) \ +if ((0 < y) && (0 < x)) \ +{ \ + if ((INT32_MAX - x) > y) \ + { \ + x += y; \ + } \ + else \ + { \ + x = INT32_MAX; \ + } \ +} \ +else if ((0 > y) && (0 > x)) \ +{ \ + if ((x - INT32_MIN) > (~y + 1)) \ + { \ + x += y; \ + } \ + else \ + { \ + x = INT32_MIN; \ + } \ +} \ +else \ +{ \ + x += y; \ +} \ + +#define CTRL_xCalcTermResult(x, y) \ +i32Temp = \ +(0 < y) ? (0x7FFFFFFF / (y)) : 0x7FFFFFFF; \ +if (0 <= x) \ +{ \ + i32ResultTerm = (i32Temp < x) ? \ + INT32_MAX : x * y; \ +} \ +else \ +{ \ + i32ResultTerm = (i32Temp < (~x + 1)) ? \ + INT32_MIN : x * y; \ +} \ + +void CTRL_vStart(puint32 const); +void CTRL_vRun(puint32 const); +void CTRL_vTerminate(puint32 const); +CTRLAPI_ttPIDIDX CTRL_tRequestKernelPIDController(CTRLAPI_tstPIDCB* pstPIDCBReq); +void CTRL_vIteratePIDCB(CTRLAPI_tstPIDCB*); +void CTRL_vIteratePID(CTRLAPI_ttPIDIDX); + +#endif // CTRL_H + diff --git a/source/UserServices/SPREADS.c b/source/UserServices/SPREADS.c new file mode 100644 index 0000000..ec1ceb8 --- /dev/null +++ b/source/UserServices/SPREADS.c @@ -0,0 +1,429 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#include +#include +#include +#include "OS.h" +#include "stddef.h" +#include "SYSAPI.h" + +/* Private data declarations + -------------------------*/ +SPREADAPI_tstSpreadCB SPREAD_astSpreadCB[SPREAD_nKernelSpreadCount]; +SPREADAPI_tstSpreadCB* SPREAD_apstSpreadCB[SPREAD_nKernelSpreadCount + SPREAD_nUserSpreadCount]; +uint32 SPREAD_au32Counter[SPREAD_nKernelSpreadCount + SPREAD_nUserSpreadCount]; +SPREADAPI_tstSpreadResult SPREAD_astSpreadResult[SPREAD_nKernelSpreadCount]; + +/* Private function declarations + ----------------------------*/ + +/* Public function definitions + ---------------------------*/ +void SPREADS_vStart(puint32 const pu32Arg) +{ + uint32 u32IDX; + + for (u32IDX = 0; u32IDX < (SPREAD_nKernelSpreadCount + SPREAD_nUserSpreadCount); u32IDX++) + { + SPREAD_apstSpreadCB[u32IDX] = NULL; + } +} + +void SPREADS_vRun(puint32 const pu32Arg) +{ + + +} + +void SPREADS_vTerminate(puint32 const pu32Arg) +{ + + +} + +SPREADAPI_ttSpreadIDX SPREAD_tRequestKernelSpread(SPREADAPI_tstSpreadCB* pstSpreadCBReq) +{ + SPREADAPI_tstSpreadCB* pstSpreadCB; + uint32 u32SpreadIDX; + SPREADAPI_ttSpreadIDX tSpreadIDX = -1; + + /* Request a Kernel managed spread */ + for (u32SpreadIDX = 0; SPREAD_nKernelSpreadCount > u32SpreadIDX; u32SpreadIDX++) + { + if (NULL == SPREAD_apstSpreadCB[u32SpreadIDX]) + { + pstSpreadCB = &SPREAD_astSpreadCB[u32SpreadIDX]; + SPREAD_apstSpreadCB[u32SpreadIDX] = pstSpreadCB; + memcpy((void*)pstSpreadCB, (void*)pstSpreadCBReq, sizeof(SPREADAPI_tstSpreadCB)); + tSpreadIDX = u32SpreadIDX; + break; + } + } + + return tSpreadIDX; +} + + +bool SPREAD_vCalculate(SPREADAPI_ttSpreadIDX tSpreadIDX) +{ + SPREADAPI_tstSpreadCB* pstSpreadCB; + puint32 pu32Spread; puint16 pu16Spread; puint8 pu8Spread; + psint32 ps32Spread; psint16 ps16Spread; psint8 ps8Spread; + uint16 u16SpreadIDX; uint16 u16OldSpreadIDX; uint16 u16TempSpreadIDX; + uint32 u32Source; + uint16 u16Source; + sint32 s32Source; sint16 s16Source; + sint32 s32Step; + sint32 s32Increment; + uint32 u32Shift = 0; + bool boResultFound = false; + + if ((0 <= tSpreadIDX) && + ((SPREAD_nKernelSpreadCount + SPREAD_nUserSpreadCount) > tSpreadIDX)) + { + pstSpreadCB = SPREAD_apstSpreadCB[tSpreadIDX]; + + switch (pstSpreadCB->enDataType) + { + { + case TYPE_enUInt8: + u32Source = *(puint32)(pstSpreadCB->pvSourceData); + pu8Spread = (puint8)pstSpreadCB->pvSpreadData; + break; + } + case TYPE_enUInt16: + { + u16Source = *(puint16)(pstSpreadCB->pvSourceData); + pu16Spread = (puint16)pstSpreadCB->pvSpreadData; + + if (u16Source < *pu16Spread) + { + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex = 0; + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadOffset = 0; + } + else if (u16Source >= *(pu16Spread + (pstSpreadCB->s16SpreadSize - 1))) + { + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex = pstSpreadCB->s16SpreadSize - 2; + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadOffset = 0xffff; + } + else + { + /* Start bisection search */ + u16SpreadIDX = (pstSpreadCB->s16SpreadSize) / 2; + u16OldSpreadIDX = pstSpreadCB->s16SpreadSize - 1; + + while (false == boResultFound) + { + if (u16Source == *(pu16Spread + u16SpreadIDX)) + { + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex = u16SpreadIDX; + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadOffset = 0; + boResultFound = true; + } + else if (u16Source < *(pu16Spread + u16SpreadIDX)) + { + if (u16Source >= *(pu16Spread + u16SpreadIDX - 1)) + { + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex = u16SpreadIDX - 1; + boResultFound = true; + } + else + { + /* Move left */ + if (u16OldSpreadIDX < u16SpreadIDX) + { + /* Was moving right */ + u16TempSpreadIDX = u16OldSpreadIDX; + u16OldSpreadIDX = u16SpreadIDX; + u16SpreadIDX = (u16SpreadIDX + u16TempSpreadIDX) / 2; + } + else + { + /* Was moving left */ + u16OldSpreadIDX = u16SpreadIDX; + u16SpreadIDX = u16SpreadIDX / 2; + } + } + } + else if (u16Source >= *(pu16Spread + u16SpreadIDX)) + { + if (u16Source <= *(pu16Spread + u16SpreadIDX + 1)) + { + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex = u16SpreadIDX; + boResultFound = true; + } + else + { + /* Move right */ + if (u16OldSpreadIDX > u16SpreadIDX) + { + /* Was moving left */ + u16TempSpreadIDX = u16OldSpreadIDX; + u16OldSpreadIDX = u16SpreadIDX; + u16SpreadIDX = (u16SpreadIDX + u16TempSpreadIDX) / 2; + } + else + { + /* Was moving right */ + u16OldSpreadIDX = u16SpreadIDX; + u16SpreadIDX = (u16SpreadIDX + pstSpreadCB->s16SpreadSize) / 2; + } + } + } + } + + s32Step = *(pu16Spread + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex + 1) + - *(pu16Spread + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex); + + while (0xffff < s32Step) + { + u32Shift++; + s32Step = s32Step >> 1; + } + + s32Increment = u16Source - *(pu16Spread + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex); + s32Increment = s32Increment >> u32Shift; + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadOffset = (0x10000 * (uint32)s32Increment) / (uint32)s32Step; + } + break; + } + case TYPE_enUInt32: + { + u32Source = *(puint32)(pstSpreadCB->pvSourceData); + pu32Spread = (puint32)pstSpreadCB->pvSpreadData; + + if (u32Source < *pu32Spread) + { + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex = 0; + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadOffset = 0; + } + else if (u32Source >= *(pu32Spread + (pstSpreadCB->s16SpreadSize - 1))) + { + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex = pstSpreadCB->s16SpreadSize - 2; + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadOffset = 0xffff; + } + else + { + /* Start bisection search */ + u16SpreadIDX = (pstSpreadCB->s16SpreadSize) / 2; + u16OldSpreadIDX = pstSpreadCB->s16SpreadSize - 1; + + while (false == boResultFound) + { + if ((u32Source == *(pu32Spread + u16SpreadIDX))) + { + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex = u16SpreadIDX; + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadOffset = 0; + boResultFound = true; + } + else if (u32Source < *(pu32Spread + u16SpreadIDX)) + { + if (u32Source >= *(pu32Spread + u16SpreadIDX - 1)) + { + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex = u16SpreadIDX - 1; + boResultFound = true; + } + else + { + /* Move left */ + if (u16OldSpreadIDX < u16SpreadIDX) + { + /* Was moving right */ + u16TempSpreadIDX = u16OldSpreadIDX; + u16OldSpreadIDX = u16SpreadIDX; + u16SpreadIDX = (u16SpreadIDX + u16TempSpreadIDX) / 2; + } + else + { + /* Was moving left */ + u16OldSpreadIDX = u16SpreadIDX; + u16SpreadIDX = u16SpreadIDX / 2; + } + } + } + else if (u32Source >= *(pu32Spread + u16SpreadIDX)) + { + if (u32Source < *(pu32Spread + u16SpreadIDX + 1)) //matthew was <= + { + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex = u16SpreadIDX; + boResultFound = true; + } + else + { + /* Move right */ + if (u16OldSpreadIDX > u16SpreadIDX) + { + /* Was moving left */ + u16TempSpreadIDX = u16OldSpreadIDX; + u16OldSpreadIDX = u16SpreadIDX; + u16SpreadIDX = (u16SpreadIDX + u16TempSpreadIDX) / 2; + } + else + { + /* Was moving right */ + u16OldSpreadIDX = u16SpreadIDX; + u16SpreadIDX = (u16SpreadIDX + pstSpreadCB->s16SpreadSize) / 2; + } + } + } + } + + s32Step = *(pu32Spread + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex + 1) + - *(pu32Spread + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex); + + while (0xffff < s32Step) + { + u32Shift++; + s32Step = s32Step >> 1; + } + + s32Increment = u32Source - *(pu32Spread + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex); + s32Increment = s32Increment >> u32Shift; + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadOffset = (0x10000 * (uint32)s32Increment) / (uint32)s32Step; + } + break; + } + + case TYPE_enInt8: + { + s32Source = *(psint8)(pstSpreadCB->pvSourceData); + ps8Spread = (psint8)pstSpreadCB->pvSpreadData; + break; + } + + case TYPE_enInt16: + { + s16Source = *(psint16)(pstSpreadCB->pvSourceData); + ps16Spread = (psint16)pstSpreadCB->pvSpreadData; + break; + } + + case TYPE_enInt32: + { + s32Source = *(psint32)(pstSpreadCB->pvSourceData); + ps32Spread = (psint32)pstSpreadCB->pvSpreadData; + + if (s32Source < *ps32Spread) + { + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex = 0; + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadOffset = 0; + } + else if (s32Source >= *(ps32Spread + (pstSpreadCB->s16SpreadSize - 1))) + { + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex = pstSpreadCB->s16SpreadSize - 2; + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadOffset = 0xffff; + } + else + { + /* Start bisection search */ + u16SpreadIDX = (pstSpreadCB->s16SpreadSize) / 2; + u16OldSpreadIDX = pstSpreadCB->s16SpreadSize - 1; + + while (false == boResultFound) + { + if ((s32Source == *(ps32Spread + u16SpreadIDX))) + { + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex = u16SpreadIDX; + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadOffset = 0; + boResultFound = true; + } + else if (s32Source < *(ps32Spread + u16SpreadIDX)) + { + if (s32Source >= *(ps32Spread + u16SpreadIDX - 1)) + { + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex = u16SpreadIDX - 1; + boResultFound = true; + } + else + { + /* Move left */ + if (u16OldSpreadIDX < u16SpreadIDX) + { + /* Was moving right */ + u16TempSpreadIDX = u16OldSpreadIDX; + u16OldSpreadIDX = u16SpreadIDX; + u16SpreadIDX = (u16SpreadIDX + u16TempSpreadIDX) / 2; + } + else + { + /* Was moving left */ + u16OldSpreadIDX = u16SpreadIDX; + u16SpreadIDX = u16SpreadIDX / 2; + } + } + } + else if (s32Source >= *(ps32Spread + u16SpreadIDX)) + { + if (s32Source <= *(ps32Spread + u16SpreadIDX + 1)) + { + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex = u16SpreadIDX; + boResultFound = true; + } + else + { + /* Move right */ + if (u16OldSpreadIDX > u16SpreadIDX) + { + /* Was moving left */ + u16TempSpreadIDX = u16OldSpreadIDX; + u16OldSpreadIDX = u16SpreadIDX; + u16SpreadIDX = (u16SpreadIDX + u16TempSpreadIDX) / 2; + } + else + { + /* Was moving right */ + u16OldSpreadIDX = u16SpreadIDX; + u16SpreadIDX = (u16SpreadIDX + pstSpreadCB->s16SpreadSize) / 2; + } + } + } + } + + s32Step = *(ps32Spread + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex + 1) + - *(ps32Spread + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex); + + while (0xffff < s32Step) + { + u32Shift++; + s32Step = s32Step >> 1; + } + + s32Increment = s32Source - *(ps32Spread + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadIndex); + s32Increment = s32Increment >> u32Shift; + SPREAD_astSpreadResult[tSpreadIDX].uSpreadData.stSpreadResult.u16SpreadOffset = (0x10000 * (uint32)s32Increment) / (uint32)s32Step; + } + break; + } + } + } + + /* TODO suppress warnings */ + (void)pu8Spread; + (void)ps16Spread; + (void)ps8Spread; + (void)s16Source; + + OS_stSVCDataStruct.pvData = (void*)&SPREAD_astSpreadResult;//matthew + + return boResultFound; +} + +SPREADAPI_tstSpreadResult SPREAD_stGetSpread(SPREADAPI_ttSpreadIDX tSpreadIDX) +{ + return SPREAD_astSpreadResult[tSpreadIDX]; +} + +SPREADAPI_tstSpreadResult* SPREAD_pstGetSpread(SPREADAPI_ttSpreadIDX tSpreadIDX) +{ + return &SPREAD_astSpreadResult[tSpreadIDX]; +} diff --git a/source/UserServices/SPREADS.h b/source/UserServices/SPREADS.h new file mode 100644 index 0000000..e351a80 --- /dev/null +++ b/source/UserServices/SPREADS.h @@ -0,0 +1,30 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef SPREADS_H +#define SPREADS_H + +#include "SPREADSAPI.h" +#include "SYSAPI.h" + +#define SPREAD_nKernelSpreadCount 50u +#define SPREAD_nUserSpreadCount 45u + +void SPREADS_vStart(puint32 const pu32Arg); +void SPREADS_vRun(puint32 const pu32Arg); +void SPREADS_vTerminate(puint32 const pu32Arg); +SPREADAPI_ttSpreadIDX SPREAD_tRequestKernelSpread(SPREADAPI_tstSpreadCB*); +bool SPREAD_vCalculate(SPREADAPI_ttSpreadIDX); +SPREADAPI_tstSpreadResult SPREAD_stGetSpread(SPREADAPI_ttSpreadIDX); +SPREADAPI_tstSpreadResult* SPREAD_pstGetSpread(SPREADAPI_ttSpreadIDX); + +#endif // TEPM_H + diff --git a/source/UserServices/TABLES.c b/source/UserServices/TABLES.c new file mode 100644 index 0000000..14ce375 --- /dev/null +++ b/source/UserServices/TABLES.c @@ -0,0 +1,276 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#include "os.h" +#include "stddef.h" +#include "types.h" +#include "SPREADS.h" +#include "TABLES.h" +#include "SYSAPI.h" +#include "MATH.h" +#include "declarations.h" + +/* Private data declarations + -------------------------*/ +TABLEAPI_tstTableCB TABLE_astTableCB[TABLE_nKernelTableCount]; +TABLEAPI_tstTableCB* TABLE_apstTableCB[TABLE_nKernelTableCount + TABLE_nUserTableCount]; +uint32 TABLE_au32Counter[TABLE_nKernelTableCount + TABLE_nUserTableCount]; + +/* Private function declarations + ----------------------------*/ + +/* Public function definitions + ---------------------------*/ +void TABLES_vStart(puint32 const pu32Arg) +{ + uint32 u32IDX; + + for (u32IDX = 0; u32IDX < (TABLE_nKernelTableCount + TABLE_nUserTableCount); u32IDX++) + { + TABLE_apstTableCB[u32IDX] = NULL; + } +} + +void TABLES_vRun(puint32 const pu32Arg) +{ + + +} + +void TABLES_vTerminate(puint32 const pu32Arg) +{ + + +} + +TABLEAPI_ttTableIDX TABLE_tRequestKernelTable(TABLEAPI_tstTableCB* pstTableCBReq) +{ + TABLEAPI_tstTableCB* pstTableCB; + uint32 u32TableIDX; + TABLEAPI_ttTableIDX TableIDX = -1; + + /* Request a Kernel managed TABLE */ + for (u32TableIDX = 0; TABLE_nKernelTableCount > u32TableIDX; u32TableIDX++) + { + if (NULL == TABLE_apstTableCB[u32TableIDX]) + { + pstTableCB = &TABLE_astTableCB[u32TableIDX]; + TABLE_apstTableCB[u32TableIDX] = pstTableCB; + memcpy((void*)pstTableCB, (void*)pstTableCBReq, sizeof(TABLEAPI_tstTableCB)); + TableIDX = u32TableIDX; + break; + } + } + + return TableIDX; +} + +bool TABLE_vSetKernelTableAddress(TABLEAPI_ttTableIDX tTableIDX, void* pvTableData) +{ + bool boRetVal = false; + + if (TABLE_nKernelTableCount < tTableIDX) + { + if (NULL != TABLE_apstTableCB[tTableIDX]) + { + TABLE_apstTableCB[tTableIDX]->pvTableData = pvTableData; + boRetVal = true; + } + } + + return boRetVal; +} + + +bool TABLE_vCalculate(TABLEAPI_ttTableIDX tTableIDX) +{ + uint8 u8DataR; uint16 u16DataL; uint16 u16DataR; uint32 u32DataR; uint32 u32DataL; + sint8 s8DataL; sint16 s16DataL; sint32 s32DataL; + sint8 s8DataR; sint16 s16DataR; sint32 s32DataR; + uint8 u8Data; uint16 u16Data; uint32 u32Data; + sint8 s8Data; sint16 s16Data; sint32 s32Data; + puint8 pu8Data; puint16 pu16Data; puint32 pu32Data; + psint8 ps8Data; psint16 ps16Data; psint32 ps32Data; + SPREADAPI_ttSpreadIDX tSpreadIDX; + SPREADAPI_tstSpreadResult stSpreadResult; + uint32 u32ShiftL = 0; + uint32 u32ShiftR = 0; + uint32 u32Factor; + tSpreadIDX = TABLE_astTableCB[tTableIDX].tSpreadIDX; + + stSpreadResult = SPREAD_stGetSpread(tSpreadIDX); + + switch (TABLE_astTableCB[tTableIDX].enDataType) + { + case TYPE_enUInt8: + case TYPE_enUInt16: + { + pu16Data = (uint16*)TABLE_astTableCB[tTableIDX].pvTableData; + pu16Data += stSpreadResult.uSpreadData.stSpreadResult.u16SpreadIndex; + + u16DataL = *pu16Data; + u16DataR = *(pu16Data + 1); + + while (0x4000 <= u16DataL) + { + u32ShiftL++; + u16DataL /= 2; + } + + while (0x4000 <= u16DataR) + { + u32ShiftR++; + u16DataR /= 2; + } + + u32ShiftL = (u32ShiftL > u32ShiftR) ? u32ShiftL : u32ShiftR; + u32Factor = MATH_u32IDXToMask(u32ShiftL); + + u16DataL = (*pu16Data) / u32Factor; + u16DataR = (*(pu16Data + 1)) / u32Factor; + + u32Data = (u16DataR * stSpreadResult.uSpreadData.stSpreadResult.u16SpreadOffset) + + (u16DataL * (0xffff - stSpreadResult.uSpreadData.stSpreadResult.u16SpreadOffset)); + + u32Data *= u32Factor; + u32Data /= 0xffff; + + *(uint16*)TABLE_astTableCB[tTableIDX].pvOutputData = (sint16)u32Data; + break; + } + case TYPE_enInt8: + case TYPE_enInt16: + { + ps16Data = (sint16*)TABLE_astTableCB[tTableIDX].pvTableData; + ps16Data += stSpreadResult.uSpreadData.stSpreadResult.u16SpreadIndex; + + s16DataL = *ps16Data; + s16DataR = *(ps16Data + 1); + + while ((0x4000 <= s16DataL) || (-0x4000 >= s16DataL)) + { + u32ShiftL++; + s16DataL /= 2; + } + + while ((0x4000 <= s16DataR) || (-0x4000 >= s16DataR)) + { + u32ShiftR++; + s16DataR /= 2; + } + + u32ShiftL = (u32ShiftL > u32ShiftR) ? u32ShiftL : u32ShiftR; + u32Factor = MATH_u32IDXToMask(u32ShiftL); + + s16DataL = (*ps16Data) / u32Factor; + s16DataR = (*(ps16Data + 1)) / u32Factor; + + u32Data = (s16DataR * stSpreadResult.uSpreadData.stSpreadResult.u16SpreadOffset) + + (s16DataL * (0xffff - stSpreadResult.uSpreadData.stSpreadResult.u16SpreadOffset)); + + u32Data *= u32Factor; + u32Data /= 0xffff; + + *(sint16*)TABLE_astTableCB[tTableIDX].pvOutputData = (sint16)u32Data; + break; + } + case TYPE_enInt32: + { + ps32Data = (sint32*)TABLE_astTableCB[tTableIDX].pvTableData; + ps32Data += stSpreadResult.uSpreadData.stSpreadResult.u16SpreadIndex; + + s32DataL = *ps32Data; + s32DataR = *(ps32Data + 1); + + while ((0x4000L <= s32DataL) || (-0x4000L >= s32DataL)) + { + u32ShiftL++; + s32DataL /= 2; + } + + while ((0x4000L <= s32DataR) || (-0x4000L >= s32DataR)) + { + u32ShiftR++; + s32DataR /= 2; + } + + u32ShiftL = (u32ShiftL > u32ShiftR) ? u32ShiftL : u32ShiftR; + u32Factor = MATH_u32IDXToMask(u32ShiftL); + + s32DataL = (*ps32Data) / (sint32)u32Factor; + s32DataR = (*(ps32Data + 1)) / (sint32)u32Factor; + + s32Data = (s32DataR * (sint32)stSpreadResult.uSpreadData.stSpreadResult.u16SpreadOffset) + + (s32DataL * (sint32)(0xffff - stSpreadResult.uSpreadData.stSpreadResult.u16SpreadOffset)); + + s32Data /= 0xffff; //matthew check this look for a better way to hold precision + s32Data *= u32Factor; + + *(sint32*)TABLE_astTableCB[tTableIDX].pvOutputData = s32Data; + break; + } + case TYPE_enUInt32: + { + pu32Data = (uint32*)TABLE_astTableCB[tTableIDX].pvTableData; + pu32Data += stSpreadResult.uSpreadData.stSpreadResult.u16SpreadIndex; + + u32DataL = *pu32Data; + u32DataR = *(pu32Data + 1); + + while (0x4000 <= u32DataL) + { + u32ShiftL++; + u32DataL /= 2; + } + + while (0x4000 <= u32DataR) + { + u32ShiftR++; + u32DataR /= 2; + } + + u32ShiftL = (u32ShiftL > u32ShiftR) ? u32ShiftL : u32ShiftR; + u32Factor = MATH_u32IDXToMask(u32ShiftL); + + u32DataL = (*pu32Data) / u32Factor; + u32DataR = (*(pu32Data + 1)) / u32Factor; + + u32Data = (u32DataR * stSpreadResult.uSpreadData.stSpreadResult.u16SpreadOffset) + + (u32DataL * (0xffff - stSpreadResult.uSpreadData.stSpreadResult.u16SpreadOffset)); + + u32Data /= 0xffff; //matthew check this look for a better way to hold precision + u32Data *= u32Factor; + + *(uint32*)TABLE_astTableCB[tTableIDX].pvOutputData = u32Data; + break; + } + } + + OS_stSVCDataStruct.pvData = NULL; + + /* TODO suppress warning */ + (void)u8DataR; + (void)u16DataR; + (void)s8DataL; + (void)s8DataR; + (void)u8Data; + (void)u16Data; + (void)s16Data; + (void)pu16Data; + (void)ps8Data; + (void)s8Data; + (void)s32Data; + (void)pu8Data; + + return true; +} + diff --git a/source/UserServices/TABLES.h b/source/UserServices/TABLES.h new file mode 100644 index 0000000..7332f92 --- /dev/null +++ b/source/UserServices/TABLES.h @@ -0,0 +1,28 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef TABLES_H +#define TABLES_H + +#include "TABLESAPI.h" +#include "SYSAPI.h" + +#define TABLE_nKernelTableCount 30u +#define TABLE_nUserTableCount 25u + +void TABLES_vStart(puint32 const pu32Arg); +void TABLES_vRun(puint32 const pu32Arg); +void TABLES_vTerminate(puint32 const pu32Arg); +TABLEAPI_ttTableIDX TABLE_tRequestKernelTable(TABLEAPI_tstTableCB*); +bool TABLE_vCalculate(TABLEAPI_ttTableIDX); + +#endif // TABLES_H + diff --git a/source/UserServices/TEPM.c b/source/UserServices/TEPM.c new file mode 100644 index 0000000..dced495 --- /dev/null +++ b/source/UserServices/TEPM.c @@ -0,0 +1,1285 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: TEPM */ +/* DESCRIPTION: Timed Event Programs module provides services for the */ +/* output of timed pulse-trains */ +/* FILE NAME: TEPM.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _TEPM_C + +#include +#include "build.h" +#include "CEM.h" +#include "client.h" +#include "CPUAbstract.h" +#include "CQUEUE.h" +#include "declarations.h" +#include "stddef.h" +#include "types.h" +#include "IRQ.h" +#include "TEPM.h" +#include "TEPMHA.h" +#include "TEPMAPI.h" +#include "MSG.h" +#include "SIM.h" +#include "REGSET.h" +#include "RESM.h" +#include "IOAPI.h" +#include "SYSAPI.h" + + +//#define DEBUG_TEPM + +/* Private data declarations + -------------------------*/ +TEPMAPI_tstTimedUserEvent TEPM_aastTimedUserEvents[TEPMHA_nEventChannels][TEPMHA_nUserEventsMax]; +TEPMAPI_tstTimedKernelEvent TEPM_aastTimedKernelEvents[TEPMHA_nEventChannels][TEPMHA_nKernelEventsMax]; +const TEPM_tstTEPMChannel TEPM_rastTEPMChannel[] = TEPMHA_nChannelInfo; +const IOAPI_tenEHIOResource TEPM_rastTEPMFastChannel[] = TEPMHA_nChannelFastInfo; +const TEPM_tstMasters TEPM_rastMasters[] = TEPMHA_nMasterInfo; +CQUEUE_tstQueue TEPM_astProgramKernelQueue[TEPMHA_nEventChannels]; +CQUEUE_tstQueue TEPM_astProgramUserQueue[TEPMHA_nEventChannels]; +TEPMAPI_tpfEventCB TEPM_atpfEventKernelCB[TEPMHA_nEventChannels]; +TEPMAPI_tpfEventCB TEPM_atpfEventUserCB[TEPMHA_nEventChannels]; +TEPM_tstTEPMResult TEPM_astEventResult[TEPMHA_nEventChannels]; +MSG_tstMBX* TEPM_apstMBX[TEPMHA_nEventChannels]; +bool TEPM_aboTEPMChannelModeInput[TEPMHA_nEventChannels]; +bool TEPM_aboTEPMChannelModeOutput[TEPMHA_nEventChannels]; +bool TEPM_aboTEPMChannelModeRecursive[TEPMHA_nEventChannels]; +bool TEPM_au32TEPMChannelRecursionCount[TEPMHA_nEventChannels]; +bool TEPM_aboTEPMChannelModePWM[TEPMHA_nEventChannels]; +bool TEPM_aboTEPMChannelAsyncRequestEnable[TEPMHA_nEventChannels]; +uint32 TEPM_au32TEPMChannelSequence[TEPMHA_nEventChannels]; +bool TEPM_aboSynchroniseEnable[TEPMHA_nEventChannels]; +volatile bool TEPM_aboQueueOverflow[TEPMHA_nEventChannels]; +EXTERN uint32 CAM_u32RPMRaw; +EXTERN IOAPI_tenEdgePolarity CEM_enEdgePolarity; +bool TEPM_boDisableSequences; +IOAPI_tenEHIOResource TEPM_astTEPMVVTInputs[4]; +IOAPI_tenEHIOResource TEPM_astTEPMLinkedResource[TEPMHA_nEventChannels]; +uint32 TEPM_u32PrimaryPhaseIDX; +uint16 TEPM_au16PWMLowResidual[16]; +uint32 TEPM_u32FuelCutsPercent; +uint32 TEPM_u32SparkCutsPercent; +uint32 TEPM_u32FuelCutsMask; +uint32 TEPM_u32SparkCutsMask; +uint32 TEPM_u32FuelChannelCount; +uint32 TEPM_u32SparkChannelCount; +uint32 TEPM_u32FuelCutsCounter; + +#ifdef TEPM_PRIO_INPUT_MK6X +extern const TEPM_tstTEPMReverseChannel TEPMHA_rastTEPMReverseChannel[]; +#endif //TEPM_PRIO_INPUT_MK6X + +#define TEPM_nTableCount sizeof(TEPM_rastTEPMChannel) / sizeof(TEPM_tstTEPMChannel) + +/* Private function declarations + ----------------------------*/ +#ifdef TEPM_USER_MODE +static void TEPM_vRunEventProgramUserQueue(void*, uint32, uint32); +#endif //TEPM_USER_MODE + +static void TEPM_vRunEventProgramKernelQueue(void*, uint32, uint32, uint32, bool); +static void* TEPM_pvGetModule(IOAPI_tenEHIOResource); +static void* TEPM_pstGetModuleFromEnum(TEPMHA_tenTimerModule); +static uint32 TEPM_u32GetTimerHardwareChannel(IOAPI_tenEHIOResource); + +/* Public function definitions + ---------------------------*/ +void TEPM_vStart(puint32 const pu32Arg) +{ + uint32 u32QueueIDX; + + for (u32QueueIDX = 0; u32QueueIDX < TEPMHA_nEventChannels; u32QueueIDX++) + { + CQUEUE_xInit(TEPM_astProgramUserQueue + u32QueueIDX, + TEPMHA_nUserEventsMax, (uint32)TEPM_aastTimedUserEvents + u32QueueIDX * TEPMHA_nUserEventsMax * sizeof(TEPMAPI_tstTimedUserEvent)); + + CQUEUE_xInit(TEPM_astProgramKernelQueue + u32QueueIDX, + TEPMHA_nKernelEventsMax, (uint32)TEPM_aastTimedKernelEvents + u32QueueIDX * TEPMHA_nUserEventsMax * sizeof(TEPMAPI_tstTimedKernelEvent)); + + TEPM_atpfEventKernelCB[u32QueueIDX] = NULL; + TEPM_atpfEventUserCB[u32QueueIDX] = NULL; + TEPM_apstMBX[u32QueueIDX] = NULL; + TEPM_aboTEPMChannelModeInput[u32QueueIDX] = FALSE; + TEPM_aboTEPMChannelModeOutput[u32QueueIDX] = FALSE; + TEPM_aboTEPMChannelAsyncRequestEnable[u32QueueIDX] = FALSE; + TEPM_au32TEPMChannelSequence[u32QueueIDX] = ~0; + TEPM_boDisableSequences = FALSE; + TEPM_astTEPMLinkedResource[u32QueueIDX] = EH_IO_Invalid; + } + + TEPM_u32FuelCutsPercent = 5; +} + +IOAPI_tenEHIOResource TEPM_enGetPrimaryLinkedResource(void) +{ + return TEPM_astTEPMLinkedResource[TEPM_u32PrimaryPhaseIDX]; +} + +void TEPM_vAsyncRequest(void) +{ + CEM_u32GlobalCycleFraction = 0x0000; + TEPM_vStartEventProgramKernelQueues(TRUE, 0); + CEM_u32GlobalCycleFraction += (0x10000 / CEM_u32SyncPoints); + TEPM_vStartEventProgramKernelQueues(TRUE, 1); + + CEM_u32GlobalCycleFraction = 0x10000; + TEPM_vStartEventProgramKernelQueues(TRUE, 4); + CEM_u32GlobalCycleFraction += (0x10000 / CEM_u32SyncPoints); + TEPM_vStartEventProgramKernelQueues(TRUE, 5); +} + +void TEPM_vEnableSequences(bool boEnable) +{ + TEPM_boDisableSequences = ~boEnable; +} + +void TEPM_vRun(puint32 const pu32Arg) +{ + /* + static uint32 u32Count; + uint32 u32TimerChannelIDX; + void* pvModule; + const IOAPI_tenEHIOResource raenResourceList[] = TEPMHA_nChannelResourceList; + uint32 u32ChannelIDX; + IOAPI_tenEHIOResource enEHIOResource; + TEPMAPI_ttEventTime tEventTimeScheduled; + + u32Count++; + + if (0 == (u32Count % 50)) + { + for (u32TimerChannelIDX = 0; u32TimerChannelIDX < TEPMHA_nEventChannels; u32TimerChannelIDX++) + { + if (TRUE == TEPM_aboTEPMChannelModePWM[u32TimerChannelIDX]) + { + enEHIOResource = raenResourceList[u32TimerChannelIDX]; + uint32 u32TableIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + pvModule = TEPMHA_pvGetModuleFromEnum(TEPM_rastTEPMChannel[u32TableIDX].enModule); + u32ChannelIDX = TEPM_u32GetTimerHardwareChannel(enEHIOResource); + + CPU_xEnterCritical(); + tEventTimeScheduled = TEPMHA_u32GetFreeVal(pvModule, u32ChannelIDX) + 50; + tEventTimeScheduled &= TEPMHA_nCounterMask; + TEPMHA_vCapComAction(TEPMAPI_enSetHigh, pvModule, u32ChannelIDX, 0, tEventTimeScheduled); + CPU_xExitCritical(); + } + } + } + + if (1 == (u32Count % 50)) + { + for (u32TimerChannelIDX = 0; u32TimerChannelIDX < TEPMHA_nEventChannels; u32TimerChannelIDX++) + { + if (TRUE == TEPM_aboTEPMChannelModePWM[u32TimerChannelIDX]) + { + enEHIOResource = raenResourceList[u32TimerChannelIDX]; + uint32 u32TableIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + pvModule = TEPMHA_pvGetModuleFromEnum(TEPM_rastTEPMChannel[u32TableIDX].enModule); + u32ChannelIDX = TEPM_u32GetTimerHardwareChannel(enEHIOResource); + + CPU_xEnterCritical(); + tEventTimeScheduled = TEPMHA_u32GetFreeVal(pvModule, u32ChannelIDX); + tEventTimeScheduled += ((*TEPM_aastTimedKernelEvents[u32TableIDX][0].ptEventTime)); + tEventTimeScheduled &= TEPMHA_nCounterMask; + TEPMHA_vCapComAction(TEPMAPI_enSetLow, pvModule, u32ChannelIDX, 0, tEventTimeScheduled); + CPU_xExitCritical(); + } + } + } + */ +} + +void TEPM_vTerminate(puint32 const pu32Arg) +{ + + +} + +uint32 TEPM_u32InitTEPMChannel(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_tstTEPMChannelCB* pstTEPMChannelCB, bool boPWMMode) +{ + //uint32 u32ChannelIDX; + uint32 u32TableIDX; + //uint32 u32ControlWord = 0; + MSG_tenMBXErr enMBXErr; + + TEPMHA_vInitTEPMChannel(enEHIOResource, pstTEPMChannelCB); + u32TableIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + TEPM_astTEPMLinkedResource[u32TableIDX] = pstTEPMChannelCB->enLinkedResource; + + if ((pstTEPMChannelCB->enAction == TEPMAPI_enCapAny) | + (pstTEPMChannelCB->enAction == TEPMAPI_enCapRising) | + (pstTEPMChannelCB->enAction == TEPMAPI_enCapFalling)) + { + TEPM_aboTEPMChannelModeInput[u32TableIDX] = TRUE; + TEPM_aboTEPMChannelModeOutput[u32TableIDX] = FALSE; + TEPM_aboTEPMChannelModeRecursive[u32TableIDX] = pstTEPMChannelCB->boRecursive; + } + else + { + TEPM_aboTEPMChannelModeOutput[u32TableIDX] = TRUE; + TEPM_aboTEPMChannelModeInput[u32TableIDX] = FALSE; + TEPM_aboTEPMChannelModePWM[u32TableIDX] = boPWMMode; + TEPM_aboTEPMChannelModeRecursive[u32TableIDX] = FALSE; + } + + if (0x10000000 <= pstTEPMChannelCB->u32Sequence) + { + /* Special case for VVT input MS 8bit = 0x10 */ + TEPM_au32TEPMChannelSequence[u32TableIDX] = pstTEPMChannelCB->u32Sequence; + } + else if (0x10000 <= pstTEPMChannelCB->u32Sequence) + { + /* Special case for fuel pressure control solenoid MS 16bit != 0*/ + TEPM_au32TEPMChannelSequence[u32TableIDX] = (pstTEPMChannelCB->u32Sequence & 0xf) + + ((pstTEPMChannelCB->u32Sequence & 0xf00) >> 4) + + ((pstTEPMChannelCB->u32Sequence & 0xf0000) >> 8) + + ((pstTEPMChannelCB->u32Sequence & 0xf000000) >> 12) + + 0x04000000; + } + else if ((0x00000080 <= pstTEPMChannelCB->u32Sequence) && + (0x000000FF >= pstTEPMChannelCB->u32Sequence)) + { + /* Special case for fuel pressure control solenoid Golf MK6 16bit != 0*/ + TEPM_au32TEPMChannelSequence[u32TableIDX] = (pstTEPMChannelCB->u32Sequence & 0xff) + + 0x08000000; + } + else + { + TEPM_au32TEPMChannelSequence[u32TableIDX] = pstTEPMChannelCB->u32Sequence & 0xffff; + + if (((TEPM_au32TEPMChannelSequence[u32TableIDX] & 0x0ff) == 0x0ff) || + ((TEPM_au32TEPMChannelSequence[u32TableIDX] & 0xff00) == 0xff00)) + { + TEPM_au32TEPMChannelSequence[u32TableIDX] |= 0x02000000; + } + else + { + TEPM_au32TEPMChannelSequence[u32TableIDX] |= 0x01000000; + } + } + + + TEPM_aboTEPMChannelAsyncRequestEnable[u32TableIDX] = pstTEPMChannelCB->boAsyncRequestEnable; + + /* Check if a mailbox is allocated for this table index */ + if (NULL == TEPM_apstMBX[u32TableIDX]) + { + enMBXErr = MSG_enMBXNew((MSG_tstMBX**)&TEPM_apstMBX[u32TableIDX], + MSG_enTEPMEvent); + } + + /* TODO suppress warning */ + (void)enMBXErr; + + return TEPM_rastTEPMChannel[u32TableIDX].u32MuxSel; +} + + +SYSAPI_tenSVCResult TEPM_vInitTEPMResource(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_tstTEPMResourceCB* pstTEPMResourceCB) +{ + return TEPMHA_vInitTEPMResource(enEHIOResource, pstTEPMResourceCB); +} + +void TEPM_boGetMasterEHIOResourceList(IOAPI_tenEHIOResource enEHIOResource, IOAPI_tenEHIOResource* penEHIOResource, puint32 pu32MasterCount) +{ + uint32 u32ChannelIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + uint32 u32MasterIDX = 0; + + while ((RESM_nMastersMax > *pu32MasterCount) && (TEPMHA_nMastersMax > u32MasterIDX)) + { + if (NULL != TEPM_rastMasters[u32ChannelIDX].enEHIOResource[u32MasterIDX]) + { + *penEHIOResource = TEPM_rastMasters[u32ChannelIDX].enEHIOResource[u32MasterIDX]; + penEHIOResource++; + (*pu32MasterCount)++; + u32MasterIDX++; + } + } +} + +void TEPM_vAppendTEPMQueue(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_tstTimedUserEvent* pstTimedEvents, TEPMAPI_ttEventCount tEventCount) +{ + uint32 u32TableIDX; + + CPU_xEnterCritical(); + + u32TableIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + + while ((0 < tEventCount--) + && (FALSE == CQUEUE_xIsFull(TEPM_astProgramUserQueue + u32TableIDX))) + { + memcpy((void*)&TEPM_aastTimedUserEvents[u32TableIDX][TEPM_astProgramUserQueue[u32TableIDX].u32Tail], + (void*)pstTimedEvents++, sizeof(TEPMAPI_tstTimedUserEvent)); + CQUEUE_xAddItem(TEPM_astProgramUserQueue + u32TableIDX); + } + + CPU_xExitCritical(); +} + +void TEPM_vConfigureUserTEPMInput(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_tstTimedUserEvent* pstTimedEvent) +{ + uint32 u32TableIDX; + + u32TableIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + + switch (pstTimedEvent->enMethod) + { + case TEPMAPI_enLinkPrimaryProgram: + { + TEPM_atpfEventKernelCB[u32TableIDX] = &CEM_vPrimaryEventCB; + TEPM_u32PrimaryPhaseIDX = u32TableIDX; + break; + } + case TEPMAPI_enLinkVVT1Input: + { + TEPM_atpfEventKernelCB[u32TableIDX] = &CEM_vPhaseEventCB; + TEPM_astTEPMVVTInputs[0] = enEHIOResource; + break; + } + case TEPMAPI_enLinkVVT2Input: + { + TEPM_atpfEventKernelCB[u32TableIDX] = &CEM_vPhaseEventCB; + TEPM_astTEPMVVTInputs[1] = enEHIOResource; + break; + } + case TEPMAPI_enLinkVVT3Input: + { + TEPM_atpfEventKernelCB[u32TableIDX] = &CEM_vPhaseEventCB; + TEPM_astTEPMVVTInputs[2] = enEHIOResource; + break; + } + case TEPMAPI_enLinkVVT4Input: + { + TEPM_atpfEventKernelCB[u32TableIDX] = &CEM_vPhaseEventCB; + TEPM_astTEPMVVTInputs[3] = enEHIOResource; + break; + } + case TEPMAPI_enLinkFreqInput: + { + TEPM_atpfEventKernelCB[u32TableIDX] = & CEM_vFreqEventCB; + break; + } + default: + { + break; + } + } + + TEPM_atpfEventUserCB[u32TableIDX] = pstTimedEvent->pfEventCB; + + if (FALSE == CQUEUE_xIsFull(TEPM_astProgramUserQueue + u32TableIDX)) + { + memcpy((void*)&TEPM_aastTimedUserEvents[u32TableIDX][TEPM_astProgramUserQueue[u32TableIDX].u32Tail], + (void*)pstTimedEvent, sizeof(TEPMAPI_tstTimedUserEvent)); + CQUEUE_xAddItem(TEPM_astProgramUserQueue + u32TableIDX); + } +} + +void TEPM_vConfigureKernelTEPMOutput(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_tstTimedKernelEvent* pstTimedEvents, TEPMAPI_ttEventCount tEventCount) +{ + uint32 u32TableIDX; + + u32TableIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + + TEPM_atpfEventUserCB[u32TableIDX] = pstTimedEvents->pfEventCB; + + /* Reset the queue count it is not possible to append a Kernel output queue */ + CQUEUE_xClearCount(TEPM_astProgramKernelQueue + u32TableIDX); + + while ((0 < tEventCount--) + && (FALSE == CQUEUE_xIsFull(TEPM_astProgramKernelQueue + u32TableIDX))) + { + memcpy((void*)&TEPM_aastTimedKernelEvents[u32TableIDX][TEPM_astProgramKernelQueue[u32TableIDX].u32Tail], + (void*)pstTimedEvents++, sizeof(TEPMAPI_tstTimedKernelEvent)); + CQUEUE_xAddItem(TEPM_astProgramKernelQueue + u32TableIDX); + } +} + +void TEPM_vInitiateUserCallBack(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_ttEventTime tEventTime) +{ + MSG_tstMBX* pstMBX; + tpfClientCB pfClientCB; + CLIENT_tenErr enErr; + uint32 u32TableIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + + /* Store the programmed event resource for the user callback */ + TEPM_astEventResult[u32TableIDX].enEHIOResource = enEHIOResource; + + /* Store the timer result for the user callback */ + TEPM_astEventResult[u32TableIDX].tEventTime = tEventTime; + + pfClientCB = (tpfClientCB)TEPM_atpfEventUserCB[u32TableIDX]; + pstMBX = TEPM_apstMBX[u32TableIDX]; + MSG_vMBXPost(pstMBX, (void*)&TEPM_astEventResult[u32TableIDX]); + + if ((NULL != pfClientCB) && (MSG_boMBXValid(pstMBX))) + { + enErr = CLIENT_enEnqueueCB(pstMBX, pfClientCB); + } + + /* TODO suppress warning */ + (void)enErr; +} + + +void TEPM_u32GetFreeVal(IOAPI_tenEHIOResource enEHIOResource, puint32 pu32Data) +{ + void* pvModule = TEPM_pvGetModule(enEHIOResource); + + TEPMHA_vGetFreeVal(pvModule, pu32Data); +} + +void TEPM_vInterruptHandler(IOAPI_tenEHIOResource enEHVIOResource, void* pvData) +{ + uint32 u32ChannelIDX; + uint32 u32TableIDX; + uint32 u32Flags = 0; + uint32 u32Temp; + TEPMAPI_tpfEventCB pfTEPMEventCB; + uint32 u32StartChannelIDX = 0; + uint32 u32EndChannelIDX; + IOAPI_tenEHIOResource enEHIOResource; + static uint32 u32FalseAlarmCount; + TEPMAPI_ttEventTime tEventTimeScheduled; + +#ifdef TEPM_PRIO_INPUT_MK6X + static uint32 u32PrioChannelIDX = TEPMHA_nPRIOCHANNEL; +#endif //TEPM_PRIO_INPUT_MK6X + + + /* Note here the resource passed in is the timer module resource not the timer channel */ + void* pvModule = TEPMHA_pvGetTimerModuleFromVIO(enEHVIOResource); + +#ifndef TEPM_SPEED_MK6X + u32StartChannelIDX = 0; +#endif //TEPM_SPEED_MK6X + u32EndChannelIDX = u32StartChannelIDX + TEPMHA_u32GetTimerChannelsPerInterruptGroup(pvModule); + + /* Loop through the channels contained within this interrupt group */ + for (u32ChannelIDX = u32StartChannelIDX; u32ChannelIDX < u32EndChannelIDX; u32ChannelIDX++) + { +#ifdef TEPM_SPEED_MK6X + if (FTM_CnSC_CHF_MASK == (FTM_CnSC_CHF_MASK & ((tstTimerModule*)pvModule)->CONTROLS[u32ChannelIDX].CnSC)) +#else + if (true == TEPMHA_boFlagIsSet(pvModule, u32ChannelIDX, &u32Flags, u32Sequence[u32Prio], u32Prio)) +#endif //TEPM_SPEED_MK6X + { +#ifdef TEPM_SPEED_MK6X + if (FTM_CnSC_CHIE_MASK == (FTM_CnSC_CHIE_MASK & ((tstTimerModule*)pvModule)->CONTROLS[u32ChannelIDX].CnSC)) +#else + if (true == TEMPHA_boInterruptEnabled(pvModule, u32ChannelIDX)) +#endif //TEPM_SPEED_MK6X + { +#ifndef TEPM_SPEED_MK6X + enEHIOResource = TEPMHA_enGetTimerResourceFromVIOAndIndex(enEHVIOResource, u32ChannelIDX); + u32TableIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); +#else + u32Temp = 8 * ((uint32)(enEHVIOResource - EH_VIO_FTM0)) + u32ChannelIDX; + enEHIOResource = TEPMHA_rastTEPMReverseChannel[u32Temp].enEHIOResource; + u32TableIDX = enEHIOResource - EH_IO_TMR1; +#endif //TEPM_SPEED_MK6X + + if (TRUE == TEPM_aboTEPMChannelModeOutput[u32TableIDX]) + { + if (TRUE == TEPM_aboTEPMChannelModePWM[u32TableIDX]) + { + pvModule = TEPMHA_pvGetModuleFromEnum(TEPM_rastTEPMChannel[u32TableIDX].enModule); + u32ChannelIDX = TEPM_u32GetTimerHardwareChannel(enEHIOResource); + + if (0 == TEPM_au16PWMLowResidual[u32TableIDX]) + { + tEventTimeScheduled = TEPMHA_tGetScheduledVal(pvModule, u32ChannelIDX, FALSE, 0); + u32Temp = (*TEPM_aastTimedKernelEvents[u32TableIDX][0].ptEventTime); + u32Temp *= TEPM_aastTimedKernelEvents[u32TableIDX][0].tAccumulate; + u32Temp /= 0x10000; + tEventTimeScheduled += u32Temp; + tEventTimeScheduled &= TEPMHA_nCounterMask; + TEPMHA_vCapComAction(TEPMAPI_enSetLow, pvModule, u32ChannelIDX, 0, tEventTimeScheduled); + TEPM_au16PWMLowResidual[u32TableIDX] = TEPM_aastTimedKernelEvents[u32TableIDX][0].tAccumulate - u32Temp; + } + else + { + tEventTimeScheduled = TEPMHA_tGetScheduledVal(pvModule, u32ChannelIDX, FALSE, 0); + tEventTimeScheduled += TEPM_au16PWMLowResidual[u32TableIDX]; + tEventTimeScheduled &= TEPMHA_nCounterMask; + TEPMHA_vCapComAction(TEPMAPI_enSetHigh, pvModule, u32ChannelIDX, 0, tEventTimeScheduled); + TEPM_au16PWMLowResidual[u32TableIDX] = 0; + } + } + else + { + if (TRUE == TEPM_aboQueueOverflow[u32TableIDX]) + { + TEPM_aboQueueOverflow[u32TableIDX] = FALSE; + CQUEUE_xSetHead(TEPM_astProgramKernelQueue + u32TableIDX, 0); + TEPM_vStartEventProgramKernelQueues(FALSE, TEPM_au32TEPMChannelSequence[u32TableIDX]); + } + + else if (FALSE == TEPMHA_boCheckFalseAlarm(pvModule, u32ChannelIDX, TEPMHA_u32GetTimerHardwareSubChannel(u32TableIDX))) + { + TEPM_vRunEventProgramKernelQueue(pvModule, u32ChannelIDX, u32TableIDX, + TEPM_au32TEPMChannelSequence[u32TableIDX], false); + TEPM_vInitiateUserCallBack(enEHIOResource, TEPMHA_tGetScheduledVal(pvModule, u32ChannelIDX, TEPM_aboTEPMChannelModeInput[u32TableIDX], u32Flags)); + } + else + { + u32FalseAlarmCount++; + } + } + } + else if (TRUE == TEPM_aboTEPMChannelModeInput[u32TableIDX]) + { + pfTEPMEventCB = TEPM_atpfEventKernelCB[u32TableIDX]; + + if (NULL != pfTEPMEventCB) + { +#if defined (TEPM_REENTRANCY) + IOAPI_tenTriState enPrioTriState; + IOAPI_tenTriState enPrioTriStateOld; + bool boHWReentrancy = FALSE; + bool boHWReentrancyFlag = FALSE; + + if (TRUE == TEPM_aboTEPMChannelModeRecursive[u32TableIDX]) + { + + if (0 == TEPM_au32TEPMChannelRecursionCount[u32TableIDX]) + { + /* Let's go again */ + TEMPHA_vResetTimerFlag(pvModule, u32ChannelIDX); + TEPM_au32TEPMChannelRecursionCount[u32TableIDX]++; + pfTEPMEventCB(enEHIOResource, TEPMHA_tGetScheduledVal(pvModule, u32ChannelIDX, TEPM_aboTEPMChannelModeInput[u32TableIDX], u32Flags)); + } + else + { + TEPM_au32TEPMChannelRecursionCount[u32TableIDX]++; + } + + if (0 != TEPM_au32TEPMChannelRecursionCount[u32TableIDX]) + { + TEPM_au32TEPMChannelRecursionCount[u32TableIDX]--; + } + } + else +#endif //TEPM_REENTRANCY + { + pfTEPMEventCB(enEHIOResource, TEPMHA_tGetScheduledVal(pvModule, u32ChannelIDX, TEPM_aboTEPMChannelModeInput[u32TableIDX], u32Flags)); +#ifdef TEPM_REENTRANCY_HW + IOAPI_tenTriState enPrioTriState; + IOAPI_tenTriState enPrioTriStateOld; + bool boHWReentrancy = FALSE; + bool boHWReentrancyFlag = FALSE; + + if (u32PrioChannelIDX == u32ChannelIDX) + { + if (IOAPI_enEdgeFalling == CEM_enEdgePolarity) + { + /* But HW inverted */ + enPrioTriStateOld = IOAPI_enHigh; + enPrioTriState = TEPM_enGetTimerDigitalState(TEPM_PRIO_RESOURCE); + } + else + { + /* But HW inverted */ + enPrioTriStateOld = IOAPI_enLow; + enPrioTriState = TEPM_enGetTimerDigitalState(TEPM_PRIO_RESOURCE); + } + + boHWReentrancy = TRUE; + boHWReentrancyFlag = FALSE; + } +#endif //TEPM_REENTRANCY_HW + } + } + } + } + + TEMPHA_vResetTimerFlag(pvModule, u32ChannelIDX); + } + +#ifdef TEPM_PRIO_INPUT_MK6X + +#ifdef TEPM_SPEED_MK6X + if ((u32PrioChannelIDX < u32EndChannelIDX) && + (FTM_CnSC_CHIE_MASK == (FTM_CnSC_CHIE_MASK & ((tstTimerModule*)pvModule)->CONTROLS[u32ChannelIDX].CnSC))) +#else + if ((u32PrioChannelIDX < u32EndChannelIDX) && (true == TEMPHA_boInterruptEnabled(pvModule, u32PrioChannelIDX))) +#endif //TEPM_SPEED_MK6X + { +#ifndef TEPM_SPEED_MK6X + enEHIOResource = TEPMHA_enGetTimerResourceFromVIOAndIndex(enEHVIOResource, u32PrioChannelIDX); + u32TableIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); +#else + u32Temp = 8 * ((uint32)(enEHVIOResource - EH_VIO_FTM0)) + u32PrioChannelIDX; + enEHIOResource = TEPMHA_rastTEPMReverseChannel[u32Temp].enEHIOResource; + u32TableIDX = enEHIOResource - EH_IO_TMR1; +#endif //TEPM_SPEED_MK6X + + if (TRUE == TEPM_aboTEPMChannelModeInput[u32TableIDX]) + { +#if defined (TEPM_REENTRANCY_HW) + if (TRUE == boHWReentrancy) + { + /* Sanity check edge polarity */ + if (IOAPI_enEdgeFalling == CEM_enEdgePolarity) + { + enPrioTriState = TEPM_enGetTimerDigitalState(enEHIOResource); + + /* Invert the polarity because the circuit inverts */ + if (enPrioTriState != enPrioTriStateOld) + { + if (IOAPI_enHigh == enPrioTriState) + { + boHWReentrancyFlag = TRUE; + } + } + + enPrioTriStateOld = enPrioTriState;//move up + } + } +#endif //TEPM_RENTRANCY_HW + + if (FTM_CnSC_CHF_MASK == (FTM_CnSC_CHF_MASK & ((tstTimerModule*)pvModule)->CONTROLS[u32PrioChannelIDX].CnSC)) + { + pfTEPMEventCB = TEPM_atpfEventKernelCB[u32TableIDX]; + +#if defined (TEPM_REENTRANCY) + if (IOAPI_enEdgeFalling == CEM_enEdgePolarity) + { + /* But HW inverted */ + enPrioTriStateOld = IOAPI_enHigh; + enPrioTriState = TEPM_enGetTimerDigitalState(TEPM_PRIO_RESOURCE); + } + else + { + /* But HW inverted */ + enPrioTriStateOld = IOAPI_enLow; + enPrioTriState = TEPM_enGetTimerDigitalState(TEPM_PRIO_RESOURCE); + } + + boHWReentrancy = TRUE; + boHWReentrancyFlag = FALSE; +#endif //TEPM_REENTRANCY + + if (NULL != pfTEPMEventCB) + { +#if defined (TEPM_REENTRANCY) + if (TRUE == TEPM_aboTEPMChannelModeRecursive[u32TableIDX]) + { + + if (0 == TEPM_au32TEPMChannelRecursionCount[u32TableIDX]) + { + /* Let's go again */ + TEMPHA_vResetTimerFlag(pvModule, u32PrioChannelIDX); + TEPM_au32TEPMChannelRecursionCount[u32TableIDX]++; + pfTEPMEventCB(enEHIOResource, TEPMHA_tGetScheduledVal(pvModule, u32PrioChannelIDX, TEPM_aboTEPMChannelModeInput[u32TableIDX], u32Flags)); + } + else + { + TEPM_au32TEPMChannelRecursionCount[u32TableIDX]++; + } + + if (0 != TEPM_au32TEPMChannelRecursionCount[u32TableIDX]) + { + TEPM_au32TEPMChannelRecursionCount[u32TableIDX]--; + } + } + else +#endif //TEPM_REENTRANCY + { +#if defined (TEPM_REENTRANCY_HW) + //boHWReentrancy = FALSE; +#endif //TEPM_REENTRANCY_HW + pfTEPMEventCB(enEHIOResource, TEPMHA_tGetScheduledVal(pvModule, u32PrioChannelIDX, TEPM_aboTEPMChannelModeInput[u32TableIDX], u32Flags)); + } + } + + TEMPHA_vResetTimerFlag(pvModule, u32PrioChannelIDX); + } +#if defined (TEPM_REENTRANCY_HW) + else if (TRUE == boHWReentrancyFlag) + { + pfTEPMEventCB = TEPM_atpfEventKernelCB[u32TableIDX]; + + if (NULL != pfTEPMEventCB) + { + boHWReentrancyFlag = FALSE; + pfTEPMEventCB(enEHIOResource, TEPMHA_tGetScheduledVal(pvModule, u32PrioChannelIDX, TEPM_aboTEPMChannelModeInput[u32TableIDX], u32Flags)); + } + } +#endif //TEPM_REENTRANCY_HW + } + } +#endif //TEPM_PRIO_INPUT_MK6X + } +} + +IOAPI_tenTriState TEPM_enGetTimerDigitalState(IOAPI_tenEHIOResource enEHIOResource) +{ + return TEPMHA_enGetTimerDigitalState(enEHIOResource); +} + +/* Private function definitions + ---------------------------*/ + +#ifdef TEPM_USER_MODE +static void TEPM_vRunEventProgramUserQueue(void* pvModule, uint32 u32ChannelIDX, uint32 u32TableIDX) +{ + TEPMAPI_tstTimedUserEvent* pstTimedEvent; + TEPMAPI_ttEventTime tEventTimeScheduled; + TEPMAPI_ttEventTime tEventTimeRemains; + + if (FALSE == (CQUEUE_xIsEmpty(TEPM_astProgramUserQueue + u32TableIDX))) + { + pstTimedEvent = &TEPM_aastTimedUserEvents[u32TableIDX][TEPM_astProgramUserQueue[u32TableIDX].u32Head]; + + switch (pstTimedEvent->enMethod) + { + case TEPMAPI_enHardAlarm: + { + if (0x7ff0 > pstTimedEvent->tEventTime) + { + tEventTimeScheduled = TEPMHA_u32GetFreeVal(pvModule, u32ChannelIDX) + pstTimedEvent->tEventTime; + tEventTimeRemains = tEventTimeScheduled - TEPMHA_u32GetFreeVal(pvModule, u32ChannelIDX); + if ((0x10 > tEventTimeRemains) || (0x8000 < tEventTimeRemains)) + { + tEventTimeScheduled = TEPMHA_u32GetFreeVal(pvModule, u32ChannelIDX) + 0x80; + } + } + else + { + tEventTimeScheduled = TEPMHA_u32GetFreeVal(pvModule, u32ChannelIDX) + pstTimedEvent->tEventTime; + } + break; + } + case TEPMAPI_enHardLinkedTimeStep: + { + if (0x7ff0 > pstTimedEvent->tEventTime) + { + tEventTimeScheduled = TEPMHA_tGetScheduledVal(pvModule, u32ChannelIDX, FALSE, 0) + pstTimedEvent->tEventTime; + tEventTimeRemains = tEventTimeScheduled - TEPMHA_u32GetFreeVal(pvModule, u32ChannelIDX); + if ((0x10 > tEventTimeRemains) || (0x8000 < tEventTimeRemains)) + { + tEventTimeScheduled = TEPMHA_u32GetFreeVal(pvModule, u32ChannelIDX) + 0x80; + } + } + else + { + tEventTimeScheduled = TEPMHA_tGetScheduledVal(pvModule, u32ChannelIDX, FALSE, 0) + pstTimedEvent->tEventTime; + } + break; + } + default: + { + break; + } + } + + //TEPMHA_vCapComAction(pstTimedEvent->enAction, pvModule, u32ChannelIDX, 0, tEventTimeScheduled); + TEPM_atpfEventUserCB[u32TableIDX] = pstTimedEvent->pfEventCB; + CQUEUE_xRemoveItem(TEPM_astProgramUserQueue + u32TableIDX); + } + else + { +#ifdef TEPM_REMOVE_RESIDUAL_INTERRUPTS + /* The queue is empty therefore this was a next window interrupt + so go ahead and disable interrupts */ + TEPMHA_vDisconnectEnable(pvModule, u32ChannelIDX); +#endif + } +} +#endif //TEPM_USER_MODE + + +void TEPM_vStartEventProgramKernelQueues(bool boAsyncRequest, uint32 u32SequenceIDX) +{ + IOAPI_tenEHIOResource enEHIOResource; + void* pvModule; + uint32 u32ChannelIDX; + uint32 u32SubChannelIDX; + const IOAPI_tenEHIOResource raenResourceList[] = TEPMHA_nChannelResourceList; + uint32 u32TimerChannelIDX; + uint32 u32TableIDX; + static uint32 u32SyncRPMLimit = 6000; + bool boSyncProceed = false; + + if (TRUE == boAsyncRequest) + { + CEM_u32GlobalCycleTime = 0x8000; + } + + for (u32TimerChannelIDX = 0; u32TimerChannelIDX < TEPMHA_nEventChannels; u32TimerChannelIDX++) + { + enEHIOResource = raenResourceList[u32TimerChannelIDX]; + +#ifndef TEPM_SPEED_MK6X + u32TableIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); +#else + u32TableIDX = enEHIOResource - EH_IO_TMR1; +#endif //TEPM_SPEED_MK6X + + if ((TRUE == TEPM_aboTEPMChannelModeOutput[u32TableIDX]) && + (FALSE == TEPM_aboTEPMChannelModePWM[u32TableIDX])) + { + if (0x04 == (TEPM_au32TEPMChannelSequence[u32TableIDX] >> 24)) + { + if ((u32SequenceIDX == (TEPM_au32TEPMChannelSequence[u32TableIDX] & 0x0f)) || + (u32SequenceIDX == ((TEPM_au32TEPMChannelSequence[u32TableIDX] & 0xf0) >> 4)) || + (u32SequenceIDX == ((TEPM_au32TEPMChannelSequence[u32TableIDX] & 0xf00) >> 8)) || + (u32SequenceIDX == ((TEPM_au32TEPMChannelSequence[u32TableIDX] & 0xf000) >> 12))) + { + boSyncProceed = true; + } + } + else if (0x08 == (TEPM_au32TEPMChannelSequence[u32TableIDX] >> 24)) + { + if (u32SequenceIDX == (TEPM_au32TEPMChannelSequence[u32TableIDX] & 0xff)) + { + boSyncProceed = true; + } + } + else + { + if ((u32SequenceIDX == (TEPM_au32TEPMChannelSequence[u32TableIDX] & 0xff)) || + (u32SequenceIDX == ((TEPM_au32TEPMChannelSequence[u32TableIDX] & 0xff00) >> 8))) + { + boSyncProceed = true; + } + } + } + + if (true == boSyncProceed) + { + TEPM_aboSynchroniseEnable[u32TimerChannelIDX] = u32SyncRPMLimit < CAM_u32RPMRaw ? FALSE : TRUE; + + if (((TRUE == TEPM_aboTEPMChannelAsyncRequestEnable[u32TableIDX]) && (TRUE == boAsyncRequest)) || + (FALSE == boAsyncRequest)) + { + //if ((TRUE == CQUEUE_xIsEmpty(TEPM_astProgramKernelQueue + u32TableIDX)) && + // (TRUE == CQUEUE_xIsStaticActive(TEPM_astProgramKernelQueue + u32TableIDX))) + /* EMPTY TEST MAYBE NOT REQUIRED */ + if ((TRUE == CQUEUE_xIsEmpty(TEPM_astProgramKernelQueue + u32TableIDX)) && + (TRUE == CQUEUE_xIsStaticActive(TEPM_astProgramKernelQueue + u32TableIDX)) && + (FALSE == CQUEUE_xIsAtStaticHead(TEPM_astProgramKernelQueue + u32TableIDX))) + { + pvModule = TEPMHA_pvGetModuleFromEnum(TEPM_rastTEPMChannel[u32TableIDX].enModule); + u32ChannelIDX = TEPM_u32GetTimerHardwareChannel(enEHIOResource); + u32SubChannelIDX = TEPMHA_u32GetTimerHardwareSubChannel(u32TableIDX); + + /* Queue didn't end normally last cycle */ + TEPMHA_vForceQueueTerminate(pvModule, u32ChannelIDX, u32SubChannelIDX); + CQUEUE_xResetStaticHead(TEPM_astProgramKernelQueue + u32TableIDX); + //TEPM_aboQueueOverflow[u32TableIDX] = TRUE; + } + + if (FALSE == CQUEUE_xIsEmpty(TEPM_astProgramKernelQueue + u32TableIDX) && + TRUE == CQUEUE_xIsAtStaticHead(TEPM_astProgramKernelQueue + u32TableIDX)) + { + /* This queue is populated and head is at zero (static head) */ + pvModule = TEPMHA_pvGetModuleFromEnum(TEPM_rastTEPMChannel[u32TableIDX].enModule); + u32ChannelIDX = TEPM_u32GetTimerHardwareChannel(enEHIOResource); + + TEPM_vRunEventProgramKernelQueue(pvModule, u32ChannelIDX, u32TableIDX, + u32SequenceIDX, false); + + TEPM_aboQueueOverflow[u32TimerChannelIDX] = FALSE; + } + } + + boSyncProceed = false; + } + } +} + +void TEPM_vGetTimerVal(IOAPI_tenEHIOResource enEHIOResource, puint32 pu32Val) +{ + *pu32Val = TEPMHA_u32GetTimerVal(enEHIOResource); +} + +void TEPM_vSynchroniseEventProgramKernelQueues(void) +{ + IOAPI_tenEHIOResource enEHIOResource; + void* pvModule; + const IOAPI_tenEHIOResource raenResourceList[] = TEPMHA_nChannelResourceList; + uint32 u32ChannelIDX; + uint32 u32TimerChannelIDX; + + for (u32TimerChannelIDX = 0; u32TimerChannelIDX < TEPMHA_nEventChannels; u32TimerChannelIDX++) + { + enEHIOResource = raenResourceList[u32TimerChannelIDX]; + uint32 u32TableIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + + if (FALSE == CQUEUE_xIsEmpty(TEPM_astProgramKernelQueue + u32TableIDX) && + (FALSE == CQUEUE_xIsAtStaticHead(TEPM_astProgramKernelQueue + u32TableIDX)) && + (TRUE == TEPM_aboTEPMChannelModeOutput[u32TableIDX])) + { + /* If not at static head which means queue is done and reset */ + pvModule = TEPMHA_pvGetModuleFromEnum(TEPM_rastTEPMChannel[u32TableIDX].enModule); + u32ChannelIDX = TEPM_u32GetTimerHardwareChannel(enEHIOResource); + + TEPM_vRunEventProgramKernelQueue(pvModule, u32ChannelIDX, u32TableIDX, + TEPM_au32TEPMChannelSequence[u32TableIDX], true); + } + } +} + + +static void TEPM_vRunEventProgramKernelQueue(void* pvModule, uint32 u32ChannelIDX, uint32 u32TableIDX, uint32 u32SequenceIDX, bool boSynchroniseUpdate) +{ + TEPMAPI_tstTimedKernelEvent* pstTimedEvent = NULL; + TEPMAPI_ttEventTime tEventTimeScheduled; + TEPMAPI_ttEventTime tEventTimeRemains; + uint32 u32Temp; + uint32 u32ModulePhaseCorrect = 0; + uint32 u32SubChannelIDX; + volatile bool boSynchroniseAbort = FALSE; + uint32 u32GlobalSequenceFraction; + uint32 u32EventTime; + TEPMAPI_tstTimedKernelEvent stTempKernelEvent; + + /* Mask out the sequence index alternate origin index and windows span */ + u32SequenceIDX &= 0xff; + +#define DEBUG_TEPM_OFF + +#ifdef DEBUG_TEPM + static volatile uint32 test[32]; + static uint32 test_idx; +#endif + + + if (FALSE == CQUEUE_xIsEmpty(TEPM_astProgramKernelQueue + u32TableIDX)) + { + if (TRUE == boSynchroniseUpdate) + { + if (1 == TEPM_astProgramKernelQueue[u32TableIDX].u32Head) + { + /* If waiting for first event, let's look at it */ + pstTimedEvent = &TEPM_aastTimedKernelEvents[u32TableIDX][TEPM_astProgramKernelQueue[u32TableIDX].u32Head - 1]; + + switch (pstTimedEvent->enMethod) + { + case TEPMAPI_enGlobalLinkedFraction: + { + if (FALSE == TEPM_aboSynchroniseEnable[u32TableIDX]) + { + /* Not eligible for a synchronise so abort */ + pstTimedEvent = NULL; + } + break; + } + default: + { + /* Not eligible for a synchronise so abort */ + pstTimedEvent = NULL; + } + } + } + } + else + { + pstTimedEvent = &TEPM_aastTimedKernelEvents[u32TableIDX][TEPM_astProgramKernelQueue[u32TableIDX].u32Head]; + } + + if (NULL != pstTimedEvent) + { + u32SubChannelIDX = TEPMHA_u32GetTimerHardwareSubChannel(u32TableIDX); + + /* Timed event pointer is NULL for a failed synchronise */ + switch (pstTimedEvent->enMethod) + { + case TEPMAPI_enGlobalLinkedFraction: + { +#ifdef DEBUG_TEPM + test[test_idx] = CEM_u32GlobalCycleTime; + test_idx++; + + if (test_idx == 0x20) + { + test_idx = 0; + } +#endif + + u32ModulePhaseCorrect = TEPMHA_u32GetModulePhaseCorrect(TEPMHA_enTimerEnumFromModule(pvModule), u32ChannelIDX); + + if (1 == (TEPM_au32TEPMChannelSequence[u32TableIDX] >> 24)) + { + u32GlobalSequenceFraction = 0xffff & (CEM_u32GlobalCycleFraction - (u32SequenceIDX * 0x10000 / CEM_u32SyncPoints)); + + /* Divide global cycle time by 8 for scale again by phase repeats this might be half global window */ + u32Temp = CEM_u32GlobalCycleTime / (TEPMHA_nCounterGlobalDiv * CEM_u8PhaseRepeats); + } + else if (2 == (TEPM_au32TEPMChannelSequence[u32TableIDX] >> 24)) + { + u32GlobalSequenceFraction = 0xffff & ((CEM_u32GlobalCycleFraction >> 1) - (u32SequenceIDX * 0x8000 / CEM_u32SyncPoints)); + + /* Divide global cycle time by TEPMHA_nCounterGlobalDiv for scale */ + u32Temp = CEM_u32GlobalCycleTime / TEPMHA_nCounterGlobalDiv; + } + else + { + u32GlobalSequenceFraction = 0; + + /* Divide global cycle time by TEPMHA_nCounterGlobalDiv for scale */ + u32Temp = CEM_u32GlobalCycleTime / (2 * TEPMHA_nCounterGlobalDiv * CEM_u8PhaseRepeats); + } + + if (u32GlobalSequenceFraction < *(pstTimedEvent->ptEventTime)) + { + if (((0 == u32GlobalSequenceFraction) && (FALSE == boSynchroniseUpdate)) || (TRUE == boSynchroniseUpdate)) + { + u32Temp *= (*(pstTimedEvent->ptEventTime) - u32GlobalSequenceFraction); + u32Temp = u32Temp / (0x10000 / TEPMHA_nCounterGlobalDiv); + u32Temp = TEPMHA_nLongestDelay < u32Temp ? TEPMHA_nLongestDelay : u32Temp; + + tEventTimeScheduled = CEM_tSyncTimeLast + u32ModulePhaseCorrect + u32Temp; + tEventTimeScheduled &= TEPMHA_nCounterMask; + tEventTimeRemains = tEventTimeScheduled - TEPMHA_u32GetFreeVal(pvModule, u32ChannelIDX); + tEventTimeRemains &= TEPMHA_nCounterMask; + + if (FALSE == boSynchroniseUpdate) + { + if ((TEPM_nSoonCounts > tEventTimeRemains) || ((TEPMHA_nCounterMask - TEPM_nSoonCounts) < tEventTimeRemains)) + //if (TEPM_nSoonCountsLoose > tEventTimeRemains) + { + tEventTimeScheduled = TEPMHA_u32GetFreeVal(pvModule, u32ChannelIDX) + TEPM_nSoonCountsLoose; + tEventTimeScheduled &= TEPMHA_nCounterMask; + } + } + else + { + if ((TEPM_nSoonCounts > tEventTimeRemains) || ((TEPMHA_nCounterMask - TEPM_nSoonCounts) < tEventTimeRemains)) + { + boSynchroniseAbort = TRUE; + } + } + } + else + { + boSynchroniseAbort = TRUE; + } + } + else + { + boSynchroniseAbort = TRUE; + } + + break; + } + case TEPMAPI_enGlobalLinkedTimeStep: + { + u32ModulePhaseCorrect = TEPMHA_u32GetModulePhaseCorrect(TEPMHA_enTimerEnumFromModule(pvModule), u32ChannelIDX); + + if (FALSE == boSynchroniseUpdate) + { + u32Temp = *(pstTimedEvent->ptEventTime); + + tEventTimeScheduled = CEM_tSyncTimeLast + u32ModulePhaseCorrect + u32Temp; + tEventTimeScheduled &= TEPMHA_nCounterMask; + tEventTimeRemains = tEventTimeScheduled - TEPMHA_u32GetFreeVal(pvModule, u32ChannelIDX); + tEventTimeRemains &= TEPMHA_nCounterMask; + + if ((TEPM_nSoonCounts > tEventTimeRemains) || ((TEPMHA_nCounterMask - TEPM_nSoonCounts) < tEventTimeRemains)) + { + tEventTimeScheduled = TEPMHA_u32GetFreeVal(pvModule, u32ChannelIDX) + TEPM_nSoonCounts; + tEventTimeScheduled &= TEPMHA_nCounterMask; + } + } + else + { + boSynchroniseAbort = TRUE; + } + + + break; + } + case TEPMAPI_enGlobalLinkedFractionStep: + { + u32Temp = CEM_u32GlobalCycleTime / 2; + u32Temp *= *(pstTimedEvent->ptEventTime); + u32Temp = MIN(0x7fc00000, u32Temp); + u32Temp /= 0x8000; + tEventTimeScheduled = TEPMHA_tGetScheduledVal(pvModule, u32ChannelIDX, FALSE, 0) + u32Temp; + tEventTimeScheduled &= TEPMHA_nCounterMask; + tEventTimeRemains = tEventTimeScheduled - TEPMHA_u32GetFreeVal(pvModule, u32ChannelIDX); + if ((TEPM_nSoonCounts > tEventTimeRemains) || (-TEPM_nSoonCounts < tEventTimeRemains)) + { + tEventTimeScheduled = TEPMHA_u32GetFreeVal(pvModule, u32ChannelIDX) + TEPM_nSoonCounts; + tEventTimeScheduled &= TEPMHA_nCounterMask; + } + + break; + } + case TEPMAPI_enHardLinkedTimeStep: + { + if (0 != pstTimedEvent->ptAccumulate) + { + if (*(pstTimedEvent->ptEventTime) > (*pstTimedEvent->ptAccumulate - pstTimedEvent->tAccumulate)) + { + u32EventTime = *pstTimedEvent->ptAccumulate - pstTimedEvent->tAccumulate; + memcpy(&stTempKernelEvent, pstTimedEvent, sizeof(stTempKernelEvent)); + pstTimedEvent = &stTempKernelEvent; + pstTimedEvent->enAction = TEPMAPI_enSetLow; + TEPM_astProgramKernelQueue[u32TableIDX].u32Head = TEPM_astProgramKernelQueue[u32TableIDX].u32Tail - 1; + } + else + { + u32EventTime = *(pstTimedEvent->ptEventTime); + } + } + else + { + u32EventTime = *(pstTimedEvent->ptEventTime); + } + + if (-TEPM_nSoonCounts > *(pstTimedEvent->ptEventTime)) + { + tEventTimeScheduled = TEPMHA_tGetScheduledVal(pvModule, u32ChannelIDX, FALSE, 0) + u32EventTime; + tEventTimeScheduled &= TEPMHA_nCounterMask; + tEventTimeRemains = tEventTimeScheduled - TEPMHA_u32GetFreeVal(pvModule, u32ChannelIDX); + if ((TEPM_nSoonCounts > tEventTimeRemains) || (-TEPM_nSoonCounts < tEventTimeRemains)) + { + tEventTimeScheduled = TEPMHA_u32GetFreeVal(pvModule, u32ChannelIDX) + TEPM_nSoonCounts; + tEventTimeScheduled &= TEPMHA_nCounterMask; + } + } + else + { + tEventTimeScheduled = TEPMHA_tGetScheduledVal(pvModule, u32ChannelIDX, FALSE, 0) + u32EventTime; + } + break; + } + default: + { + break; + } + } + + if (FALSE == boSynchroniseAbort) + { + if (FALSE == TEPM_boDisableSequences) + { + if (TEPMAPI_enSetLow == pstTimedEvent->enAction) + { + if (0 != (TEPM_u32FuelCutsMask & MATH_u32IDXToMask(u32TableIDX))) + { + TEPM_u32FuelCutsCounter = (TEPM_u32FuelCutsCounter + 1) % 5; + + if (5 > TEPM_u32FuelCutsPercent) + { + if (TEPM_u32FuelCutsPercent <= TEPM_u32FuelCutsCounter) + { + tEventTimeScheduled = TEPMHA_u32GetFreeVal(pvModule, u32ChannelIDX) + TEPM_nSoonCountsLoose; + tEventTimeScheduled &= TEPMHA_nCounterMask; + } + } + } + } + + TEPMHA_vCapComAction(pstTimedEvent->enAction, pvModule, u32ChannelIDX, u32SubChannelIDX, tEventTimeScheduled); + + if (EH_IO_Invalid != pstTimedEvent->enEHIOBitMirrorResource) + { + if (TEPMAPI_enSetLow == pstTimedEvent->enAction) + { + IO_vAssertDIOResource(pstTimedEvent->enEHIOBitMirrorResource, IOAPI_enHigh); + } + } + } + else + { + TEPMHA_vCapComAction(TEPMAPI_enSetLow, pvModule, u32ChannelIDX, u32SubChannelIDX, tEventTimeScheduled); + } + } + + if (FALSE == boSynchroniseUpdate) + { + TEPM_atpfEventUserCB[u32TableIDX] = pstTimedEvent->pfEventCB; + + if (0 != pstTimedEvent->ptAccumulate) + { + /* Accumulate time into next event */ + pstTimedEvent[1].tAccumulate = pstTimedEvent->tAccumulate + *(pstTimedEvent->ptEventTime); + } + + CQUEUE_xRemoveItem(TEPM_astProgramKernelQueue + u32TableIDX); + } + } + } + else if (FALSE == boSynchroniseUpdate) + { + if (TRUE == CQUEUE_xIsStaticActive(TEPM_astProgramKernelQueue + u32TableIDX)) + { + CQUEUE_xResetStaticHead(TEPM_astProgramKernelQueue + u32TableIDX); + pstTimedEvent = &TEPM_aastTimedKernelEvents[u32TableIDX][0]; + + if (EH_IO_Invalid != pstTimedEvent->enEHIOBitMirrorResource) + { + IO_vAssertDIOResource(pstTimedEvent->enEHIOBitMirrorResource, IOAPI_enLow); + } + } + + /* The queue is empty so go ahead and disable interrupts and connection */ + TEPMHA_vDisconnectEnable(pvModule, u32ChannelIDX); + } +} + +static void* TEPM_pvGetModule(IOAPI_tenEHIOResource enEHIOResource) +{ + uint32 u32ChannelIDX; + void* pvModule; + + u32ChannelIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + pvModule = TEPM_pstGetModuleFromEnum(TEPM_rastTEPMChannel[u32ChannelIDX].enModule); + + return pvModule; +} + +static void* TEPM_pstGetModuleFromEnum(TEPMHA_tenTimerModule enTimerModule) +{ + return TEPMHA_pvGetModuleFromEnum(enTimerModule); +} + +static uint32 TEPM_u32GetTimerHardwareChannel(IOAPI_tenEHIOResource enEHIOResource) +{ + uint32 u32ChannelIDX; + + u32ChannelIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + + return TEPM_rastTEPMChannel[u32ChannelIDX].u32Channel; +} + +uint32 TEPM_u32GetFTMTableIndex(IOAPI_tenEHIOResource enEHIOResource) +{ + return TEPMHA_u32GetFTMTableIndex(enEHIOResource); +} + +uint32 TEPM_u32GetTimerVal(IOAPI_tenEHIOResource enEHIOResource, void* pvData) +{ + return 0; +} + +void TEPM_vSetFuelCutsMask(uint32 u32CutsPercent, uint32 u32CutsMask, uint32 u32ChannelCount) +{ + TEPM_u32FuelCutsPercent = 5 - (u32CutsPercent / 20); + TEPM_u32FuelCutsMask = u32CutsMask; + TEPM_u32FuelChannelCount = u32ChannelCount; +} + +void TEPM_vSetSparkCutsMask(uint32 u32CutsPercent, uint32 u32CutsMask, uint32 u32ChannelCount) +{ + TEPM_u32SparkCutsPercent = 5 - (u32CutsPercent / 20); + TEPM_u32SparkCutsMask = u32CutsMask; + TEPM_u32SparkChannelCount = u32ChannelCount; +} + + + + + diff --git a/source/UserServices/TEPM.h b/source/UserServices/TEPM.h new file mode 100644 index 0000000..08f6305 --- /dev/null +++ b/source/UserServices/TEPM.h @@ -0,0 +1,276 @@ +/******************************************************************************/ +/* TEPM header file */ +/******************************************************************************/ +/* */ +/* Copyright (c) 2013 MD Automotive Controls. All rights reserved. */ +/* */ +/* */ +/* */ +/******************************************************************************/ +#ifndef TEPM_H +#define TEPM_H + +#include "IOAPI.h" +#include "TEPMAPI.h" +#include "SYSAPI.h" +#include "TEPMHA.h" + +#define TEPM_nSoonCounts 80 +#define TEPM_nSoonCountsLoose 250 +#define TEPM_nFarCounts 0xe0000000 + +#define TEPM_SPEED +#define TEPM_SPEED_MK6X +#define TEPM_PRIO_INPUT_MK6X +#define TEPM_REENTRANCY_OFF +#define TEPM_REENTRANCY_HW_OFF + +#ifdef BUILD_SPARKDOG_PF +#define TEPM_PRIO_RESOURCE EH_IO_TMR11 +#endif //BUILD_SPARKDOG_PF + +#ifdef BUILD_SPARKDOG_TEENSY_ADAPT +#define TEPM_PRIO_RESOURCE EH_IO_TMR10 +#endif //BUILD_SPARKDOG_TEENSY_ADAPT + +#ifdef BUILD_MK60 +#define TEPM_nEventChannels 24u +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +#define TEPM_nEventChannels 18u +#endif //BUILD_MK64 + +#define TEPM_nEventsMax 30u +#define TEPM_nMastersMax 1u + + +typedef enum +{ + FTM_enFTM0, + FTM_enFTM1, + FTM_enFTM2, + FTM_enFTM3, + FTM_enFTMModuleCount +} FTM_tenFTMModule; + +#ifdef BUILD_MK60 +#define TEPM_nChannelInfo \ +{ \ + {EH_IO_TMR1, FTM_enFTM0, 7u, 4u}, \ + {EH_IO_TMR2, FTM_enFTM0, 6u, 4u}, \ + {EH_IO_TMR3, FTM_enFTM0, 5u, 4u}, \ + {EH_IO_TMR4, FTM_enFTM0, 4u, 4u}, \ + {EH_IO_TMR5, FTM_enFTM3, 3u, 4u}, \ + {EH_IO_TMR6, FTM_enFTM3, 2u, 4u}, \ + {EH_IO_TMR7, FTM_enFTM3, 1u, 4u}, \ + {EH_IO_TMR8, FTM_enFTM3, 0u, 4u}, \ + {EH_IO_TMR9, FTM_enFTM3, 4u, 6u}, \ + {EH_IO_TMR10, FTM_enFTM3, 5u, 6u}, \ + {EH_IO_TMR11, FTM_enFTM3, 6u, 6u}, \ + {EH_IO_TMR12, FTM_enFTM3, 7u, 6u}, \ + {EH_IO_TMR13, FTM_enFTM0, 3u, 4u}, \ + {EH_IO_TMR14, FTM_enFTM0, 2u, 4u}, \ + {EH_IO_TMR15, FTM_enFTM0, 1u, 4u}, \ + {EH_IO_TMR16, FTM_enFTM0, 0u, 4u}, \ + {EH_IO_ADSE4, FTM_enFTM1, 0u, 6u}, \ + {EH_IO_GPSE9, FTM_enFTM1, 0u, 3u}, \ + {EH_IO_GPSE8, FTM_enFTM1, 1u, 3u}, \ + {EH_IO_ADSE5, FTM_enFTM2, 0u, 6u}, \ + {EH_IO_GPSE7, FTM_enFTM2, 0u, 3u}, \ + {EH_IO_CAN1T, FTM_enFTM2, 0u, 3u}, \ + {EH_IO_CAN1R, FTM_enFTM2, 1u, 3u} \ +} +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +#define TEPM_nChannelInfo \ +{ \ + {EH_IO_TMR1, FTM_enFTM3, 0u, 0u, 3u}, \ + {EH_IO_TMR2, FTM_enFTM0, 0u, 0u, 3u}, \ + {EH_IO_TMR3, FTM_enFTM0, 1u, 0u, 3u}, \ + {EH_IO_TMR4, FTM_enFTM0, 1u, 0u, 3u}, \ + {EH_IO_TMR5, FTM_enFTM3, 4u, 0u, 3u}, \ + {EH_IO_TMR6, FTM_enFTM3, 2u, 0u, 3u}, \ + {EH_IO_TMR7, FTM_enFTM3, 3u, 0u, 3u}, \ + {EH_IO_TMR8, FTM_enFTM0, 2u, 0u, 3u}, \ + {EH_IO_TMR9, FTM_enFTM0, 3u, 0u, 3u}, \ + {EH_IO_TMR10, FTM_enFTM0, 5u, 0u, 3u}, \ + {EH_IO_TMR11, FTM_enFTM0, 6u, 0u, 3u}, \ + {EH_IO_TMR12, FTM_enFTM3, 1u, 0u, 3u}, \ + {EH_IO_TMR13, FTM_enFTM2, 0u, 0u, 3u}, \ + {EH_IO_TMR14, FTM_enFTM2, 1u, 0u, 3u}, \ + {EH_IO_TMR15, FTM_enFTM3, 4u, 0u, 2u}, \ + {EH_IO_TMR16, FTM_enFTM3, 5u, 0u, 2u}, \ + {EH_IO_TMR17, FTM_enFTM3, 6u, 0u, 2u}, \ + {EH_IO_TMR18, FTM_enFTM3, 7u, 0u, 2u}, \ +} +#endif //BUILD_MK60 + +#ifdef BUILD_MK60 +#define TEPM_nChannelFastInfo \ +{ \ + {EH_IO_TMR16}, \ + {EH_IO_TMR15}, \ + {EH_IO_TMR14}, \ + {EH_IO_TMR13}, \ + {EH_IO_TMR4}, \ + {EH_IO_TMR3}, \ + {EH_IO_TMR2}, \ + {EH_IO_TMR1} \ +} +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +#define TEPM_nChannelFastInfo \ +{ \ + {EH_IO_TMR2}, \ + {EH_IO_TMR3}, \ + {EH_IO_TMR8}, \ + {EH_IO_TMR9}, \ + {EH_IO_TMR5}, \ + {EH_IO_TMR10}, \ + {EH_IO_TMR11}, \ + {EH_IO_Invalid}, \ + {EH_IO_Invalid}, \ + {EH_IO_Invalid}, \ + {EH_IO_Invalid}, \ + {EH_IO_Invalid}, \ + {EH_IO_Invalid}, \ + {EH_IO_Invalid}, \ + {EH_IO_Invalid}, \ + {EH_IO_Invalid}, \ + {EH_IO_TMR13}, \ + {EH_IO_TMR14}, \ + {EH_IO_Invalid}, \ + {EH_IO_Invalid}, \ + {EH_IO_Invalid}, \ + {EH_IO_Invalid}, \ + {EH_IO_Invalid}, \ + {EH_IO_Invalid}, \ + {EH_IO_TMR1}, \ + {EH_IO_TMR12}, \ + {EH_IO_TMR6}, \ + {EH_IO_TMR7}, \ + {EH_IO_TMR15}, \ + {EH_IO_TMR16}, \ + {EH_IO_TMR17}, \ + {EH_IO_TMR18}, \ +} +#endif //BUILD_MK64 + +#ifdef BUILD_MK60 +#define TEPM_nMasterInfo \ +{ \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM1}, \ + {EH_VIO_FTM1}, \ + {EH_VIO_FTM1}, \ + {EH_VIO_FTM2}, \ + {EH_VIO_FTM2}, \ + {EH_VIO_FTM2}, \ + {EH_VIO_FTM2} \ +} +#endif + +#ifdef BUILD_MK64 +#define TEPM_nMasterInfo \ +{ \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM2}, \ + {EH_VIO_FTM2}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3} \ +} +#endif + + +#define TEPM_xInitInterrupts(x) \ +if (FTM0 == x){TEPM_vInitInterrupts(FTM0_IRQn);} \ +if (FTM1 == x){TEPM_vInitInterrupts(FTM1_IRQn);} \ +if (FTM2 == x){TEPM_vInitInterrupts(FTM2_IRQn);} \ +if (FTM3 == x){TEPM_vInitInterrupts(FTM3_IRQn);} \ + +typedef struct +{ + IOAPI_tenEHIOResource enEHIOResource; + TEPMAPI_ttEventTime tEventTime; +} TEPM_tstTEPMResult; + +typedef struct +{ + IOAPI_tenEHIOResource enEHIOResource; + TEPMHA_tenTimerModule enModule; + TEPMHA_tenModuleType enModuleType; + uint32 u32Channel; + uint32 u32SubChannel; + uint32 u32MuxSel; + IRQn_Type enIRQType; +} TEPM_tstTEPMChannel; + +typedef struct +{ + TEPMHA_tenTimerModule enModule; + uint32 u32Channel; + IOAPI_tenEHIOResource enEHIOResource; +} TEPM_tstTEPMReverseChannel; + +typedef struct +{ + IOAPI_tenEHIOResource enEHIOResource[TEPMHA_nMastersMax]; +} TEPM_tstMasters; + + +void TEPM_vStart(puint32 const pu32Arg); +void TEPM_vRun(puint32 const pu32Arg); +void TEPM_vAsyncRequest(void); +IOAPI_tenEHIOResource TEPM_enGetPrimaryLinkedResource(void); +void TEMP_vTerminate(puint32 const pu32Arg); +SYSAPI_tenSVCResult TEPM_vInitTEPMResource(IOAPI_tenEHIOResource, TEPMAPI_tstTEPMResourceCB*); +uint32 TEPM_u32InitTEPMChannel(IOAPI_tenEHIOResource, TEPMAPI_tstTEPMChannelCB*, bool boPWMMode); +void TEPM_boGetMasterEHIOResourceList(IOAPI_tenEHIOResource, IOAPI_tenEHIOResource*, puint32); +void TEPM_vAppendTEPMQueue(IOAPI_tenEHIOResource, TEPMAPI_tstTimedUserEvent*, TEPMAPI_ttEventCount); +void TEPM_vConfigureKernelTEPMInput(IOAPI_tenEHIOResource, TEPMAPI_tstTimedKernelEvent*); +void TEPM_vConfigureKernelTEPMOutput(IOAPI_tenEHIOResource, TEPMAPI_tstTimedKernelEvent*, TEPMAPI_ttEventCount); +void TEPM_vConfigureUserTEPMInput(IOAPI_tenEHIOResource, TEPMAPI_tstTimedUserEvent*); +void TEPM_vInitiateUserCallBack(IOAPI_tenEHIOResource, TEPMAPI_ttEventTime); +void TEPM_vGetTimerVal(IOAPI_tenEHIOResource, puint32); +void TEPM_vInterruptHandler(IOAPI_tenEHIOResource, void*); +uint32 TEPM_u32GetFTMTableIndex(IOAPI_tenEHIOResource); +void TEPM_vStartEventProgramKernelQueues(bool, uint32); +void TEPM_vSynchroniseEventProgramKernelQueues(void); +IOAPI_tenTriState TEPM_enGetTimerDigitalState(IOAPI_tenEHIOResource); +void TEPM_vEnableSequences(bool boEnable); +uint32 TEPM_u32GetTimerVal(IOAPI_tenEHIOResource, void*); +void TEPM_vSetFuelCutsMask(uint32, uint32, uint32); +void TEPM_vSetSparkCutsMask(uint32, uint32, uint32); +#endif // TEPM_H + diff --git a/source/UserServices/TEPMHA.c b/source/UserServices/TEPMHA.c new file mode 100644 index 0000000..d8240d9 --- /dev/null +++ b/source/UserServices/TEPMHA.c @@ -0,0 +1,1410 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: TEPM Hardware Abstraction */ +/* DESCRIPTION: Timed Event Programs module provides services for the */ +/* output of timed pulse-trains */ +/* FILE NAME: TEPMHA.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#define _TEPMHA_C + +#include "CPUAbstract.h" +#include +#include "build.h" +#include "CEM.h" +#include "client.h" +#include "CPUAbstract.h" +#include "CQUEUE.h" +#include "declarations.h" +#include "stddef.h" +#include "types.h" +#include "IRQ.h" +#include "TEPM.h" +#include "TEPMHA.h" +#include "TEPMAPI.h" +#include "MSG.h" +#include "SIM.h" +#include "REGSET.h" +#include "RESM.h" +#include "IOAPI.h" +#include "SYSAPI.h" + +//#pragma GCC optimize ("O0") +//#pragma optimize level=0 + + +/* Private data declarations + -------------------------*/ +const TEPM_tstTEPMChannel TEPMHA_rastTEPMChannel[] = TEPMHA_nChannelInfo; +const TEPM_tstTEPMReverseChannel TEPMHA_rastTEPMReverseChannel[] = TEPMHA_nChannelReverseInfo; +TEPMAPI_ttEventTime* TEPMHA_ptMasterClock; + +#define TEPM_nTableCount sizeof(TEPMHA_rastTEPMChannel) / sizeof(TEPM_tstTEPMChannel) + +/* Private function declarations + ----------------------------*/ + +static void* TEPMHA_pvGetModule(IOAPI_tenEHIOResource); + + +#ifdef BUILD_SAM3X8E +static uint32 TEPMHA_pstGetFTMChannel(IOAPI_tenEHIOResource); +static void TEPMHA_vSyncModules(void); +static bool TEPMHA_boModuleIsTimer(void*); +static bool TEPMHA_boModuleIsPWM(void*); +static IOAPI_tenEHIOResource TEPMHA_enGetParentResourceFromVIO(IOAPI_tenEHIOResource); +#endif //BUILD_SAM3X8E + + +static TEPMHA_tenTimerModule TEPMHA_enGetEnumFromVIO(IOAPI_tenEHIOResource); + +/* Public function definitions + ---------------------------*/ + +void TEPMHA_vInitTEPMChannel(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_tstTEPMChannelCB* pstTEPMChannelCB) +{ + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + vpuint32 vpuFTMReg; + uint32 u32ControlWord = 0; + tstTimerModule* pstTimerModule; + uint32 u32ChannelIDX; + uint32 u32TableIDX; + pstTimerModule = TEPMHA_pvGetModule(enEHIOResource); + u32ChannelIDX = TEPMHA_u32GetTimerHardwareChannel(enEHIOResource); + vpuFTMReg = (vpuint32)((uint32)pstTimerModule + (uint32)offsetof(tstTimerModule, CONTROLS[u32ChannelIDX])); + + switch (pstTEPMChannelCB->enAction) + { + case TEPMAPI_enSetHigh: + u32ControlWord |= + (FTM_CnSC_MSA_MASK | FTM_CnSC_ELSB_MASK | FTM_CnSC_ELSA_MASK); break; + case TEPMAPI_enSetLow: + u32ControlWord |= + (FTM_CnSC_MSA_MASK | FTM_CnSC_ELSB_MASK); break; + case TEPMAPI_enToggle: u32ControlWord |= + (FTM_CnSC_MSA_MASK | FTM_CnSC_ELSA_MASK); break; + case TEPMAPI_enCapRising: u32ControlWord |= + (FTM_CnSC_ELSA_MASK); break; + case TEPMAPI_enCapFalling: u32ControlWord |= + (FTM_CnSC_ELSB_MASK); break; + case TEPMAPI_enCapAny: u32ControlWord |= + (FTM_CnSC_ELSB_MASK | FTM_CnSC_ELSA_MASK); break; + default: break; + } + + u32ControlWord = (TRUE == pstTEPMChannelCB->boInterruptEnable) ? + u32ControlWord | FTM_CnSC_CHIE_MASK : u32ControlWord; + + *vpuFTMReg = u32ControlWord; + + u32TableIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + + if (TRUE == pstTEPMChannelCB->boInterruptEnable) + { + IRQ_vEnableIRQ(TEPMHA_rastTEPMChannel[u32TableIDX].enIRQType, IRQ_enPRIO_15, TEPM_vInterruptHandler, NULL); + } + +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + tstTimerModule* pstTimerModule; + vpuint32 vpuFTMReg; + uint32 u32ChannelIDX; + uint32 u32ChannelSubIDX; + uint32 u32ControlWord = 0; + pwm_channel_t stPWMChannelCB; + tstPWMModule* pstPWMModule; + u32ChannelIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + + if (TEPMHA_rastTEPMChannel[u32ChannelIDX].enModuleType == TEPMHA_enCapCom) + { + /* If this resource is associated with a timer module */ + pstTimerModule = (tstTimerModule*)TEPMHA_pvGetModule(enEHIOResource); + + switch (pstTEPMChannelCB->enAction) + { + case TEPMAPI_enSetHigh: + { + u32ControlWord = pstTimerModule->TC_CHANNEL[TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2].TC_CMR; + + if (0 == TEPMHA_rastTEPMChannel[u32ChannelIDX].u32SubChannel) + { + u32ControlWord |= TC_CMR_TCCLKS_TIMER_CLOCK4; + u32ControlWord |= TC_CMR_ACPA_SET; + u32ControlWord |= TC_CMR_WAVE; + tc_init(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, u32ControlWord); + tc_start(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2); + IRQ_vEnableIRQ(TEPMHA_rastTEPMChannel[u32ChannelIDX].enIRQType, IRQ_enPRIO_15, TEPM_vInterruptHandler, NULL); + } + else + { + u32ControlWord |= TC_CMR_TCCLKS_TIMER_CLOCK4; + u32ControlWord |= TC_CMR_BCPB_SET; + u32ControlWord |= TC_CMR_WAVE; + tc_init(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, u32ControlWord); + tc_start(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2); + IRQ_vEnableIRQ(TEPMHA_rastTEPMChannel[u32ChannelIDX].enIRQType, IRQ_enPRIO_15, TEPM_vInterruptHandler, NULL); + } + break; + } + case TEPMAPI_enSetLow: + { + u32ControlWord = pstTimerModule->TC_CHANNEL[TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2].TC_CMR; + + if (0 == TEPMHA_rastTEPMChannel[u32ChannelIDX].u32SubChannel) + { + u32ControlWord |= TC_CMR_TCCLKS_TIMER_CLOCK4; + u32ControlWord |= TC_CMR_WAVE; /* Waveform mode is enabled */ + u32ControlWord |= TC_CMR_ACPA_CLEAR; + tc_init(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, u32ControlWord); + IRQ_vEnableIRQ(TEPMHA_rastTEPMChannel[u32ChannelIDX].enIRQType, IRQ_enPRIO_15, TEPM_vInterruptHandler, NULL); + tc_start(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2); + } + else + { + u32ControlWord |= TC_CMR_TCCLKS_TIMER_CLOCK4; + u32ControlWord |= TC_CMR_WAVE; /* Waveform mode is enabled */ + u32ControlWord |= TC_CMR_BCPB_CLEAR; + u32ControlWord |= TC_CMR_EEVT_XC0; + tc_init(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, u32ControlWord); + //tc_enable_interrupt(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, TC_SR_CPBS); + IRQ_vEnableIRQ(TEPMHA_rastTEPMChannel[u32ChannelIDX].enIRQType, IRQ_enPRIO_15, TEPM_vInterruptHandler, NULL); + tc_start(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2); + } + break; + } + case TEPMAPI_enToggle: u32ControlWord = 0; break; + case TEPMAPI_enCapRising: + { + u32ControlWord = TC_CMR_LDRA_RISING | TC_CMR_LDRB_RISING | TC_CMR_TCCLKS_TIMER_CLOCK4; + tc_init(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, u32ControlWord); + tc_start(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2); + tc_enable_interrupt(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, TC_SR_LDRAS | TC_SR_LDRBS); + IRQ_vEnableIRQ(TEPMHA_rastTEPMChannel[u32ChannelIDX].enIRQType, IRQ_enPRIO_3, TEPM_vInterruptHandler, NULL); + TEPMHA_ptMasterClock = &(pstTimerModule->TC_CHANNEL[u32ChannelIDX].TC_CV); + break; + } + case TEPMAPI_enCapFalling: u32ControlWord = 0; break; + case TEPMAPI_enCapAny://matthew problem here + { + //u32ControlWord = TC_CMR_LDRA_RISING | TC_CMR_LDRB_FALLING | TC_CMR_TCCLKS_TIMER_CLOCK4; + u32ControlWord = TC_CMR_LDRA_EDGE | TC_CMR_LDRB_EDGE | TC_CMR_TCCLKS_TIMER_CLOCK4; + tc_init(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, u32ControlWord); + tc_start(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2); + tc_enable_interrupt(pstTimerModule, TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2, TC_SR_LDRAS | TC_SR_LDRBS); + IRQ_vEnableIRQ(TEPMHA_rastTEPMChannel[u32ChannelIDX].enIRQType, IRQ_enPRIO_3, TEPM_vInterruptHandler, NULL); + TEPMHA_ptMasterClock = &(pstTimerModule->TC_CHANNEL[u32ChannelIDX].TC_CV); + break; + } + default: + { + break; + } + TEPMHA_vSyncModules(); + } + } + else if (TEPMHA_rastTEPMChannel[u32ChannelIDX].enModuleType == TEPMHA_enPWM) + { + /* If this resource is associated with a PWM module */ + pstPWMModule = (tstPWMModule*)TEPMHA_pvGetModule(enEHIOResource); + + memset(&stPWMChannelCB, 0, sizeof(pwm_channel_t)); + + stPWMChannelCB.channel = TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel; + stPWMChannelCB.polarity = PWM_LOW; + //stPWMChannelCB.alignment = PWM_ALIGN_CENTER; + stPWMChannelCB.ul_prescaler = 0x0c;//pstTEPMChannelCB->enPreScalar; + + pwm_channel_init(pstPWMModule, &stPWMChannelCB); + } +#endif //BUILD_SAM3X8E +} + + +SYSAPI_tenSVCResult TEPMHA_vInitTEPMResource(IOAPI_tenEHIOResource enEHIOResource, TEPMAPI_tstTEPMResourceCB* pstTEPMResourceCB) +{ + tstTimerModule* pstTimerModule = NULL; + REGSET_tstReg32Val astTEPMReg32Val[2]; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + switch (enEHIOResource) + { + case EH_VIO_FTM0: + { + pstTimerModule = FTM0; + break; + } + case EH_VIO_FTM1: + { + pstTimerModule = FTM1; + break; + } + case EH_VIO_FTM2: + { + pstTimerModule = FTM2; + break; + } + case EH_VIO_FTM3: + { + pstTimerModule = FTM3; + break; + } + default: + { + pstTimerModule = NULL; + break; + } + } + + TEPMHA_xRequestPortClock(pstTimerModule); + + astTEPMReg32Val[0].reg = (vpuint32)(pstTimerModule + offsetof(tstTimerModule, SC)); + astTEPMReg32Val[0].val = (uint32)(FTM_SC_PS(pstTEPMResourceCB->enPreScalar) | FTM_SC_CLKS(1) | + (pstTEPMResourceCB->enCountType << FTM_SC_CPWMS_SHIFT)); + astTEPMReg32Val[0].writeMode = REGSET_enOverwrite; + astTEPMReg32Val[1].reg = NULL; + REGSET_vInitReg32(&astTEPMReg32Val[0]); +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + tstPWMModule* pstPWMModule = NULL; + pwm_clock_t stPWMClockConfig; + + switch (enEHIOResource) + { + case EH_VIO_TC0: + { + pstTimerModule = TC0; + break; + } + case EH_VIO_TC1: + { + pstTimerModule = TC1; + break; + } + case EH_VIO_TC2: + { + pstTimerModule = TC2; + break; + } + case EH_VIO_PWM: + { + pstPWMModule = PWM; + break; + } + default: + { + break; + } + } + + if (NULL != pstTimerModule) + { + TEPMHA_xRequestTimerClock(pstTimerModule); + } + else if (NULL != pstPWMModule) + { + TEPMHA_xRequestPWMClock(pstPWMModule); + + stPWMClockConfig.ul_mck = SYS_FREQ_BUS; + stPWMClockConfig.ul_clka = SYS_FREQ_BUS / pstTEPMResourceCB->enPreScalar; + stPWMClockConfig.ul_clkb = SYS_FREQ_BUS / pstTEPMResourceCB->enPreScalar; + pwm_init(pstPWMModule, &stPWMClockConfig); + IRQ_vEnableIRQ(PWM_IRQn, IRQ_enPRIO_15, TEPM_vInterruptHandler, NULL); + } +#endif //BUILD_MK60 + + return SYSAPI_enOK; +} + + +void TEPMHA_vForceQueueTerminate(void* pvModule, uint32 u32ChannelIDX, uint32 u32SubChannelIDX) +{ + volatile TEPMAPI_ttEventTime tEventTimeScheduled; + volatile TEPMAPI_ttEventTime tEventTimeRemains; + uint32 u32Temp; + tstTimerModule* pstTimerModule; + + CPU_xEnterCritical(); + +#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10) + pstTimerModule = (tstTimerModule*)pvModule; + u32Temp = pstTimerModule->CONTROLS[u32ChannelIDX].CnSC & ~FTM_CnSC_CHIE_MASK; + u32Temp &= ~FTM_CnSC_CHF_MASK; + + tEventTimeRemains = (0xffff & pstTimerModule->CONTROLS[u32ChannelIDX].CnV) - + (0xffff & pstTimerModule->CNT); + + if (0 < tEventTimeRemains) + { + tEventTimeScheduled = pstTimerModule->CNT + 2; + tEventTimeScheduled &= TEPMHA_nCounterMask; + pstTimerModule->CONTROLS[u32ChannelIDX].CnSC = u32Temp; + + /* Force it now! */ + while (pstTimerModule->CONTROLS[u32ChannelIDX].CnV != tEventTimeScheduled) + { + pstTimerModule->CONTROLS[u32ChannelIDX].CnV = tEventTimeScheduled; + } + + /* Wait for it! Dangerous!!!*/ + //while (pstTimerModule->CONTROLS[u32ChannelIDX].CnV != pstTimerModule->CNT){} + } + else + { + pstTimerModule->CONTROLS[u32ChannelIDX].CnSC = u32Temp; + } +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + volatile u32Stat; + uint32 u32ControlWord; + pstTimerModule = (tstTimerModule*)pvModule; + sint32 s32ExitLoops = 100; + + if (0 == u32SubChannelIDX) + { + TEPMHA_vCapComAction(TEPMAPI_enSetLow, pvModule, u32ChannelIDX, u32SubChannelIDX, tc_read_cv(pstTimerModule, u32ChannelIDX / 2) + 10); + + tc_disable_interrupt(pstTimerModule, u32ChannelIDX / 2, TC_SR_CPAS); + + u32Stat = 0; + + tEventTimeRemains = tc_read_ra(pstTimerModule, u32ChannelIDX / 2) - + tc_read_cv(pstTimerModule, u32ChannelIDX / 2); + + while (0 != (0x80000000 & tEventTimeRemains)) + { + tEventTimeRemains = tc_read_ra(pstTimerModule, u32ChannelIDX / 2) - + tc_read_cv(pstTimerModule, u32ChannelIDX / 2); + } + + while ((0 == (u32Stat & TC_SR_CPAS)) && (0 < s32ExitLoops)) + { + u32Stat = tc_get_status(pstTimerModule, u32ChannelIDX / 2); + s32ExitLoops--; + } + + + /* + u32ControlWord = pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR; + u32ControlWord &= ~TC_CMR_ACPA_TOGGLE; + u32ControlWord |= TC_CMR_ACPA_CLEAR; + pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR = u32ControlWord; + + u32Stat = 0; + tEventTimeRemains = tc_read_ra(pstTimerModule, u32ChannelIDX / 2) - + tc_read_cv(pstTimerModule, u32ChannelIDX / 2); + + * If already past then force again * + if ((UINT32_MAX / 2) < tEventTimeRemains) + { + tEventTimeScheduled = tc_read_cv(pstTimerModule, u32ChannelIDX / 2) + 120; + tc_write_ra(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled); + } + + * If is not too close then reschedule very close * + if (((UINT32_MAX / 2) > tEventTimeRemains) && + (tEventTimeRemains > 50)) + { + tEventTimeScheduled = tc_read_cv(pstTimerModule, u32ChannelIDX / 2) + 120; + tc_write_ra(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled); + } + + while (0 == (u32Stat & TC_SR_CPAS)) + { + u32Stat = tc_get_status(pstTimerModule, u32ChannelIDX / 2); + + tEventTimeRemains = tc_read_ra(pstTimerModule, u32ChannelIDX / 2) - + tc_read_cv(pstTimerModule, u32ChannelIDX / 2); + + if ((UINT32_MAX / 2) < tEventTimeRemains) break; + }*/ + } + else + { + TEPMHA_vCapComAction(TEPMAPI_enSetLow, pvModule, u32ChannelIDX, u32SubChannelIDX, tc_read_cv(pstTimerModule, u32ChannelIDX / 2) + 10); + + tc_disable_interrupt(pstTimerModule, u32ChannelIDX / 2, TC_SR_CPBS); + + u32Stat = 0; + tEventTimeRemains = tc_read_rb(pstTimerModule, u32ChannelIDX / 2) - + tc_read_cv(pstTimerModule, u32ChannelIDX / 2); + + while (0 == (0x80000000 & tEventTimeRemains)) + { + tEventTimeRemains = tc_read_rb(pstTimerModule, u32ChannelIDX / 2) - + tc_read_cv(pstTimerModule, u32ChannelIDX / 2); + } + + while ((0 == (u32Stat & TC_SR_CPBS)) && (0 < s32ExitLoops)) + { + u32Stat = tc_get_status(pstTimerModule, u32ChannelIDX / 2); + s32ExitLoops--; + } + + + /* + u32ControlWord = pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR; + u32ControlWord &= ~TC_CMR_BCPB_TOGGLE; + u32ControlWord |= TC_CMR_BCPB_CLEAR; + pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR = u32ControlWord; + + u32Stat = 0; + tEventTimeRemains = tc_read_rb(pstTimerModule, u32ChannelIDX / 2) - + tc_read_cv(pstTimerModule, u32ChannelIDX / 2); + + * If already past then force again * + if ((UINT32_MAX / 2) < tEventTimeRemains) + { + tEventTimeScheduled = tc_read_cv(pstTimerModule, u32ChannelIDX / 2) + 120; + tc_write_rb(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled); + } + + * If is not too close then reschedule very close * + if (((UINT32_MAX / 2) > tEventTimeRemains) && + (tEventTimeRemains > 50)) + { + tEventTimeScheduled = tc_read_cv(pstTimerModule, u32ChannelIDX / 2) + 120; + tc_write_rb(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled); + } + + while (0 == (u32Stat & TC_SR_CPBS)) + { + u32Stat = tc_get_status(pstTimerModule, u32ChannelIDX / 2); + + tEventTimeRemains = tc_read_rb(pstTimerModule, u32ChannelIDX / 2) - + tc_read_cv(pstTimerModule, u32ChannelIDX / 2); + + if ((UINT32_MAX / 2) < tEventTimeRemains) break; + }*/ + } +#endif //BUILD_SAM3X8E + + CPU_xExitCritical(); +} + +bool TEPMHA_boCheckFalseAlarm(void* pvModule, uint32 u32ChannelIDX, uint32 u32SubChannelIDX) +{ + bool boFalseAlarm = FALSE; + + +#ifdef BUILD_SAM3X8E + uint32 u32Delay; + tstTimerModule* pstTimerModule = (tstTimerModule*)pvModule; + + if (0 == u32SubChannelIDX) + { + u32Delay = tc_read_ra(pstTimerModule, u32ChannelIDX / 2) - + tc_read_cv(pstTimerModule, u32ChannelIDX / 2); + + if ((UINT32_MAX / 2) > u32Delay) + { + boFalseAlarm = TRUE; + } + } + else + { + u32Delay = tc_read_rb(pstTimerModule, u32ChannelIDX / 2) - + tc_read_cv(pstTimerModule, u32ChannelIDX / 2); + + if ((UINT32_MAX / 2) > u32Delay) + { + boFalseAlarm = TRUE; + } + } +#endif + + return boFalseAlarm; +} + + +void TEPMHA_vCapComAction(TEPMAPI_tenAction enAction, void* pvModule, uint32 u32ChannelIDX, uint32 u32SubChannelIDX, TEPMAPI_ttEventTime tEventTimeScheduled) +{ + uint32 u32Temp; + tstTimerModule* pstTimerModule; + + switch (enAction) + { + case TEPMAPI_enSetHigh: + { +#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10) + pstTimerModule = (tstTimerModule*)pvModule; + u32Temp = pstTimerModule->CONTROLS[u32ChannelIDX].CnSC | FTM_CnSC_ELSA_MASK | FTM_CnSC_ELSB_MASK | FTM_CnSC_CHIE_MASK; + u32Temp &= ~FTM_CnSC_CHF_MASK; + pstTimerModule->CONTROLS[u32ChannelIDX].CnSC = u32Temp; + + while (pstTimerModule->CONTROLS[u32ChannelIDX].CnV != tEventTimeScheduled) + { + pstTimerModule->CONTROLS[u32ChannelIDX].CnV = tEventTimeScheduled; + } +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + uint32 u32ControlWord; + + if (TRUE == TEPMHA_boModuleIsTimer(pvModule)) + { + pstTimerModule = (tstTimerModule*)pvModule; + + u32ControlWord = pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR; + + if (0 == u32SubChannelIDX) + { + tc_write_ra(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled); + u32ControlWord &= ~TC_CMR_ACPA_CLEAR; + u32ControlWord |= TC_CMR_ACPA_SET; + pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR = u32ControlWord; + tc_enable_interrupt(pstTimerModule, u32ChannelIDX / 2, TC_SR_CPAS); + //tc_write_ra(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled); + } + else if (1 == u32SubChannelIDX) + { + tc_write_rb(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled); + u32ControlWord &= ~TC_CMR_BCPB_CLEAR; + u32ControlWord |= TC_CMR_BCPB_SET; + pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR = u32ControlWord; + tc_enable_interrupt(pstTimerModule, u32ChannelIDX / 2, TC_SR_CPBS); + //tc_write_rb(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled); + } + } + else if (TRUE == TEPMHA_boModuleIsPWM(pvModule)) + { + tstPWMModule* pstPWMModule; + TEPMAPI_ttEventTime tEventTime; + uint32 u32Temp; + pwm_channel_t stPWMChannel; + + pstPWMModule = (tstPWMModule*)pvModule; + + //u32Temp = pwm_channel_get_status(pstPWMModule); + + tEventTime = tEventTimeScheduled - *TEPMHA_ptMasterClock; + + memset(&stPWMChannel, 0, sizeof(pwm_channel_t)); + stPWMChannel.channel = u32ChannelIDX; + + pwm_channel_enable(pstPWMModule, u32ChannelIDX); + + //pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CPRD = pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CCNT + 2; + + while (pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CCNT > 5) + { + pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CDTY = 1; + pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CPRD = 10; + } + + + pwm_channel_update_period(pstPWMModule, &stPWMChannel, 6000u); + pwm_channel_update_duty(pstPWMModule, &stPWMChannel, 4000u); + //pwm_channel_update_period(pstPWMModule, &stPWMChannel, 5000u); + //pwm_channel_update_duty(pstPWMModule, &stPWMChannel, 2000u); + + //pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CDTY = 5; + //pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CPRD = 10; + //pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CPRD = 5000; + //pstPWMModule->PWM_CH_NUM[u32ChannelIDX].PWM_CDTY = 1000; + + //if (0 == ((1 << u32ChannelIDX) & u32Temp)) + { + + } + } +#endif //BUILD_SAM3X8E + break; + } + case TEPMAPI_enSetLow: + { +#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10) + pstTimerModule = (tstTimerModule*)pvModule; + u32Temp = pstTimerModule->CONTROLS[u32ChannelIDX].CnSC | FTM_CnSC_CHIE_MASK; + u32Temp &= ~FTM_CnSC_CHF_MASK; + u32Temp &= ~(FTM_CnSC_ELSA_MASK); + + pstTimerModule->CONTROLS[u32ChannelIDX].CnSC = u32Temp; + + while (pstTimerModule->CONTROLS[u32ChannelIDX].CnV != tEventTimeScheduled) + { + pstTimerModule->CONTROLS[u32ChannelIDX].CnV = tEventTimeScheduled; + } + //pstTimerModule->CONTROLS[u32ChannelIDX].CnSC = u32Temp; +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + if (TRUE == TEPMHA_boModuleIsTimer(pvModule)) + { + pstTimerModule = (tstTimerModule*)pvModule; + + u32ControlWord = pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR; + + if (0 == u32SubChannelIDX) + { + u32ControlWord &= ~TC_CMR_ACPA_SET; + u32ControlWord |= TC_CMR_ACPA_CLEAR; + pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR = u32ControlWord; + tc_enable_interrupt(pstTimerModule, u32ChannelIDX / 2, TC_SR_CPAS); + tc_write_ra(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled); + } + else if (1 == u32SubChannelIDX) + { + u32ControlWord &= ~TC_CMR_BCPB_SET; + u32ControlWord |= TC_CMR_BCPB_CLEAR; + pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR = u32ControlWord; + tc_enable_interrupt(pstTimerModule, u32ChannelIDX / 2, TC_SR_CPBS); + tc_write_rb(pstTimerModule, u32ChannelIDX / 2, tEventTimeScheduled); + } + } + else if (TRUE == TEPMHA_boModuleIsPWM(pvModule)) + { + + } +#endif //BUILD_SAM3X8E + break; + } + case TEPMAPI_enToggle: + { +#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10) + pstTimerModule = (tstTimerModule*)pvModule; + pstTimerModule->CONTROLS[u32ChannelIDX].CnSC |= (FTM_CnSC_ELSA_MASK | FTM_CnSC_CHIE_MASK); + pstTimerModule->CONTROLS[u32ChannelIDX].CnSC &= ~FTM_CnSC_ELSB_MASK; + pstTimerModule->CONTROLS[u32ChannelIDX].CnV = tEventTimeScheduled; +#endif //BUILD_MK6X + break; + } + case TEPMAPI_enEndProgram: + { +#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10) + pstTimerModule = (tstTimerModule*)pvModule; + pstTimerModule->CONTROLS[u32ChannelIDX].CnSC = pstTimerModule->CONTROLS[u32ChannelIDX].CnSC; + pstTimerModule->CONTROLS[u32ChannelIDX].CnV = tEventTimeScheduled; +#endif //BUILD_MK6X + break; + } + default: + { + break; + } + } +} + + +static void* TEPMHA_pvGetModule(IOAPI_tenEHIOResource enEHIOResource) +{ + uint32 u32ChannelIDX; + void* pvModule; + + u32ChannelIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + pvModule = TEPMHA_pvGetModuleFromEnum(TEPMHA_rastTEPMChannel[u32ChannelIDX].enModule); + + return pvModule; +} + + +void* TEPMHA_pvGetModuleFromEnum(TEPMHA_tenTimerModule enTimerModule) +{ + void* pvModule; + +#ifdef BUILD_MK60 + switch (enTimerModule) + { + case FTM_enFTM0: pvModule = (tstTimerModule*)FTM0; break; + case FTM_enFTM1: pvModule = (tstTimerModule*)FTM1; break; + case FTM_enFTM2: pvModule = (tstTimerModule*)FTM2; break; + case FTM_enFTM3: pvModule = (tstTimerModule*)FTM3; break; + default: pvModule = NULL; break; + } +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 + switch (enTimerModule) + { + case FTM_enFTM0: pvModule = (tstTimerModule*)FTM0; break; + case FTM_enFTM1: pvModule = (tstTimerModule*)FTM1; break; + case FTM_enFTM2: pvModule = (tstTimerModule*)FTM2; break; + case FTM_enFTM3: pvModule = (tstTimerModule*)FTM3; break; + default: pvModule = NULL; break; + } +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E + switch (enTimerModule) + { + case TEPMHA_enTC0: pvModule = (void*)TC0; break; + case TEPMHA_enTC1: pvModule = (void*)TC1; break; + case TEPMHA_enTC2: pvModule = (void*)TC2; break; + case TEPMHA_enPWM0: pvModule = (void*)PWM; break; + default: pvModule = NULL; break; + } +#endif //BUILD_SAMX3X8E + + return pvModule; +} + +uint32 TEPMHA_u32GetFTMTableIndex(IOAPI_tenEHIOResource enEHIOResource) +{ + uint32 u32TableIDX = 0; + +#ifdef BUILD_MK60 + if ((EH_IO_TMR16 >= enEHIOResource) && (EH_IO_TMR1 <= enEHIOResource)) + { + u32ChannelIDX = enEHIOResource - EH_IO_TMR1; + } + else + { + switch (enEHIOResource) + { + case EH_IO_ADSE4: u32ChannelIDX = 16; break; + case EH_IO_GPSE9: u32ChannelIDX = 16; break; + case EH_IO_GPSE8: u32ChannelIDX = 16; break; + case EH_IO_ADSE5: u32ChannelIDX = 16; break; + case EH_IO_GPSE7: u32ChannelIDX = 16; break; + case EH_IO_CAN1T: u32ChannelIDX = 16; break; + case EH_IO_CAN1R: u32ChannelIDX = 16; break; + } + } +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 + if ((EH_IO_TMR18 >= enEHIOResource) && (EH_IO_TMR1 <= enEHIOResource)) + { + u32TableIDX = enEHIOResource - EH_IO_TMR1; + } + else + { + u32TableIDX = ~0; + } +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E + if ((EH_IO_TMR12 >= enEHIOResource) && (EH_IO_TMR1 <= enEHIOResource)) + { + u32ChannelIDX = enEHIOResource - EH_IO_TMR1; + } + else if (EH_IO_ADD5 == enEHIOResource) + { + u32ChannelIDX = 12; + } + else if (EH_IO_ADD7 == enEHIOResource) + { + u32ChannelIDX = 13; + } + else if (EH_IO_ADD8 == enEHIOResource) + { + u32ChannelIDX = 14; + } + else if (EH_IO_EXTINT == enEHIOResource) + { + u32ChannelIDX = 15; + } +#endif //BUILD_SAM3X8E + + return u32TableIDX; +} + + + +bool TEPMHA_boFlagIsSet(void* pvModule, uint32 u32ChannelIDX, puint32 pu32Flags, uint32 u32Sequence, uint32 u32Prio) +{ + bool boFlagIsSet = false; + tstTimerModule* pstTimerModule; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10) + pstTimerModule = (tstTimerModule*)pvModule; + boFlagIsSet = (FTM_CnSC_CHF_MASK == (FTM_CnSC_CHF_MASK & pstTimerModule->CONTROLS[u32ChannelIDX].CnSC)); +#endif //BUILD_MK60 + +#ifdef BUILD_SAM3X8E + static uint32 u32Seq[2]; + static uint32 u32FlagsCache[9]; /* Once the flags are read they are cleared so cache them */ + uint32 u32CacheIndex = 0; + uint32 u32CMR; + bool boWaveMode; + tstPWMModule* pstPWMModule; + + if ((TC0 == (tstTimerModule*)pvModule) || + (TC1 == (tstTimerModule*)pvModule) || + (TC2 == (tstTimerModule*)pvModule)) + { + pstTimerModule = (tstTimerModule*)pvModule; + + switch ((uint32)pstTimerModule) + { + case (uint32)TC0: u32CacheIndex = (u32ChannelIDX / 2); break; + case (uint32)TC1: u32CacheIndex = 3 + (u32ChannelIDX / 2); break; + case (uint32)TC2: u32CacheIndex = 6 + (u32ChannelIDX / 2); break; + } + + if (u32Seq[u32Prio] != u32Sequence) + { + u32FlagsCache[u32CacheIndex] = pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_SR; + u32Seq[u32Prio] = u32Sequence; + } + + u32CMR = pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_CMR; + + if (0 == u32FlagsCache[u32CacheIndex]) + { + u32FlagsCache[u32CacheIndex] = pstTimerModule->TC_CHANNEL[u32ChannelIDX / 2].TC_SR; + } + + *pu32Flags = u32FlagsCache[u32CacheIndex]; + boWaveMode = TC_CMR_WAVE == (u32CMR & TC_CMR_WAVE) ? TRUE : FALSE; + + if (0 == (u32ChannelIDX & 0x1)) + { + /* Is channel A? */ + if (FALSE == boWaveMode) + { + boFlagIsSet = 0 != (*pu32Flags & (TC_SR_LDRAS | TC_SR_LDRBS)) ? + TRUE : FALSE; + } + else + { + boFlagIsSet = 0 != (*pu32Flags & TC_IMR_CPAS) ? TRUE : FALSE; + } + } + else + { + /* Is channel B? */ + if (FALSE == boWaveMode) + { + /* There is no input capture on the physical B channel */ + boFlagIsSet = FALSE; + } + else + { + boFlagIsSet = 0 != (*pu32Flags & TC_IMR_CPBS) ? TRUE : FALSE; + } + } + } + else if (PWM == (tstPWMModule*)pvModule) + { + boFlagIsSet = TRUE; + } +#endif //BUILD_SAM3X8E + + return boFlagIsSet; +} + +bool TEMPHA_boInterruptEnabled(void* pvModule, uint32 u32ChannelIDX) +{ + bool boEnableSet = false; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10) + boEnableSet = (FTM_CnSC_CHIE_MASK == (FTM_CnSC_CHIE_MASK & ((tstTimerModule*)pvModule)->CONTROLS[u32ChannelIDX].CnSC)); +#endif + +#ifdef BUILD_SAM3X8E + if (TRUE == TEPMHA_boModuleIsTimer(pvModule)) + { + tstTimerModule* pstModule = (tstTimerModule*)pvModule; + if (0 == (u32ChannelIDX & 0x01)) + { + boEnableSet = 0 != (pstModule->TC_CHANNEL[u32ChannelIDX / 2].TC_IMR & (TC_IMR_LDRAS | TC_IMR_CPAS)) ? + TRUE : FALSE; + } + else + { + boEnableSet = 0 != (pstModule->TC_CHANNEL[u32ChannelIDX / 2].TC_IMR & (TC_IMR_LDRBS | TC_IMR_CPBS)) ? + TRUE : FALSE; + } + } + else if (TRUE == TEPMHA_boModuleIsPWM(pvModule)) + { + + } +#endif //BUILD_SAM3X8E + + return boEnableSet; +} + +TEPMAPI_ttEventTime TEPMHA_tGetScheduledVal(void* pvModule, uint32 u32ChannelIDX, bool boInputMode, uint32 u32Flags) +{ + TEPMAPI_ttEventTime tEventTime = 0; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + tEventTime = ((tstTimerModule*)pvModule)->CONTROLS[u32ChannelIDX].CnV; +#endif + +#ifdef BUILD_SAM3X8E + if (TRUE == TEPMHA_boModuleIsTimer(pvModule)) + { + if (TRUE == boInputMode) + { + if (0 != (u32Flags & TC_SR_LDRAS)) + { + tEventTime = tc_read_ra((tstTimerModule*)pvModule, u32ChannelIDX / 2); + } + if (0 != (u32Flags & TC_SR_LDRBS)) + { + tEventTime = tc_read_rb((tstTimerModule*)pvModule, u32ChannelIDX / 2); + } + } + else + { + if (0 == (u32ChannelIDX & 0x01)) + { + tEventTime = tc_read_ra((tstTimerModule*)pvModule, u32ChannelIDX / 2); + } + else + { + tEventTime = tc_read_rb((tstTimerModule*)pvModule, u32ChannelIDX / 2); + } + } + } + else if (TRUE == TEPMHA_boModuleIsPWM(pvModule)) + { + + } +#endif //BUILD_SAM3X8E + + + return tEventTime; +} + +IOAPI_tenTriState TEPMHA_enGetTimerDigitalState(IOAPI_tenEHIOResource enEHIOResource) +{ + IOAPI_tenTriState enTriState = IOAPI_enError; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(MK10) + enTriState = IO_enGetDIOResourceState(enEHIOResource); +#endif + +#ifdef BUILD_SAM3X8E + uint32 u32ChannelIDX; + void* pvModule; + u32ChannelIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + pvModule = TEPMHA_pvGetModuleFromEnum(TEPMHA_rastTEPMChannel[u32ChannelIDX].enModule); + + if (((EH_IO_TMR1 <= enEHIOResource) && (EH_IO_TMR12 >= enEHIOResource)) || + (EH_IO_ADD5 == enEHIOResource) || + (EH_IO_EXTINT == enEHIOResource) || + (EH_IO_ADD6 == enEHIOResource) || + (EH_IO_ADD7 == enEHIOResource)) + { + if (TRUE == TEPMHA_boModuleIsTimer(pvModule)) + { + tstTimerModule* pstModule = (tstTimerModule*)pvModule; + if (0 == TEPMHA_rastTEPMChannel[u32ChannelIDX].u32SubChannel) + { + enTriState = 0 != (pstModule->TC_CHANNEL[TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2].TC_SR & TC_SR_MTIOA) ? + IOAPI_enHigh : IOAPI_enLow; + } + else + { + enTriState = 0 != (pstModule->TC_CHANNEL[TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel / 2].TC_SR & TC_SR_MTIOB) ? + IOAPI_enHigh : IOAPI_enLow; + } + } + } +#endif + + return enTriState; +} + +void TEMPHA_vResetTimerFlag(void* pvModule, uint32 u32ChannelIDX) +{ +#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10) + ((tstTimerModule*)pvModule)->CONTROLS[u32ChannelIDX].CnSC &= ~FTM_CnSC_CHF_MASK; +#endif +} + + +uint32 TEPMHA_u32GetFreeVal(void* pvModule, uint32 u32ChannelIDX) +{ + uint32 u32FreeVal; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10) + u32FreeVal = ((tstTimerModule*)pvModule)->CNT; +#endif + +#ifdef BUILD_SAM3X8E + if (TRUE == TEPMHA_boModuleIsTimer(pvModule)) + { + u32FreeVal = ((tstTimerModule*)pvModule)->TC_CHANNEL[u32ChannelIDX / 2].TC_CV; + } +#endif + + return u32FreeVal; +} + +void TEPMHA_vDisconnectEnable(void* pvModule, uint32 u32ChannelIDX) +{ + uint32 u32Temp; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10) + u32Temp = ((tstTimerModule*)pvModule)->CONTROLS[u32ChannelIDX].CnSC; + u32Temp &= ~FTM_CnSC_CHIE_MASK; + ((tstTimerModule*)pvModule)->CONTROLS[u32ChannelIDX].CnSC = u32Temp; +#endif //BUILD_MK6X +} + +TEPMAPI_ttEventTime TEPMHA_u32GetTimerVal(IOAPI_tenEHIOResource enEHIOResource) +{ + tstTimerModule* pstTimerModule; + TEPMAPI_ttEventTime tEventTime = 0; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10) + uint32 u32TableIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + pstTimerModule = (tstTimerModule*)TEPMHA_pvGetModuleFromEnum(TEPMHA_rastTEPMChannel[u32TableIDX].enModule); + tEventTime = pstTimerModule->CONTROLS[TEPMHA_rastTEPMChannel[u32TableIDX].u32Channel].CnSC; +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + pstTimerModule = TEPMHA_pvGetTimerModuleFromVIO(enEHIOResource); + tEventTime = pstTimerModule->TC_CHANNEL[0].TC_CV; +#endif //BUILD_SAM3X8E + + return tEventTime; +} + +void* TEPMHA_pvGetTimerModuleFromVIO(IOAPI_tenEHIOResource enEHIOResource) +{ + void* pvModule; + + switch(enEHIOResource) + { +#if defined(BUILD_MK60) || defined(BUILD_MK64) + case EH_VIO_FTM0: pvModule = (tstTimerModule*)FTM0; break; + case EH_VIO_FTM1: pvModule = (tstTimerModule*)FTM1; break; + case EH_VIO_FTM2: pvModule = (tstTimerModule*)FTM2; break; + case EH_VIO_FTM3: pvModule = (tstTimerModule*)FTM3; break; +#endif //BUILD_MK60X + +#ifdef BUILD_SAM3X8E + case EH_VIO_TC0: pvModule = (tstTimerModule*)TC0; break; + case EH_VIO_TC1: pvModule = (tstTimerModule*)TC1; break; + case EH_VIO_TC2: pvModule = (tstTimerModule*)TC2; break; + case EH_VIO_TCC0: pvModule = (tstTimerModule*)TC0; break; + case EH_VIO_TCC1: pvModule = (tstTimerModule*)TC0; break; + case EH_VIO_TCC2: pvModule = (tstTimerModule*)TC0; break; + case EH_VIO_TCC3: pvModule = (tstTimerModule*)TC1; break; + case EH_VIO_TCC4: pvModule = (tstTimerModule*)TC1; break; + case EH_VIO_TCC5: pvModule = (tstTimerModule*)TC1; break; + case EH_VIO_TCC6: pvModule = (tstTimerModule*)TC2; break; + case EH_VIO_TCC7: pvModule = (tstTimerModule*)TC2; break; + case EH_VIO_TCC8: pvModule = (tstTimerModule*)TC2; break; + case EH_VIO_PWM: pvModule = (tstPWMModule*)PWM; break; +#endif + default: pvModule = NULL; break; + } + + return pvModule; +} + +#ifdef BUILD_SAM3X8E +static uint32 TEPMHA_pstGetFTMChannel(IOAPI_tenEHIOResource enEHIOResource) +{ + uint32 u32ChannelIDX; + + u32ChannelIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + return TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel; +} +#endif //BUILD_SAM3X8E + +uint32 TEPMHA_u32GetTimerChannelsPerInterruptGroup(void* pvModule) +{ + uint32 u32ChannelCount = 0; +#if defined(BUILD_MK60) + u32ChannelCount = 8; +#endif //BUILD_MK60 + +#if defined(BUILD_MK64) + if (FTM0 == pvModule) u32ChannelCount = 8; + if (FTM1 == pvModule) u32ChannelCount = 8; + if (FTM2 == pvModule) u32ChannelCount = 2; + if (FTM3 == pvModule) u32ChannelCount = 8; +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E + u32ChannelCount = 2; +#endif //BUILD_SAM3X8E + + return u32ChannelCount; +} + +IOAPI_tenEHIOResource TEPMHA_enGetTimerResourceFromVIOAndIndex(IOAPI_tenEHIOResource enEHIOResource, uint32 u32Channel) +{ + IOAPI_tenEHIOResource enChannelEHIOResource = EH_IO_Invalid; + uint32 u32Temp; + +#if defined(BUILD_MK60) + TEPMHA_tenTimerModule enModule = TEPMHA_enGetEnumFromVIO(enEHIOResource); + + for (u32ChannelIDX = 0; u32ChannelIDX < TEPMHA_nEventChannels; u32ChannelIDX++) + { + if ((enModule == TEPMHA_rastTEPMChannel[u32ChannelIDX].enModule) && + u32Channel == TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel && + (TEPMHA_enCapCom == TEPMHA_rastTEPMChannel[u32ChannelIDX].enModuleType)) + { + enChannelEHIOResource = TEPMHA_rastTEPMChannel[u32ChannelIDX].enEHIOResource; + break; + } + } +#endif + + +#if defined (BUILD_MK64) + u32Temp = 8 * TEPMHA_enGetEnumFromVIO(enEHIOResource) + u32Channel; + enChannelEHIOResource = TEPMHA_rastTEPMReverseChannel[u32Temp].enEHIOResource; +#endif + + +#ifdef BUILD_SAM3X8E + uint32 u32ChannelIDX; + TEPMHA_tenTimerModule enModule = TEPMHA_enGetEnumFromVIO(enEHIOResource); + + for (u32ChannelIDX = 0; u32ChannelIDX < TEPMHA_nEventChannels; u32ChannelIDX++) + { + if ((enModule == TEPMHA_rastTEPMChannel[u32ChannelIDX].enModule) && + (u32Channel == TEPMHA_rastTEPMChannel[u32ChannelIDX].u32Channel + TEPMHA_rastTEPMChannel[u32ChannelIDX].u32SubChannel) && + (TEPMHA_enCapCom == TEPMHA_rastTEPMChannel[u32ChannelIDX].enModuleType)) + { + enChannelEHIOResource = TEPMHA_rastTEPMChannel[u32ChannelIDX].enEHIOResource; + break; + } + } +#endif //BUILD_SAM3X8E + return enChannelEHIOResource; +} + + +#ifdef BUILD_SAM3X8E +static IOAPI_tenEHIOResource TEPMHA_enGetParentResourceFromVIO(IOAPI_tenEHIOResource enEHIOResource) +{ + IOAPI_tenEHIOResource enParentVIOResource = EH_IO_Invalid; + + switch (enEHIOResource) + { + case EH_VIO_TCC0: enParentVIOResource = EH_VIO_TC0; break; + case EH_VIO_TCC1: enParentVIOResource = EH_VIO_TC0; break; + case EH_VIO_TCC2: enParentVIOResource = EH_VIO_TC0; break; + case EH_VIO_TCC3: enParentVIOResource = EH_VIO_TC1; break; + case EH_VIO_TCC4: enParentVIOResource = EH_VIO_TC1; break; + case EH_VIO_TCC5: enParentVIOResource = EH_VIO_TC1; break; + case EH_VIO_TCC6: enParentVIOResource = EH_VIO_TC2; break; + case EH_VIO_TCC7: enParentVIOResource = EH_VIO_TC2; break; + case EH_VIO_TCC8: enParentVIOResource = EH_VIO_TC2; break; + default : enParentVIOResource = EH_IO_Invalid; break; + } + + return enParentVIOResource; +} +#endif //BUILD_SAM3X8E + +uint32 TEPMHA_u32GetTimerStartChannelInterruptGroup(IOAPI_tenEHIOResource enEHIOResource) +{ + uint32 u32StartChannel; + +#ifdef BUILD_SAM3X8E + switch (enEHIOResource) + { + case EH_VIO_TCC0: u32StartChannel = 0; break; + case EH_VIO_TCC1: u32StartChannel = 2; break; + case EH_VIO_TCC2: u32StartChannel = 4; break; + case EH_VIO_TCC3: u32StartChannel = 0; break; + case EH_VIO_TCC4: u32StartChannel = 2; break; + case EH_VIO_TCC5: u32StartChannel = 4; break; + case EH_VIO_TCC6: u32StartChannel = 0; break; + case EH_VIO_TCC7: u32StartChannel = 2; break; + case EH_VIO_TCC8: u32StartChannel = 4; break; + default : u32StartChannel = 0; break; + } +#endif //BUILD_SAM3X8E + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + u32StartChannel = 0; +#endif + + return u32StartChannel; +} + +uint32 TEPMHA_u32GetTimerHardwareSubChannel(uint32 u32TableIndex) +{ + uint32 u32ChannelSubIDX = 0; + +#ifdef BUILD_SAM3X8E + u32ChannelSubIDX = TEPMHA_rastTEPMChannel[u32TableIndex].u32SubChannel; +#endif //BUILD_SAM3X8E + + return u32ChannelSubIDX; +} + +uint32 TEPMHA_u32GetTimerHardwareChannel(IOAPI_tenEHIOResource enEHIOResource) +{ +#if defined(BUILD_MK64) || defined(BUILD_MK60) + uint32 u32ChannelIDX = 0; + uint32 u32TableIDX = 0; + + u32TableIDX = TEPMHA_u32GetFTMTableIndex(enEHIOResource); + u32ChannelIDX = TEPMHA_rastTEPMChannel[u32TableIDX].u32Channel; + + return u32ChannelIDX; +#endif //BUILD_MK6X +} + + +TEPMHA_tenTimerModule TEPMHA_enTimerEnumFromModule(tstTimerModule* pstTimerModule) +{ +#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10) + TEPMHA_tenTimerModule enTimerModule = TEPMHA_enFTM0; + + if (FTM1 == pstTimerModule) enTimerModule = TEPMHA_enFTM1; + if (FTM2 == pstTimerModule) enTimerModule = TEPMHA_enFTM2; + if (FTM3 == pstTimerModule) enTimerModule = TEPMHA_enFTM3; +#endif + +#ifdef BUILD_SAM3X8E + TEPMHA_tenTimerModule enTimerModule = TEPMHA_enTC0; + + if (TC0 == pstTimerModule) + { + enTimerModule = TEPMHA_enTC0; + } + else if (TC1 == pstTimerModule) + { + enTimerModule = TEPMHA_enTC1; + } + else if (TC2 == pstTimerModule) + { + enTimerModule = TEPMHA_enTC2; + } +#endif //BUILD_SAM3X8E + + return enTimerModule; +} + + +#ifdef BUILD_SAM3X8E +static void TEPMHA_vSyncModules(void) +{ + tc_sync_trigger((tstTimerModule*)TC0); + tc_sync_trigger((tstTimerModule*)TC1); + tc_sync_trigger((tstTimerModule*)TC2); +} +#endif //BUILD_SAM3X8E + + +#ifdef BUILD_SAM3X8E +static bool TEPMHA_boModuleIsTimer(void* pvModule) +{ + bool boRetVal = FALSE; + + + if ((TC0 == (tstTimerModule*)pvModule) || + (TC1 == (tstTimerModule*)pvModule) || + (TC2 == (tstTimerModule*)pvModule)) + { + boRetVal = TRUE; + } + + return boRetVal; +} +#endif //BUILD_SAM3X8E + +static TEPMHA_tenTimerModule TEPMHA_enGetEnumFromVIO(IOAPI_tenEHIOResource enEHIOResource) +{ + TEPMHA_tenTimerModule enModule; +#ifdef BUILD_SAM3X8E + switch (enEHIOResource) + { + case EH_VIO_TC0: + case EH_VIO_TCC0: + case EH_VIO_TCC1: + case EH_VIO_TCC2: + { + enModule = TEPMHA_enTC0; + break; + } + case EH_VIO_TC1: + case EH_VIO_TCC3: + case EH_VIO_TCC4: + case EH_VIO_TCC5: + { + enModule = TEPMHA_enTC1; + break; + } + case EH_VIO_TC2: + case EH_VIO_TCC6: + case EH_VIO_TCC7: + case EH_VIO_TCC8: + { + enModule = TEPMHA_enTC2; + break; + } + case EH_VIO_PWM: + { + + enModule = TEPMHA_enPWM0; + break; + } + default: + { + enModule = TEPMHA_enModuleInvalid; + break; + } + } +#endif //BUILD_SAM3X8E + +#if defined(BUILD_MK60) || defined(BUILD_MK64) + enModule = (uint32)(enEHIOResource - EH_VIO_FTM0); +#endif //BUILD_MK6X + + return enModule; +} +#ifdef BUILD_SAM3X8E +static bool TEPMHA_boModuleIsPWM(void* pvModule) +{ + bool boRetVal = FALSE; + + + if (PWM == (tstPWMModule*)pvModule) + { + boRetVal = TRUE; + } + return boRetVal; +} +#endif //BUILD_SAM3X8E +uint32 TEPMHA_u32GetModulePhaseCorrect(TEPMHA_tenTimerModule enTimerModule, uint32 u32ChannelIDX) +{ + uint32 u32PhaseCorrect = 0; + +#if defined(BUILD_MK60) || defined(BUILD_MK64) || defined(BUILD_MK10) + switch (enTimerModule) + { + case TEPMHA_enFTM0: + { + u32PhaseCorrect = FTM0->CNT - FTM3->CNT; + break; + } + case TEPMHA_enFTM1: + { + u32PhaseCorrect = FTM1->CNT - FTM3->CNT; + break; + } + case TEPMHA_enFTM2: + { + u32PhaseCorrect = FTM2->CNT - FTM3->CNT; + break; + } + default: + { + u32PhaseCorrect = 0; + break; + } + } +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E + (uint32)CEM_ttGetModulePhase(3 * enTimerEnumModule + u32ChannelIDX / 2); +#endif + + return u32PhaseCorrect; +} + +//#pragma GCC optimize ("O1") diff --git a/source/UserServices/TEPMHA.h b/source/UserServices/TEPMHA.h new file mode 100644 index 0000000..0d98e0d --- /dev/null +++ b/source/UserServices/TEPMHA.h @@ -0,0 +1,538 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef TEPMHA_H +#define TEPMHA_H + +#include "build.h" +#include "IOAPI.h" +#include "TEPMAPI.h" +#include "SYSAPI.h" +#include "CEM.h" + +#ifdef BUILD_SAM3X8E +#include "tc.h" +#include "pwm.h" +#endif //BUILD_SAM3X8E + +#ifdef BUILD_MK60 +#define TEPMHA_nEventChannels 16u +typedef FTM_Type tstTimerModule; +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +#include "mk64f12.h" +#define TEPMHA_nEventChannels 18u +typedef FTM_Type tstTimerModule; +#define TEPMHA_nCounterMask 0xffff +#define TEPMHA_nLongestDelay 0xfe00 +#define TEPMHA_nCounterGlobalDiv 4 + +#ifdef BUILD_SPARKDOG_PF +#define TEPMHA_nPRIOCHANNEL 5 +#endif //BUILD_SPARKDOG_PF + +#ifdef BUILD_SPARKDOG_TEENSY_ADAPT +#define TEPMHA_nPRIOCHANNEL 4 +#endif //BUILD_SPARKDOG_TEENSY_ADAPT + +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +#define TEPMHA_nEventChannels 16u +typedef Tc tstTimerModule; +typedef Pwm tstPWMModule; +#define TEPMHA_nCounterMask 0xffffffff +#define TEPMHA_nCounterGlobalDiv 8 +#endif //BUILD_SAM3X8E + + +#define TEPMHA_nUserEventsMax 4u +#define TEPMHA_nKernelEventsMax 100u +#define TEPMHA_nMastersMax 1u + + +#ifdef _TEPMHA_C +#define EXTERN +#else +#define EXTERN extern +#endif + +EXTERN uint32 TEPMHA_u32PortClockRequested; + + +#ifdef BUILD_MK60 +typedef enum +{ + TEPMHA_enFTM0, + TEPMHA_enFTM1, + TEPMHA_enFTM2, + TEPMHA_enFTM3, + TEPMHA_enTimerModuleCount +} TEPMHA_tenTimerModule; +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +typedef enum +{ + TEPMHA_enFTM0, + TEPMHA_enFTM1, + TEPMHA_enFTM2, + TEPMHA_enFTM3, + TEPMHA_enTimerModuleCount +} TEPMHA_tenTimerModule; +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +typedef enum +{ + TEPMHA_enTC0, + TEPMHA_enTC1, + TEPMHA_enTC2, + TEPMHA_enPWM0, + TEPMHA_enModuleCount, + TEPMHA_enModuleInvalid +} TEPMHA_tenModule; +#endif //BUILD_SAM3X8E + +typedef enum +{ + TEPMHA_enCapCom, + TEPMHA_enPWM, + TEPMHA_enSoft +} TEPMHA_tenModuleType; + + +#ifdef BUILD_MK60 +#define TEPMHA_nChannelInfo \ +{ \ + {EH_IO_TMR1, TEPMHA_enFTM0, 7u, 4u}, \ + {EH_IO_TMR2, TEPMHA_enFTM0, 6u, 4u}, \ + {EH_IO_TMR3, TEPMHA_enFTM0, 5u, 4u}, \ + {EH_IO_TMR4, TEPMHA_enFTM0, 4u, 4u}, \ + {EH_IO_TMR5, TEPMHA_enFTM3, 3u, 4u}, \ + {EH_IO_TMR6, TEPMHA_enFTM3, 2u, 4u}, \ + {EH_IO_TMR7, TEPMHA_enFTM3, 1u, 4u}, \ + {EH_IO_TMR8, TEPMHA_enFTM3, 0u, 4u}, \ + {EH_IO_TMR9, TEPMHA_enFTM3, 4u, 6u}, \ + {EH_IO_TMR10, TEPMHA_enFTM3, 5u, 6u}, \ + {EH_IO_TMR11, TEPMHA_enFTM3, 6u, 6u}, \ + {EH_IO_TMR12, TEPMHA_enFTM3, 7u, 6u}, \ + {EH_IO_TMR13, TEPMHA_enFTM0, 3u, 4u}, \ + {EH_IO_TMR14, TEPMHA_enFTM0, 2u, 4u}, \ + {EH_IO_TMR15, TEPMHA_enFTM0, 1u, 4u}, \ + {EH_IO_TMR16, TEPMHA_enFTM0, 0u, 4u}, \ + {EH_IO_ADSE4, TEPMHA_enFTM1, 0u, 6u}, \ + {EH_IO_GPSE9, TEPMHA_enFTM1, 0u, 3u}, \ + {EH_IO_GPSE8, TEPMHA_enFTM1, 1u, 3u}, \ + {EH_IO_ADSE5, TEPMHA_enFTM2, 0u, 6u}, \ + {EH_IO_GPSE7, TEPMHA_enFTM2, 0u, 3u}, \ + {EH_IO_CAN1T, TEPMHA_enFTM2, 0u, 3u}, \ + {EH_IO_CAN1R, TEPMHA_enFTM2, 1u, 3u} \ +} +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +#define TEPMHA_nChannelInfo \ +{ \ + {EH_IO_TMR1, FTM_enFTM3, TEPMHA_enCapCom, 0u,0u, 4u, FTM3_IRQn}, \ + {EH_IO_TMR2, FTM_enFTM0, TEPMHA_enCapCom, 7u,0u, 4u, FTM0_IRQn}, \ + {EH_IO_TMR3, FTM_enFTM0, TEPMHA_enCapCom, 4u,0u, 4u, FTM0_IRQn}, \ + {EH_IO_TMR4, FTM_enFTM3, TEPMHA_enCapCom, 2u,0u, 4u, FTM3_IRQn}, \ + {EH_IO_TMR5, FTM_enFTM3, TEPMHA_enCapCom, 3u,0u, 4u, FTM3_IRQn}, \ + {EH_IO_TMR6, FTM_enFTM0, TEPMHA_enCapCom, 2u,0u, 4u, FTM0_IRQn}, \ + {EH_IO_TMR7, FTM_enFTM0, TEPMHA_enCapCom, 3u,0u, 4u, FTM0_IRQn}, \ + {EH_IO_TMR8, FTM_enFTM2, TEPMHA_enCapCom, 0u,0u, 3u, FTM2_IRQn}, \ + {EH_IO_TMR9, FTM_enFTM2, TEPMHA_enCapCom, 1u,0u, 3u, FTM2_IRQn}, \ + {EH_IO_TMR10, FTM_enFTM3, TEPMHA_enCapCom, 4u,0u, 3u, FTM3_IRQn}, \ + {EH_IO_TMR11, FTM_enFTM3, TEPMHA_enCapCom, 5u,0u, 3u, FTM3_IRQn}, \ + {EH_IO_TMR12, FTM_enFTM3, TEPMHA_enCapCom, 6u,0u, 3u, FTM3_IRQn}, \ + {EH_IO_TMR13, FTM_enFTM3, TEPMHA_enCapCom, 7u,0u, 3u, FTM3_IRQn}, \ + {EH_IO_TMR14, FTM_enFTM3, TEPMHA_enCapCom, 1u,0u, 3u, FTM3_IRQn}, \ + {EH_IO_TMR15, FTM_enFTM0, TEPMHA_enCapCom, 5u,0u, 4u, FTM0_IRQn}, \ + {EH_IO_TMR16, FTM_enFTM0, TEPMHA_enCapCom, 6u,0u, 4u, FTM0_IRQn}, \ + {EH_IO_TMR17, FTM_enFTM0, TEPMHA_enCapCom, 0u,0u, 4u, FTM0_IRQn}, \ + {EH_IO_TMR18, FTM_enFTM0, TEPMHA_enCapCom, 1u,0u, 4u, FTM0_IRQn}, \ +} + +#define TEPMHA_nChannelReverseInfo \ +{\ + {FTM_enFTM0, 0u, EH_IO_TMR17},\ + {FTM_enFTM0, 1u, EH_IO_TMR18},\ + {FTM_enFTM0, 2u, EH_IO_TMR6},\ + {FTM_enFTM0, 3u, EH_IO_TMR7},\ + {FTM_enFTM0, 4u, EH_IO_TMR3},\ + {FTM_enFTM0, 5u, EH_IO_TMR15},\ + {FTM_enFTM0, 6u, EH_IO_TMR16},\ + {FTM_enFTM0, 7u, EH_IO_TMR2},\ + {FTM_enFTM1, 0u, EH_IO_Invalid},\ + {FTM_enFTM1, 1u, EH_IO_Invalid},\ + {FTM_enFTM1, 2u, EH_IO_Invalid},\ + {FTM_enFTM1, 3u, EH_IO_Invalid},\ + {FTM_enFTM1, 4u, EH_IO_Invalid},\ + {FTM_enFTM1, 5u, EH_IO_Invalid},\ + {FTM_enFTM1, 6u, EH_IO_Invalid},\ + {FTM_enFTM1, 7u, EH_IO_Invalid},\ + {FTM_enFTM2, 0u, EH_IO_TMR8},\ + {FTM_enFTM2, 1u, EH_IO_TMR9},\ + {FTM_enFTM2, 2u, EH_IO_Invalid},\ + {FTM_enFTM2, 3u, EH_IO_Invalid},\ + {FTM_enFTM2, 4u, EH_IO_Invalid},\ + {FTM_enFTM2, 5u, EH_IO_Invalid},\ + {FTM_enFTM2, 6u, EH_IO_Invalid},\ + {FTM_enFTM2, 7u, EH_IO_Invalid},\ + {FTM_enFTM3, 0u, EH_IO_TMR1},\ + {FTM_enFTM3, 1u, EH_IO_TMR14},\ + {FTM_enFTM3, 2u, EH_IO_TMR4},\ + {FTM_enFTM3, 3u, EH_IO_TMR5},\ + {FTM_enFTM3, 4u, EH_IO_TMR10},\ + {FTM_enFTM3, 5u, EH_IO_TMR11},\ + {FTM_enFTM3, 6u, EH_IO_TMR12},\ + {FTM_enFTM3, 7u, EH_IO_TMR13}\ +} +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +#define TEPMHA_nChannelInfo \ +{ \ + {EH_IO_TMR1, TEPMHA_enTC0, TEPMHA_enCapCom, 0u, 0u, 1u, TC0_IRQn}, \ + {EH_IO_TMR2, TEPMHA_enTC2, TEPMHA_enCapCom, 2u, 0u, 1u, TC7_IRQn}, \ + {EH_IO_TMR3, TEPMHA_enTC2, TEPMHA_enCapCom, 0u, 1u, 1u, TC6_IRQn}, \ + {EH_IO_TMR4, TEPMHA_enTC2, TEPMHA_enCapCom, 0u, 0u, 1u, TC6_IRQn}, \ + {EH_IO_TMR5, TEPMHA_enPWM0, TEPMHA_enPWM, 7u, 0u, 1u, PWM_IRQn}, \ + {EH_IO_TMR6, TEPMHA_enPWM0, TEPMHA_enPWM, 6u, 0u, 1u, PWM_IRQn}, \ + {EH_IO_TMR7, TEPMHA_enPWM0, TEPMHA_enPWM, 5u, 0u, 1u, PWM_IRQn}, \ + {EH_IO_TMR8, TEPMHA_enPWM0, TEPMHA_enPWM, 4u, 0u, 1u, PWM_IRQn}, \ + {EH_IO_TMR9, TEPMHA_enTC2, TEPMHA_enCapCom, 2u, 1u, 1u, TC7_IRQn}, \ + {EH_IO_TMR10, TEPMHA_enTC2, TEPMHA_enCapCom, 4u, 0u, 1u, TC8_IRQn}, \ + {EH_IO_TMR11, TEPMHA_enTC2, TEPMHA_enCapCom, 4u, 1u, 1u, TC8_IRQn}, \ + {EH_IO_TMR12, TEPMHA_enTC0, TEPMHA_enCapCom, 0u, 1u, 1u, TC0_IRQn}, \ + {EH_IO_ADD5, TEPMHA_enTC0, TEPMHA_enCapCom, 4u, 1u, 0u, TC2_IRQn}, \ + {EH_IO_ADD7, TEPMHA_enTC0, TEPMHA_enCapCom, 2u, 1u, 0u, TC1_IRQn}, \ + {EH_IO_ADD8, TEPMHA_enTC0, TEPMHA_enCapCom, 2u, 0u, 0u, TC1_IRQn}, \ + {EH_IO_EXTINT, TEPMHA_enTC0, TEPMHA_enCapCom, 4u, 0u, 0u, TC2_IRQn}, \ +} +#endif //BUILD_SAM3X8E + +#ifdef BUILD_SAM3X8E +#define TEPMHA_nChannelResourceList \ +{ \ + EH_IO_TMR1, \ + EH_IO_TMR2, \ + EH_IO_TMR3, \ + EH_IO_TMR4, \ + EH_IO_TMR5, \ + EH_IO_TMR6, \ + EH_IO_TMR7, \ + EH_IO_TMR8, \ + EH_IO_TMR9, \ + EH_IO_TMR10, \ + EH_IO_TMR11, \ + EH_IO_TMR12, \ + EH_IO_ADD5, \ + EH_IO_ADD7, \ + EH_IO_ADD8, \ + EH_IO_EXTINT \ +} +#endif //BUILD_SAM3X8E + +#ifdef BUILD_MK64 +#define TEPMHA_nChannelResourceList \ +{ \ + EH_IO_TMR1, \ + EH_IO_TMR2, \ + EH_IO_TMR3, \ + EH_IO_TMR4, \ + EH_IO_TMR5, \ + EH_IO_TMR6, \ + EH_IO_TMR7, \ + EH_IO_TMR8, \ + EH_IO_TMR9, \ + EH_IO_TMR10, \ + EH_IO_TMR11, \ + EH_IO_TMR12, \ + EH_IO_TMR13, \ + EH_IO_TMR14, \ + EH_IO_TMR15, \ + EH_IO_TMR16, \ + EH_IO_TMR17, \ + EH_IO_TMR18 \ +} +#endif //BUILD_MK64 + + +#ifdef BUILD_MK60 +#define TEPMHA_nChannelFastInfo \ +{ \ + EH_IO_TMR16, \ + EH_IO_TMR15, \ + EH_IO_TMR14, \ + EH_IO_TMR13, \ + EH_IO_TMR4, \ + EH_IO_TMR3, \ + EH_IO_TMR2, \ + EH_IO_TMR1 \ +} +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +#define TEPMHA_nChannelFastInfo \ +{ \ + EH_IO_TMR2, \ + EH_IO_TMR3, \ + EH_IO_TMR8, \ + EH_IO_TMR9, \ + EH_IO_TMR5, \ + EH_IO_TMR10, \ + EH_IO_TMR11, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_TMR13, \ + EH_IO_TMR14, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_TMR1, \ + EH_IO_TMR12, \ + EH_IO_TMR6, \ + EH_IO_TMR7, \ + EH_IO_TMR15, \ + EH_IO_TMR16, \ + EH_IO_TMR17, \ + EH_IO_TMR18, \ +} +#endif //BUILD_MK64 + +#ifdef BUILD_SAM3X8E +#define TEPMHA_nChannelFastInfo \ +{ \ + EH_IO_TMR1, \ + EH_IO_TMR12, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_Invalid, \ + EH_IO_TMR4, \ + EH_IO_Invalid, \ + EH_IO_TMR2, \ + EH_IO_TMR9, \ + EH_IO_TMR10, \ + EH_IO_TMR11 \ +} +#endif //BUILD_SAM3X8E + +#ifdef BUILD_MK60 +#define TEPMHA_nChannelSlowInfo \ +{ \ + EH_IO_TMR8, \ + EH_IO_TMR7, \ + EH_IO_TMR6, \ + EH_IO_TMR5, \ + EH_IO_TMR9, \ + EH_IO_TMR10, \ + EH_IO_TMR11, \ + EH_IO_TMR12 \ +} +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +#define TEPMHA_nChannelSlowInfo \ +{ \ + EH_IO_TMR8, \ + EH_IO_TMR7, \ + EH_IO_TMR6, \ + EH_IO_TMR5, \ + EH_IO_TMR9, \ + EH_IO_TMR10, \ + EH_IO_TMR11, \ + EH_IO_TMR12 \ +} +#endif //BUILD_MK60 + +#ifdef BUILD_SAM3X8E +#define TEPMHA_nChannelSlowInfo \ +{ \ + {EH_IO_TMR8}, \ + {EH_IO_TMR7}, \ + {EH_IO_TMR6} \ +} +#endif //BUILD_SAM3X8E + +#ifdef BUILD_MK60 +#define TEPMHA_nMasterInfo \ +{ \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM1}, \ + {EH_VIO_FTM1}, \ + {EH_VIO_FTM1}, \ + {EH_VIO_FTM2}, \ + {EH_VIO_FTM2}, \ + {EH_VIO_FTM2}, \ + {EH_VIO_FTM2} \ +} +#endif //BUILD_MK60 + +#ifdef BUILD_MK64 +#define TEPMHA_nMasterInfo \ +{ \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM0}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM2}, \ + {EH_VIO_FTM2}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3}, \ + {EH_VIO_FTM3} \ +} +#endif + +#ifdef BUILD_SAM3X8E +#define TEPMHA_nMasterInfo \ +{ \ + {EH_VIO_TC0}, \ + {EH_VIO_TC2}, \ + {EH_VIO_TC0}, \ + {EH_VIO_TC2}, \ + {EH_VIO_TC0}, \ + {EH_VIO_TC0}, \ + {EH_VIO_TC0}, \ + {EH_VIO_TC0}, \ + {EH_VIO_TC2}, \ + {EH_VIO_TC2}, \ + {EH_VIO_TC2}, \ + {EH_VIO_TC0} \ +} +#endif //BUILD_SAM3X8E + +#if defined(BUILD_MK60) || defined (BUILD_MK64) +#define TEPMHA_xRequestPortClock(x) \ +if ((FTM0 == x) && (0 == (TEPMHA_u32PortClockRequested & 0x1))){SIM_vSetReg32(SIM_SCGC6, SIM_SCGC6_FTM0_MASK);TEPMHA_u32PortClockRequested |= 1;} \ +if ((FTM1 == x) && (0 == (TEPMHA_u32PortClockRequested & 0x2))){SIM_vSetReg32(SIM_SCGC6, SIM_SCGC6_FTM1_MASK);TEPMHA_u32PortClockRequested |= 2;} \ +if ((FTM2 == x) && (0 == (TEPMHA_u32PortClockRequested & 0x4))){SIM_vSetReg32(SIM_SCGC6, SIM_SCGC6_FTM2_MASK);TEPMHA_u32PortClockRequested |= 4;} \ +if ((FTM3 == x) && (0 == (TEPMHA_u32PortClockRequested & 0x8))){SIM_vSetReg32(SIM_SCGC3, SIM_SCGC3_FTM3_MASK);TEPMHA_u32PortClockRequested |= 8;} +#endif //BUILD_MK6X + +#ifdef BUILD_SAM3X8E +#define TEPMHA_xRequestTimerClock(x) \ +if (TC0 == x) \ +{ \ + (void)SIM_boEnablePeripheralClock(TC0_IRQn); \ + (void)SIM_boEnablePeripheralClock(TC1_IRQn); \ + (void)SIM_boEnablePeripheralClock(TC2_IRQn); \ +} \ +if (TC1 == x) \ +{ \ + (void)SIM_boEnablePeripheralClock(TC3_IRQn); \ + (void)SIM_boEnablePeripheralClock(TC4_IRQn); \ + (void)SIM_boEnablePeripheralClock(TC5_IRQn); \ +} \ +if (TC2 == x) \ +{ \ + (void)SIM_boEnablePeripheralClock(TC6_IRQn); \ + (void)SIM_boEnablePeripheralClock(TC7_IRQn); \ + (void)SIM_boEnablePeripheralClock(TC8_IRQn); \ +} + +#define TEPMHA_xRequestPWMClock(x) \ +if (PWM == x) \ +{ \ + (void)SIM_boEnablePeripheralClock(PWM_IRQn); \ +} +#endif //BUILD_SAM3X8E + +#if defined(BUILD_MK60) || defined (BUILD_MK64) +#define TEPMHA_xInitInterrupts(x) \ +if (FTM0 == x){TEPM_vInitInterrupts(FTM0_IRQn);} \ +if (FTM1 == x){TEPM_vInitInterrupts(FTM1_IRQn);} \ +if (FTM2 == x){TEPM_vInitInterrupts(FTM2_IRQn);} \ +if (FTM3 == x){TEPM_vInitInterrupts(FTM3_IRQn);} +#endif //BUILD_MK6X + + +void TEPMHA_vStart(puint32 const pu32Arg); +void TEPMHA_vRun(puint32 const pu32Arg); +void TEPMHA_vTerminate(puint32 const pu32Arg); +SYSAPI_tenSVCResult TEPMHA_vInitTEPMResource(IOAPI_tenEHIOResource, TEPMAPI_tstTEPMResourceCB*); +void TEPMHA_vInitTEPMChannel(IOAPI_tenEHIOResource, TEPMAPI_tstTEPMChannelCB*); +void TEPHAM_boGetMasterEHIOResourceList(IOAPI_tenEHIOResource, IOAPI_tenEHIOResource*, puint32); +void TEPMHA_vAppendTEPMQueue(IOAPI_tenEHIOResource, TEPMAPI_tstTimedUserEvent*, TEPMAPI_ttEventCount); +void TEPMHA_vConfigureKernelTEPMInput(IOAPI_tenEHIOResource, TEPMAPI_tstTimedKernelEvent*); +void TEPMHA_vConfigureKernelTEPMOutput(IOAPI_tenEHIOResource, TEPMAPI_tstTimedKernelEvent*, TEPMAPI_ttEventCount); +void TEPMHA_vConfigureUserTEPMInput(IOAPI_tenEHIOResource, TEPMAPI_tstTimedUserEvent*); +void TEPMHA_vInitiateUserCallBack(IOAPI_tenEHIOResource, TEPMAPI_ttEventTime); +uint32 TEPMHA_u32GetFTMTableIndex(IOAPI_tenEHIOResource); +void TEPMHA_vStartEventProgramKernelQueues(void); +void TEPMHA_vSynchroniseEventProgramKernelQueues(void); +void TEPMHA_vForceQueueTerminate(void*, uint32, uint32); +bool TEPMHA_boFlagIsSet(void*, uint32, puint32, uint32, uint32); +bool TEMPHA_boInterruptEnabled(void*, uint32); +TEPMAPI_ttEventTime TEPMHA_tGetScheduledVal(void*, uint32, bool, uint32); +void TEMPHA_vResetTimerFlag(void*, uint32); +void TEPMHA_vGetFreeVal(void*, puint32); +uint32 TEPMHA_u32GetFreeVal(void*, uint32); +void TEPMHA_vDisconnectEnable(void*, uint32); +void* TEPMHA_pvGetModuleFromEnum(TEPMHA_tenTimerModule); +void TEPMHA_vCapComAction(TEPMAPI_tenAction, void*, uint32, uint32, TEPMAPI_ttEventTime); +IOAPI_tenTriState TEPMHA_enGetTimerDigitalState(IOAPI_tenEHIOResource); +void* TEPMHA_pvGetTimerModuleFromVIO(IOAPI_tenEHIOResource); +uint32 TEPMHA_u32GetTimerChannelsPerInterruptGroup(void* pvModule); +uint32 TEPMHA_u32GetTimerStartChannelInterruptGroup(IOAPI_tenEHIOResource); +uint32 TEPMHA_u32GetTimerHardwareSubChannel(uint32); +uint32 TEPMHA_u32GetTimerHardwareChannel(IOAPI_tenEHIOResource); +TEPMHA_tenTimerModule TEPMHA_enTimerEnumFromModule(tstTimerModule*); +IOAPI_tenEHIOResource TEPMHA_enGetTimerResourceFromVIOAndIndex(IOAPI_tenEHIOResource, uint32); +TEPMAPI_ttEventTime TEPMHA_u32GetTimerVal(IOAPI_tenEHIOResource); +bool TEPMHA_boCheckFalseAlarm(void* pvModule, uint32 u32ChannelIDX, uint32 u32SubChannelIDX); +uint32 TEPMHA_u32GetModulePhaseCorrect(TEPMHA_tenTimerModule enTimerModule, uint32 u32ChannelIDX); + +#endif //TEPMHA_H + diff --git a/source/UserServices/maps.c b/source/UserServices/maps.c new file mode 100644 index 0000000..0948283 --- /dev/null +++ b/source/UserServices/maps.c @@ -0,0 +1,268 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.c */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#include +#include "os.h" +#include "stddef.h" +#include "types.h" +#include "SPREADS.h" +#include "maps.h" +#include "SYSAPI.h" +#include "MATH.h" +#include "declarations.h" + +/* Private data declarations + -------------------------*/ +MAPSAPI_tstMapCB MAP_astMapCB[MAP_nKernelMapCount]; +MAPSAPI_tstMapCB* MAP_apstMapCB[MAP_nKernelMapCount + MAP_nUserMapCount]; +uint32 MAP_au32Counter[MAP_nKernelMapCount + MAP_nUserMapCount]; + +/* Private function declarations + ----------------------------*/ +static uint16 MAP_u16Interp(void*, uint16, uint16); +static uint32 MAP_u32Interp(void*, uint16, uint16); + +/* Public function definitions + ---------------------------*/ +void MAPS_vStart(puint32 const pu32Arg) +{ + uint32 u32IDX; + + for (u32IDX = 0; u32IDX < (MAP_nKernelMapCount + MAP_nUserMapCount); u32IDX++) + { + MAP_apstMapCB[u32IDX] = NULL; + } +} + +void MAPS_vRun(puint32 const pu32Arg) +{ + + +} + +void MAPS_vTerminate(puint32 const pu32Arg) +{ + + +} + +MAPSAPI_ttMapIDX MAP_tRequestKernelMap(MAPSAPI_tstMapCB* pstTableCBReq) +{ + MAPSAPI_tstMapCB* pstMapCB; + uint32 u32MapIDX; + MAPSAPI_ttMapIDX MapIDX = -1; + + /* Request a Kernel managed map */ + for (u32MapIDX = 0; MAP_nKernelMapCount > u32MapIDX; u32MapIDX++) + { + if (NULL == MAP_apstMapCB[u32MapIDX]) + { + pstMapCB = &MAP_astMapCB[u32MapIDX]; + MAP_apstMapCB[u32MapIDX] = pstMapCB; + memcpy((void*)pstMapCB, (void*)pstTableCBReq, sizeof(MAPSAPI_tstMapCB)); + MapIDX = u32MapIDX; + break; + } + } + + return MapIDX; +} + + +bool MAP_vCalculate(MAPSAPI_ttMapIDX tMapIDX) +{ + uint8 u8DataR; uint16 u16DataR; + sint8 s8DataL; sint32 s32DataL; + sint8 s8DataR; sint32 s32DataR; + uint8 u8Data; uint16 u16Data; uint32 u32Data; + sint8 s8Data; sint16 s16Data; sint32 s32Data; + puint8 pu8Data; puint16 pu16Data; + psint8 ps8Data; psint32 ps32Data; + SPREADAPI_ttSpreadIDX tSpreadIDXX; + SPREADAPI_ttSpreadIDX tSpreadIDXY; + SPREADAPI_tstSpreadResult stSpreadResultX; + SPREADAPI_tstSpreadResult stSpreadResultY; + uint32 u32ShiftL = 0; + uint32 u32ShiftR = 0; + uint32 u32Factor; + uint16 u16DataResult[2]; + uint32 u32DataResult[2]; + void* pvMapRowData; + + tSpreadIDXX = MAP_apstMapCB[tMapIDX]->tSpreadIDXX; + tSpreadIDXY = MAP_apstMapCB[tMapIDX]->tSpreadIDXY; + + stSpreadResultX = SPREAD_stGetSpread(tSpreadIDXX); + stSpreadResultY = SPREAD_stGetSpread(tSpreadIDXY); + + switch (MAP_astMapCB[tMapIDX].enDataType) + { + case TYPE_enUInt8: + case TYPE_enUInt16: + case TYPE_enInt8: + case TYPE_enInt16: + { + pvMapRowData = MAP_astMapCB[tMapIDX].pvMapData; + pvMapRowData += stSpreadResultX.uSpreadData.stSpreadResult.u16SpreadIndex * MAP_astMapCB[tMapIDX].i16MapSizeX * sizeof(uint16); + u16DataResult[0] = MAP_u16Interp(pvMapRowData, stSpreadResultY.uSpreadData.stSpreadResult.u16SpreadIndex, stSpreadResultY.uSpreadData.stSpreadResult.u16SpreadOffset); + pvMapRowData +=MAP_astMapCB[tMapIDX].i16MapSizeX * sizeof(uint16); + u16DataResult[1] = MAP_u16Interp(pvMapRowData, stSpreadResultY.uSpreadData.stSpreadResult.u16SpreadIndex, stSpreadResultY.uSpreadData.stSpreadResult.u16SpreadOffset); + *(sint16*)MAP_astMapCB[tMapIDX].pvOutputData = MAP_u16Interp(&u16DataResult, 0, stSpreadResultX.uSpreadData.stSpreadResult.u16SpreadOffset); + break; + } + case TYPE_enInt32: + { + ps32Data = (sint32*)MAP_astMapCB[tMapIDX].pvMapData; + ps32Data += stSpreadResultX.uSpreadData.stSpreadResult.u16SpreadIndex; + + s32DataL = *ps32Data; + s32DataR = *(ps32Data + 1); + + while ((0x4000 <= s32DataL) || (-0x4000 >= s32DataL)) + { + u32ShiftL++; + s32DataL /= 2; + } + + while ((0x4000 <= s32DataR) || (-0x4000 >= s32DataR)) + { + u32ShiftR++; + s32DataR /= 2; + } + + u32ShiftL = (u32ShiftL > u32ShiftR) ? u32ShiftL : u32ShiftR; + u32Factor = MATH_u32IDXToMask(u32ShiftL); + + s32DataL = (*ps32Data) / u32Factor; + s32DataR = (*(ps32Data + 1)) / u32Factor; + + u32Data = (s32DataR * stSpreadResultX.uSpreadData.stSpreadResult.u16SpreadOffset) + + (s32DataL * (0xffff - stSpreadResultX.uSpreadData.stSpreadResult.u16SpreadOffset)); + + u32Data /= 0xffff; //matthew check this look for a better way to hold precision + u32Data *= u32Factor; + + *(sint32*)MAP_astMapCB[tMapIDX].pvOutputData = (sint32)u32Data; + break; + } + case TYPE_enUInt32: + { + pvMapRowData = MAP_astMapCB[tMapIDX].pvMapData; + pvMapRowData += stSpreadResultX.uSpreadData.stSpreadResult.u16SpreadIndex * MAP_astMapCB[tMapIDX].i16MapSizeX * sizeof(uint32); + u32DataResult[0] = MAP_u32Interp(pvMapRowData, stSpreadResultY.uSpreadData.stSpreadResult.u16SpreadIndex, stSpreadResultY.uSpreadData.stSpreadResult.u16SpreadOffset); + pvMapRowData +=MAP_astMapCB[tMapIDX].i16MapSizeX * sizeof(uint32); + u32DataResult[1] = MAP_u32Interp(pvMapRowData, stSpreadResultY.uSpreadData.stSpreadResult.u16SpreadIndex, stSpreadResultY.uSpreadData.stSpreadResult.u16SpreadOffset); + *(uint32*)MAP_astMapCB[tMapIDX].pvOutputData = MAP_u32Interp(&u32DataResult, 0, stSpreadResultX.uSpreadData.stSpreadResult.u16SpreadOffset); + break; + } + } + + OS_stSVCDataStruct.pvData = NULL; + + /* TODO suppress warning */ + (void)u8DataR; + (void)u16DataR; + (void)s8DataL; + (void)s8DataR; + (void)u8Data; + (void)u16Data; + (void)s16Data; + (void)pu16Data; + (void)ps8Data; + (void)s8Data; + (void)s32Data; + (void)pu8Data; + + return true; +} + +static uint16 MAP_u16Interp(void* pvMapData, uint16 u16SpreadIDX, uint16 u16SpreadOffset) +{ + sint16* ps16Data; + sint16 s16DataL, s16DataR; + uint32 u32ShiftL = 0; + uint32 u32ShiftR = 0; + uint32 u32Factor, u32Data; + + ps16Data = (sint16*)pvMapData; + ps16Data += u16SpreadIDX; + + s16DataL = *ps16Data; + s16DataR = *(ps16Data + 1); + + while ((0x4000 <= s16DataL) || (-0x4000 >= s16DataL)) + { + u32ShiftL++; + s16DataL /= 2; + } + + while ((0x4000 <= s16DataR) || (-0x4000 >= s16DataR)) + { + u32ShiftR++; + s16DataR /= 2; + } + + u32ShiftL = (u32ShiftL > u32ShiftR) ? u32ShiftL : u32ShiftR; + u32Factor = MATH_u32IDXToMask(u32ShiftL); + + s16DataL = (*ps16Data) / u32Factor; + s16DataR = (*(ps16Data + 1)) / u32Factor; + + u32Data = (s16DataR * u16SpreadOffset) + + (s16DataL * (0xffff - u16SpreadOffset)); + + u32Data *= u32Factor; + u32Data /= 0xffff; + + return (sint16)u32Data; +} + +static uint32 MAP_u32Interp(void* pvMapData, uint16 u16SpreadIDX, uint16 u16SpreadOffset) +{ + puint32 pu32Data; + uint32 u32DataL, u32DataR; + uint32 u32ShiftL = 0; + uint32 u32ShiftR = 0; + uint32 u32Factor, u32Data; + + pu32Data = (uint32*)pvMapData; + pu32Data += u16SpreadIDX; + + u32DataL = *pu32Data; + u32DataR = *(pu32Data + 1); + + while (0x4000 <= u32DataL) + { + u32ShiftL++; + u32DataL /= 2; + } + + while (0x4000 <= u32DataR) + { + u32ShiftR++; + u32DataR /= 2; + } + + u32ShiftL = (u32ShiftL > u32ShiftR) ? u32ShiftL : u32ShiftR; + u32Factor = MATH_u32IDXToMask(u32ShiftL); + + u32DataL = (*pu32Data) / u32Factor; + u32DataR = (*(pu32Data + 1)) / u32Factor; + + u32Data = (u32DataR * u16SpreadOffset) + + (u32DataL * (0x10000 - u16SpreadOffset)); + + u32Data /= 0x10000; + u32Data *= u32Factor; + + return u32Data; +} + diff --git a/source/UserServices/maps.h b/source/UserServices/maps.h new file mode 100644 index 0000000..60ab814 --- /dev/null +++ b/source/UserServices/maps.h @@ -0,0 +1,28 @@ +/******************************************************************************/ +/* Copyright (c) 2016 MD Automotive Controls. Original Work. */ +/* License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher */ +/******************************************************************************/ +/* CONTEXT:KERNEL */ +/* PACKAGE TITLE: XXX Header File */ +/* DESCRIPTION: XXX */ +/* FILE NAME: XXX.h */ +/* REVISION HISTORY: 19-08-2016 | 1.0 | Initial revision */ +/* */ +/******************************************************************************/ +#ifndef MAPS_H +#define MAPS_H + +#include "MAPSAPI.h" +#include "SYSAPI.h" + +#define MAP_nKernelMapCount 10u +#define MAP_nUserMapCount 10u + +void MAPS_vStart(puint32 const pu32Arg); +void MAPS_vRun(puint32 const pu32Arg); +void MAPS_vTerminate(puint32 const pu32Arg); +MAPSAPI_ttMapIDX MAP_tRequestKernelMap(MAPSAPI_tstMapCB*); +bool MAP_vCalculate(MAPSAPI_ttMapIDX); + +#endif //MAPS_H + diff --git a/source/generated/usb_device_config.h b/source/generated/usb_device_config.h new file mode 100644 index 0000000..869556e --- /dev/null +++ b/source/generated/usb_device_config.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _USB_DEVICE_CONFIG_H_ +#define _USB_DEVICE_CONFIG_H_ + +/******************************************************************************* +* Definitions +******************************************************************************/ +/*! + * @addtogroup usb_device_configuration + * @{ + */ + +/*! + * @name Hardware instance define + * @{ + */ + +/*! @brief KHCI instance count */ +#define USB_DEVICE_CONFIG_KHCI (1U) + +/*! @brief EHCI instance count */ +#define USB_DEVICE_CONFIG_EHCI (0U) + +/*! @brief LPC USB IP3511 FS instance count */ +#define USB_DEVICE_CONFIG_LPCIP3511FS (0U) + +/*! @brief LPC USB IP3511 HS instance count */ +#define USB_DEVICE_CONFIG_LPCIP3511HS (0U) + +/*! @brief Device instance count, the sum of KHCI and EHCI instance counts*/ +#define USB_DEVICE_CONFIG_NUM \ + (USB_DEVICE_CONFIG_KHCI + USB_DEVICE_CONFIG_EHCI + USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS) + +/* @} */ + +/*! + * @name class instance define + * @{ + */ + +/*! @brief HID instance count */ +#define USB_DEVICE_CONFIG_HID (0U) + +/*! @brief CDC ACM instance count */ +#define USB_DEVICE_CONFIG_CDC_ACM (1U) + +/*! @brief MSC instance count */ +#define USB_DEVICE_CONFIG_MSC (0U) + +/*! @brief Audio instance count */ +#define USB_DEVICE_CONFIG_AUDIO (0U) + +/*! @brief PHDC instance count */ +#define USB_DEVICE_CONFIG_PHDC (0U) + +/*! @brief Video instance count */ +#define USB_DEVICE_CONFIG_VIDEO (0U) + +/*! @brief CCID instance count */ +#define USB_DEVICE_CONFIG_CCID (0U) + +/*! @brief Printer instance count */ +#define USB_DEVICE_CONFIG_PRINTER (0U) + +/*! @brief DFU instance count */ +#define USB_DEVICE_CONFIG_DFU (0U) + +/* @} */ + +/*! @brief Whether device is self power. 1U supported, 0U not supported */ +#define USB_DEVICE_CONFIG_SELF_POWER (1U) + +/*! @brief How many endpoints are supported in the stack. */ +#define USB_DEVICE_CONFIG_ENDPOINTS (4U) + +/*! @brief Whether the device task is enabled. */ +#define USB_DEVICE_CONFIG_USE_TASK (0U) + +/*! @brief How many the notification message are supported when the device task is enabled. */ +#define USB_DEVICE_CONFIG_MAX_MESSAGES (8U) + +/*! @brief Whether test mode enabled. */ +#define USB_DEVICE_CONFIG_USB20_TEST_MODE (0U) + +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) + +/*! @brief The MAX buffer length for the KHCI DMA workaround.*/ +#define USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH (64U) +/*! @brief Whether handle the USB KHCI bus error. */ +#define USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING (0U) +#endif + +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) +/*! @brief How many the DTD are supported. */ +#define USB_DEVICE_CONFIG_EHCI_MAX_DTD (16U) +/*! @brief Whether handle the USB EHCI bus error. */ +#define USB_DEVICE_CONFIG_EHCI_ERROR_HANDLING (0U) + +/*! @brief Whether the EHCI ID pin detect feature enabled. */ +#define USB_DEVICE_CONFIG_EHCI_ID_PIN_DETECT (0U) +#endif + +/*! @brief Whether the keep alive feature enabled. */ +#define USB_DEVICE_CONFIG_KEEP_ALIVE_MODE (0U) + +/*! @brief Whether the transfer buffer is cache-enabled or not. */ +#define USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE (0U) + +/*! @brief Whether the low power mode is enabled or not. */ +#define USB_DEVICE_CONFIG_LOW_POWER_MODE (0U) + +#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +/*! @brief Whether device remote wakeup supported. 1U supported, 0U not supported */ +#define USB_DEVICE_CONFIG_REMOTE_WAKEUP (0U) + +/*! @brief Whether LPM is supported. 1U supported, 0U not supported */ +#define USB_DEVICE_CONFIG_LPM_L1 (0U) +#else +/*! @brief The device remote wakeup is unsupported. */ +#define USB_DEVICE_CONFIG_REMOTE_WAKEUP (0U) +#endif + +/*! @brief Whether the device detached feature is enabled or not. */ +#define USB_DEVICE_CONFIG_DETACH_ENABLE (0U) + +/* @} */ + +#endif /* _USB_DEVICE_CONFIG_H_ */ diff --git a/source/semihost_hardfault.c b/source/semihost_hardfault.c new file mode 100644 index 0000000..a29f2f6 --- /dev/null +++ b/source/semihost_hardfault.c @@ -0,0 +1,109 @@ +// **************************************************************************** +// semihost_hardfault.c +// - Provides hard fault handler to allow semihosting code not +// to hang application when debugger not connected. +// +// **************************************************************************** +// Copyright 2017-2018 NXP +// All rights reserved. +// +// Software that is described herein is for illustrative purposes only +// which provides customers with programming information regarding the +// NXP Cortex-M based MCUs. This software is supplied "AS IS" without any +// warranties of any kind, and NXP Semiconductors and its licensor disclaim any +// and all warranties, express or implied, including all implied warranties of +// merchantability, fitness for a particular purpose and non-infringement of +// intellectual property rights. NXP Semiconductors assumes no responsibility +// or liability for the use of the software, conveys no license or rights under +// any patent, copyright, mask work right, or any other intellectual property +// rights in or to any products. NXP Semiconductors reserves the right to make +// changes in the software without notification. NXP Semiconductors also makes +// no representation or warranty that such application will be suitable for the +// specified use without further testing or modification. +// +// Permission to use, copy, modify, and distribute this software and its +// documentation is hereby granted, under NXP Semiconductors' and its +// licensor's relevant copyrights in the software, without fee, provided that it +// is used in conjunction with NXP Semiconductors microcontrollers. This +// copyright, permission, and disclaimer notice must appear in all copies of +// this code. +// **************************************************************************** +// +// ===== DESCRIPTION ===== +// +// One of the issues with applications that make use of semihosting operations +// (such as printf calls) is that the code will not execute correctly when the +// debugger is not connected. Generally this will show up with the application +// appearing to just hang. This may include the application running from reset +// or powering up the board (with the application already in FLASH), and also +// as the application failing to continue to execute after a debug session is +// terminated. +// +// The problem here is that the "bottom layer" of the semihosted variants of +// the C library, semihosting is implemented by a "BKPT 0xAB" instruction. +// When the debug tools are not connected, this instruction triggers a hard +// fault - and the default hard fault handler within an application will +// typically just contains an infinite loop - causing the application to +// appear to have hang when no debugger is connected. +// +// The below code provides an example hard fault handler which instead looks +// to see what the instruction that caused the hard fault was - and if it +// was a "BKPT 0xAB", then it instead returns back to the user application. +// +// In most cases this will allow applications containing semihosting +// operations to execute (to some degree) when the debugger is not connected. +// +// == NOTE == +// +// Correct execution of the application containing semihosted operations +// which are vectored onto this hard fault handler cannot be guaranteed. This +// is because the handler may not return data or return codes that the higher +// level C library code or application code expects. This hard fault handler +// is meant as a development aid, and it is not recommended to leave +// semihosted code in a production build of your application! +// +// **************************************************************************** + +// Allow handler to be removed by setting a define (via command line) +#if !defined (__SEMIHOST_HARDFAULT_DISABLE) + +__attribute__((naked)) +void HardFault_Handler(void){ + __asm( ".syntax unified\n" + // Check which stack is in use + "MOVS R0, #4 \n" + "MOV R1, LR \n" + "TST R0, R1 \n" + "BEQ _MSP \n" + "MRS R0, PSP \n" + "B _process \n" + "_MSP: \n" + "MRS R0, MSP \n" + // Load the instruction that triggered hard fault + "_process: \n" + "LDR R1,[R0,#24] \n" + "LDRH R2,[r1] \n" + // Semihosting instruction is "BKPT 0xAB" (0xBEAB) + "LDR R3,=0xBEAB \n" + "CMP R2,R3 \n" + "BEQ _semihost_return \n" + // Wasn't semihosting instruction so enter infinite loop + "B . \n" + // Was semihosting instruction, so adjust location to + // return to by 1 instruction (2 bytes), then exit function + "_semihost_return: \n" + "ADDS R1,#2 \n" + "STR R1,[R0,#24] \n" + // Set a return value from semihosting operation. + // 32 is slightly arbitrary, but appears to allow most + // C Library IO functions sitting on top of semihosting to + // continue to operate to some degree + "MOVS R1,#32 \n" + "STR R1,[ R0,#0 ] \n" // R0 is at location 0 on stack + // Return from hard fault handler to application + "BX LR \n" + ".syntax divided\n") ; +} + +#endif + diff --git a/startup/startup_mk64f12.c b/startup/startup_mk64f12.c new file mode 100644 index 0000000..2b06920 --- /dev/null +++ b/startup/startup_mk64f12.c @@ -0,0 +1,941 @@ +//***************************************************************************** +// MK64F12 startup code for use with MCUXpresso IDE +// +// Version : 010818 +//***************************************************************************** +// +// Copyright 2016-2018 NXP +// +// SPDX-License-Identifier: BSD-3-Clause +//***************************************************************************** + +#if defined (DEBUG) +#pragma GCC push_options +#pragma GCC optimize ("Og") +#endif // (DEBUG) + +#if defined (__cplusplus) +#ifdef __REDLIB__ +#error Redlib does not support C++ +#else +//***************************************************************************** +// +// The entry point for the C++ library startup +// +//***************************************************************************** +extern "C" { + extern void __libc_init_array(void); +} +#endif +#endif + +#define WEAK __attribute__ ((weak)) +#define WEAK_AV __attribute__ ((weak, section(".after_vectors"))) +#define ALIAS(f) __attribute__ ((weak, alias (#f))) + +//***************************************************************************** +#if defined (__cplusplus) +extern "C" { +#endif + +//***************************************************************************** +// Flash Configuration block : 16-byte flash configuration field that stores +// default protection settings (loaded on reset) and security information that +// allows the MCU to restrict access to the Flash Memory module. +// Placed at address 0x400 by the linker script. +//***************************************************************************** +__attribute__ ((used,section(".FlashConfig"))) const struct { + unsigned int word1; + unsigned int word2; + unsigned int word3; + unsigned int word4; +} Flash_Config = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE}; +//***************************************************************************** +// Declaration of external SystemInit function +//***************************************************************************** +#if defined (__USE_CMSIS) +extern void SystemInit(void); +#endif // (__USE_CMSIS) + +//***************************************************************************** +// Forward declaration of the core exception handlers. +// When the application defines a handler (with the same name), this will +// automatically take precedence over these weak definitions. +// If your application is a C++ one, then any interrupt handlers defined +// in C++ files within in your main application will need to have C linkage +// rather than C++ linkage. To do this, make sure that you are using extern "C" +// { .... } around the interrupt handler within your main application code. +//***************************************************************************** + void ResetISR(void); +WEAK void NMI_Handler(void); +WEAK void HardFault_Handler(void); +WEAK void MemManage_Handler(void); +WEAK void BusFault_Handler(void); +WEAK void UsageFault_Handler(void); +WEAK void SVC_Handler(void); +WEAK void DebugMon_Handler(void); +WEAK void PendSV_Handler(void); +WEAK void SysTick_Handler(void); +WEAK void IntDefaultHandler(void); + +//***************************************************************************** +// Forward declaration of the application IRQ handlers. When the application +// defines a handler (with the same name), this will automatically take +// precedence over weak definitions below +//***************************************************************************** +WEAK void DMA0_IRQHandler(void); +WEAK void DMA1_IRQHandler(void); +WEAK void DMA2_IRQHandler(void); +WEAK void DMA3_IRQHandler(void); +WEAK void DMA4_IRQHandler(void); +WEAK void DMA5_IRQHandler(void); +WEAK void DMA6_IRQHandler(void); +WEAK void DMA7_IRQHandler(void); +WEAK void DMA8_IRQHandler(void); +WEAK void DMA9_IRQHandler(void); +WEAK void DMA10_IRQHandler(void); +WEAK void DMA11_IRQHandler(void); +WEAK void DMA12_IRQHandler(void); +WEAK void DMA13_IRQHandler(void); +WEAK void DMA14_IRQHandler(void); +WEAK void DMA15_IRQHandler(void); +WEAK void DMA_Error_IRQHandler(void); +WEAK void MCM_IRQHandler(void); +WEAK void FTFE_IRQHandler(void); +WEAK void Read_Collision_IRQHandler(void); +WEAK void LVD_LVW_IRQHandler(void); +WEAK void LLWU_IRQHandler(void); +WEAK void WDOG_EWM_IRQHandler(void); +WEAK void RNG_IRQHandler(void); +WEAK void I2C0_IRQHandler(void); +WEAK void I2C1_IRQHandler(void); +WEAK void SPI0_IRQHandler(void); +WEAK void SPI1_IRQHandler(void); +WEAK void I2S0_Tx_IRQHandler(void); +WEAK void I2S0_Rx_IRQHandler(void); +WEAK void UART0_LON_IRQHandler(void); +WEAK void UART0_RX_TX_IRQHandler(void); +WEAK void UART0_ERR_IRQHandler(void); +WEAK void UART1_RX_TX_IRQHandler(void); +WEAK void UART1_ERR_IRQHandler(void); +WEAK void UART2_RX_TX_IRQHandler(void); +WEAK void UART2_ERR_IRQHandler(void); +WEAK void UART3_RX_TX_IRQHandler(void); +WEAK void UART3_ERR_IRQHandler(void); +WEAK void ADC0_IRQHandler(void); +WEAK void CMP0_IRQHandler(void); +WEAK void CMP1_IRQHandler(void); +WEAK void FTM0_IRQHandler(void); +WEAK void FTM1_IRQHandler(void); +WEAK void FTM2_IRQHandler(void); +WEAK void CMT_IRQHandler(void); +WEAK void RTC_IRQHandler(void); +WEAK void RTC_Seconds_IRQHandler(void); +WEAK void PIT0_IRQHandler(void); +WEAK void PIT1_IRQHandler(void); +WEAK void PIT2_IRQHandler(void); +WEAK void PIT3_IRQHandler(void); +WEAK void PDB0_IRQHandler(void); +WEAK void USB0_IRQHandler(void); +WEAK void USBDCD_IRQHandler(void); +WEAK void Reserved71_IRQHandler(void); +WEAK void DAC0_IRQHandler(void); +WEAK void MCG_IRQHandler(void); +WEAK void LPTMR0_IRQHandler(void); +WEAK void PORTA_IRQHandler(void); +WEAK void PORTB_IRQHandler(void); +WEAK void PORTC_IRQHandler(void); +WEAK void PORTD_IRQHandler(void); +WEAK void PORTE_IRQHandler(void); +WEAK void SWI_IRQHandler(void); +WEAK void SPI2_IRQHandler(void); +WEAK void UART4_RX_TX_IRQHandler(void); +WEAK void UART4_ERR_IRQHandler(void); +WEAK void UART5_RX_TX_IRQHandler(void); +WEAK void UART5_ERR_IRQHandler(void); +WEAK void CMP2_IRQHandler(void); +WEAK void FTM3_IRQHandler(void); +WEAK void DAC1_IRQHandler(void); +WEAK void ADC1_IRQHandler(void); +WEAK void I2C2_IRQHandler(void); +WEAK void CAN0_ORed_Message_buffer_IRQHandler(void); +WEAK void CAN0_Bus_Off_IRQHandler(void); +WEAK void CAN0_Error_IRQHandler(void); +WEAK void CAN0_Tx_Warning_IRQHandler(void); +WEAK void CAN0_Rx_Warning_IRQHandler(void); +WEAK void CAN0_Wake_Up_IRQHandler(void); +WEAK void SDHC_IRQHandler(void); +WEAK void ENET_1588_Timer_IRQHandler(void); +WEAK void ENET_Transmit_IRQHandler(void); +WEAK void ENET_Receive_IRQHandler(void); +WEAK void ENET_Error_IRQHandler(void); + +//***************************************************************************** +// Forward declaration of the driver IRQ handlers. These are aliased +// to the IntDefaultHandler, which is a 'forever' loop. When the driver +// defines a handler (with the same name), this will automatically take +// precedence over these weak definitions +//***************************************************************************** +void DMA0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA2_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA3_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA4_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA5_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA6_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA7_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA8_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA9_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA10_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA11_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA12_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA13_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA14_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA15_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA_Error_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void MCM_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void FTFE_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void Read_Collision_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void LVD_LVW_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void LLWU_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void WDOG_EWM_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void RNG_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void I2C0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void I2C1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void SPI0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void SPI1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void I2S0_Tx_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void I2S0_Rx_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void UART0_LON_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void UART0_RX_TX_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void UART0_ERR_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void UART1_RX_TX_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void UART1_ERR_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void UART2_RX_TX_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void UART2_ERR_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void UART3_RX_TX_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void UART3_ERR_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void CMP0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void CMP1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void FTM0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void FTM1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void FTM2_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void CMT_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void RTC_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void RTC_Seconds_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIT0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIT1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIT2_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIT3_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PDB0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void USB0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void USBDCD_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void Reserved71_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DAC0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void MCG_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void LPTMR0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PORTA_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PORTB_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PORTC_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PORTD_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PORTE_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void SWI_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void SPI2_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void UART4_RX_TX_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void UART4_ERR_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void UART5_RX_TX_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void UART5_ERR_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void CMP2_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void FTM3_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DAC1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void ADC1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void I2C2_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void CAN0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void SDHC_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void ENET_1588_Timer_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void ENET_Transmit_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void ENET_Receive_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void ENET_Error_DriverIRQHandler(void) ALIAS(IntDefaultHandler); + +//***************************************************************************** +// The entry point for the application. +// __main() is the entry point for Redlib based applications +// main() is the entry point for Newlib based applications +//***************************************************************************** +#if defined (__REDLIB__) +extern void __main(void); +#endif +extern int main(void); + +//***************************************************************************** +// External declaration for the pointer to the stack top from the Linker Script +//***************************************************************************** +extern void _vStackTop(void); +//***************************************************************************** +#if defined (__cplusplus) +} // extern "C" +#endif +//***************************************************************************** +// The vector table. +// This relies on the linker script to place at correct location in memory. +//***************************************************************************** +extern void (* const g_pfnVectors[])(void); +extern void * __Vectors __attribute__ ((alias ("g_pfnVectors"))); + +__attribute__ ((used, section(".isr_vector"))) +void (* const g_pfnVectors[])(void) = { + // Core Level - CM4 + &_vStackTop, // The initial stack pointer + ResetISR, // The reset handler + NMI_Handler, // The NMI handler + HardFault_Handler, // The hard fault handler + MemManage_Handler, // The MPU fault handler + BusFault_Handler, // The bus fault handler + UsageFault_Handler, // The usage fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVC_Handler, // SVCall handler + DebugMon_Handler, // Debug monitor handler + 0, // Reserved + PendSV_Handler, // The PendSV handler + SysTick_Handler, // The SysTick handler + + // Chip Level - MK64F12 + DMA0_IRQHandler, // 16 : DMA Channel 0 Transfer Complete + DMA1_IRQHandler, // 17 : DMA Channel 1 Transfer Complete + DMA2_IRQHandler, // 18 : DMA Channel 2 Transfer Complete + DMA3_IRQHandler, // 19 : DMA Channel 3 Transfer Complete + DMA4_IRQHandler, // 20 : DMA Channel 4 Transfer Complete + DMA5_IRQHandler, // 21 : DMA Channel 5 Transfer Complete + DMA6_IRQHandler, // 22 : DMA Channel 6 Transfer Complete + DMA7_IRQHandler, // 23 : DMA Channel 7 Transfer Complete + DMA8_IRQHandler, // 24 : DMA Channel 8 Transfer Complete + DMA9_IRQHandler, // 25 : DMA Channel 9 Transfer Complete + DMA10_IRQHandler, // 26 : DMA Channel 10 Transfer Complete + DMA11_IRQHandler, // 27 : DMA Channel 11 Transfer Complete + DMA12_IRQHandler, // 28 : DMA Channel 12 Transfer Complete + DMA13_IRQHandler, // 29 : DMA Channel 13 Transfer Complete + DMA14_IRQHandler, // 30 : DMA Channel 14 Transfer Complete + DMA15_IRQHandler, // 31 : DMA Channel 15 Transfer Complete + DMA_Error_IRQHandler, // 32 : DMA Error Interrupt + MCM_IRQHandler, // 33 : Normal Interrupt + FTFE_IRQHandler, // 34 : FTFE Command complete interrupt + Read_Collision_IRQHandler, // 35 : Read Collision Interrupt + LVD_LVW_IRQHandler, // 36 : Low Voltage Detect, Low Voltage Warning + LLWU_IRQHandler, // 37 : Low Leakage Wakeup Unit + WDOG_EWM_IRQHandler, // 38 : WDOG Interrupt + RNG_IRQHandler, // 39 : RNG Interrupt + I2C0_IRQHandler, // 40 : I2C0 interrupt + I2C1_IRQHandler, // 41 : I2C1 interrupt + SPI0_IRQHandler, // 42 : SPI0 Interrupt + SPI1_IRQHandler, // 43 : SPI1 Interrupt + I2S0_Tx_IRQHandler, // 44 : I2S0 transmit interrupt + I2S0_Rx_IRQHandler, // 45 : I2S0 receive interrupt + UART0_LON_IRQHandler, // 46 : UART0 LON interrupt + UART0_RX_TX_IRQHandler, // 47 : UART0 Receive/Transmit interrupt + UART0_ERR_IRQHandler, // 48 : UART0 Error interrupt + UART1_RX_TX_IRQHandler, // 49 : UART1 Receive/Transmit interrupt + UART1_ERR_IRQHandler, // 50 : UART1 Error interrupt + UART2_RX_TX_IRQHandler, // 51 : UART2 Receive/Transmit interrupt + UART2_ERR_IRQHandler, // 52 : UART2 Error interrupt + UART3_RX_TX_IRQHandler, // 53 : UART3 Receive/Transmit interrupt + UART3_ERR_IRQHandler, // 54 : UART3 Error interrupt + ADC0_IRQHandler, // 55 : ADC0 interrupt + CMP0_IRQHandler, // 56 : CMP0 interrupt + CMP1_IRQHandler, // 57 : CMP1 interrupt + FTM0_IRQHandler, // 58 : FTM0 fault, overflow and channels interrupt + FTM1_IRQHandler, // 59 : FTM1 fault, overflow and channels interrupt + FTM2_IRQHandler, // 60 : FTM2 fault, overflow and channels interrupt + CMT_IRQHandler, // 61 : CMT interrupt + RTC_IRQHandler, // 62 : RTC interrupt + RTC_Seconds_IRQHandler, // 63 : RTC seconds interrupt + PIT0_IRQHandler, // 64 : PIT timer channel 0 interrupt + PIT1_IRQHandler, // 65 : PIT timer channel 1 interrupt + PIT2_IRQHandler, // 66 : PIT timer channel 2 interrupt + PIT3_IRQHandler, // 67 : PIT timer channel 3 interrupt + PDB0_IRQHandler, // 68 : PDB0 Interrupt + USB0_IRQHandler, // 69 : USB0 interrupt + USBDCD_IRQHandler, // 70 : USBDCD Interrupt + Reserved71_IRQHandler, // 71 : Reserved interrupt + DAC0_IRQHandler, // 72 : DAC0 interrupt + MCG_IRQHandler, // 73 : MCG Interrupt + LPTMR0_IRQHandler, // 74 : LPTimer interrupt + PORTA_IRQHandler, // 75 : Port A interrupt + PORTB_IRQHandler, // 76 : Port B interrupt + PORTC_IRQHandler, // 77 : Port C interrupt + PORTD_IRQHandler, // 78 : Port D interrupt + PORTE_IRQHandler, // 79 : Port E interrupt + SWI_IRQHandler, // 80 : Software interrupt + SPI2_IRQHandler, // 81 : SPI2 Interrupt + UART4_RX_TX_IRQHandler, // 82 : UART4 Receive/Transmit interrupt + UART4_ERR_IRQHandler, // 83 : UART4 Error interrupt + UART5_RX_TX_IRQHandler, // 84 : UART5 Receive/Transmit interrupt + UART5_ERR_IRQHandler, // 85 : UART5 Error interrupt + CMP2_IRQHandler, // 86 : CMP2 interrupt + FTM3_IRQHandler, // 87 : FTM3 fault, overflow and channels interrupt + DAC1_IRQHandler, // 88 : DAC1 interrupt + ADC1_IRQHandler, // 89 : ADC1 interrupt + I2C2_IRQHandler, // 90 : I2C2 interrupt + CAN0_ORed_Message_buffer_IRQHandler, // 91 : CAN0 OR'd message buffers interrupt + CAN0_Bus_Off_IRQHandler, // 92 : CAN0 bus off interrupt + CAN0_Error_IRQHandler, // 93 : CAN0 error interrupt + CAN0_Tx_Warning_IRQHandler, // 94 : CAN0 Tx warning interrupt + CAN0_Rx_Warning_IRQHandler, // 95 : CAN0 Rx warning interrupt + CAN0_Wake_Up_IRQHandler, // 96 : CAN0 wake up interrupt + SDHC_IRQHandler, // 97 : SDHC interrupt + ENET_1588_Timer_IRQHandler, // 98 : Ethernet MAC IEEE 1588 Timer Interrupt + ENET_Transmit_IRQHandler, // 99 : Ethernet MAC Transmit Interrupt + ENET_Receive_IRQHandler, // 100: Ethernet MAC Receive Interrupt + ENET_Error_IRQHandler, // 101: Ethernet MAC Error and miscelaneous Interrupt + +}; /* End of g_pfnVectors */ + +//***************************************************************************** +// Functions to carry out the initialization of RW and BSS data sections. These +// are written as separate functions rather than being inlined within the +// ResetISR() function in order to cope with MCUs with multiple banks of +// memory. +//***************************************************************************** +__attribute__ ((section(".after_vectors.init_data"))) +void data_init(unsigned int romstart, unsigned int start, unsigned int len) { + unsigned int *pulDest = (unsigned int*) start; + unsigned int *pulSrc = (unsigned int*) romstart; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) + *pulDest++ = *pulSrc++; +} + +__attribute__ ((section(".after_vectors.init_bss"))) +void bss_init(unsigned int start, unsigned int len) { + unsigned int *pulDest = (unsigned int*) start; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) + *pulDest++ = 0; +} + +//***************************************************************************** +// The following symbols are constructs generated by the linker, indicating +// the location of various points in the "Global Section Table". This table is +// created by the linker via the Code Red managed linker script mechanism. It +// contains the load address, execution address and length of each RW data +// section and the execution and length of each BSS (zero initialized) section. +//***************************************************************************** +extern unsigned int __data_section_table; +extern unsigned int __data_section_table_end; +extern unsigned int __bss_section_table; +extern unsigned int __bss_section_table_end; + +//***************************************************************************** +// Reset entry point for your code. +// Sets up a simple runtime environment and initializes the C/C++ +// library. +//***************************************************************************** +__attribute__ ((section(".after_vectors.reset"))) +void ResetISR(void) { + + // Disable interrupts + __asm volatile ("cpsid i"); + +#if defined (__USE_CMSIS) +// If __USE_CMSIS defined, then call CMSIS SystemInit code + SystemInit(); + +#else + // Disable Watchdog + // Write 0xC520 to watchdog unlock register + *((volatile unsigned short *)0x4005200E) = 0xC520; + // Followed by 0xD928 to complete the unlock + *((volatile unsigned short *)0x4005200E) = 0xD928; + // Now disable watchdog via STCTRLH register + *((volatile unsigned short *)0x40052000) = 0x01D2u; +#endif // (__USE_CMSIS) + + // + // Copy the data sections from flash to SRAM. + // + unsigned int LoadAddr, ExeAddr, SectionLen; + unsigned int *SectionTableAddr; + + // Load base address of Global Section Table + SectionTableAddr = &__data_section_table; + + // Copy the data sections from flash to SRAM. + while (SectionTableAddr < &__data_section_table_end) { + LoadAddr = *SectionTableAddr++; + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + data_init(LoadAddr, ExeAddr, SectionLen); + } + + // At this point, SectionTableAddr = &__bss_section_table; + // Zero fill the bss segment + while (SectionTableAddr < &__bss_section_table_end) { + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + bss_init(ExeAddr, SectionLen); + } + +#if !defined (__USE_CMSIS) +// Assume that if __USE_CMSIS defined, then CMSIS SystemInit code +// will enable the FPU +#if defined (__VFP_FP__) && !defined (__SOFTFP__) + // + // Code to enable the Cortex-M4 FPU only included + // if appropriate build options have been selected. + // Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C) + // + // Read CPACR (located at address 0xE000ED88) + // Set bits 20-23 to enable CP10 and CP11 coprocessors + // Write back the modified value to the CPACR + asm volatile ("LDR.W R0, =0xE000ED88\n\t" + "LDR R1, [R0]\n\t" + "ORR R1, R1, #(0xF << 20)\n\t" + "STR R1, [R0]"); +#endif // (__VFP_FP__) && !(__SOFTFP__) +#endif // (__USE_CMSIS) + +#if !defined (__USE_CMSIS) +// Assume that if __USE_CMSIS defined, then CMSIS SystemInit code +// will setup the VTOR register + + // Check to see if we are running the code from a non-zero + // address (eg RAM, external flash), in which case we need + // to modify the VTOR register to tell the CPU that the + // vector table is located at a non-0x0 address. + unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08; + if ((unsigned int *)g_pfnVectors!=(unsigned int *) 0x00000000) { + *pSCB_VTOR = (unsigned int)g_pfnVectors; + } +#endif // (__USE_CMSIS) + +#if defined (__cplusplus) + // + // Call C++ library initialisation + // + __libc_init_array(); +#endif + + // Reenable interrupts + __asm volatile ("cpsie i"); + +#if defined (__REDLIB__) + // Call the Redlib library, which in turn calls main() + __main(); +#else + main(); +#endif + + // + // main() shouldn't return, but if it does, we'll just enter an infinite loop + // + while (1) { + ; + } +} + +//***************************************************************************** +// Default core exception handlers. Override the ones here by defining your own +// handler routines in your application code. +//***************************************************************************** +WEAK_AV void NMI_Handler(void) +{ while(1) {} +} + +WEAK_AV void HardFault_Handler(void) +{ while(1) {} +} + +WEAK_AV void MemManage_Handler(void) +{ while(1) {} +} + +WEAK_AV void BusFault_Handler(void) +{ while(1) {} +} + +WEAK_AV void UsageFault_Handler(void) +{ while(1) {} +} + +WEAK_AV void SVC_Handler(void) +{ while(1) {} +} + +WEAK_AV void DebugMon_Handler(void) +{ while(1) {} +} + +WEAK_AV void PendSV_Handler(void) +{ while(1) {} +} + +WEAK_AV void SysTick_Handler(void) +{ while(1) {} +} + +//***************************************************************************** +// Processor ends up here if an unexpected interrupt occurs or a specific +// handler is not present in the application code. +//***************************************************************************** +WEAK_AV void IntDefaultHandler(void) +{ while(1) {} +} + +//***************************************************************************** +// Default application exception handlers. Override the ones here by defining +// your own handler routines in your application code. These routines call +// driver exception handlers or IntDefaultHandler() if no driver exception +// handler is included. +//***************************************************************************** +WEAK void DMA0_IRQHandler(void) +{ DMA0_DriverIRQHandler(); +} + +WEAK void DMA1_IRQHandler(void) +{ DMA1_DriverIRQHandler(); +} + +WEAK void DMA2_IRQHandler(void) +{ DMA2_DriverIRQHandler(); +} + +WEAK void DMA3_IRQHandler(void) +{ DMA3_DriverIRQHandler(); +} + +WEAK void DMA4_IRQHandler(void) +{ DMA4_DriverIRQHandler(); +} + +WEAK void DMA5_IRQHandler(void) +{ DMA5_DriverIRQHandler(); +} + +WEAK void DMA6_IRQHandler(void) +{ DMA6_DriverIRQHandler(); +} + +WEAK void DMA7_IRQHandler(void) +{ DMA7_DriverIRQHandler(); +} + +WEAK void DMA8_IRQHandler(void) +{ DMA8_DriverIRQHandler(); +} + +WEAK void DMA9_IRQHandler(void) +{ DMA9_DriverIRQHandler(); +} + +WEAK void DMA10_IRQHandler(void) +{ DMA10_DriverIRQHandler(); +} + +WEAK void DMA11_IRQHandler(void) +{ DMA11_DriverIRQHandler(); +} + +WEAK void DMA12_IRQHandler(void) +{ DMA12_DriverIRQHandler(); +} + +WEAK void DMA13_IRQHandler(void) +{ DMA13_DriverIRQHandler(); +} + +WEAK void DMA14_IRQHandler(void) +{ DMA14_DriverIRQHandler(); +} + +WEAK void DMA15_IRQHandler(void) +{ DMA15_DriverIRQHandler(); +} + +WEAK void DMA_Error_IRQHandler(void) +{ DMA_Error_DriverIRQHandler(); +} + +WEAK void MCM_IRQHandler(void) +{ MCM_DriverIRQHandler(); +} + +WEAK void FTFE_IRQHandler(void) +{ FTFE_DriverIRQHandler(); +} + +WEAK void Read_Collision_IRQHandler(void) +{ Read_Collision_DriverIRQHandler(); +} + +WEAK void LVD_LVW_IRQHandler(void) +{ LVD_LVW_DriverIRQHandler(); +} + +WEAK void LLWU_IRQHandler(void) +{ LLWU_DriverIRQHandler(); +} + +WEAK void WDOG_EWM_IRQHandler(void) +{ WDOG_EWM_DriverIRQHandler(); +} + +WEAK void RNG_IRQHandler(void) +{ RNG_DriverIRQHandler(); +} + +WEAK void I2C0_IRQHandler(void) +{ I2C0_DriverIRQHandler(); +} + +WEAK void I2C1_IRQHandler(void) +{ I2C1_DriverIRQHandler(); +} + +WEAK void SPI0_IRQHandler(void) +{ SPI0_DriverIRQHandler(); +} + +WEAK void SPI1_IRQHandler(void) +{ SPI1_DriverIRQHandler(); +} + +WEAK void I2S0_Tx_IRQHandler(void) +{ I2S0_Tx_DriverIRQHandler(); +} + +WEAK void I2S0_Rx_IRQHandler(void) +{ I2S0_Rx_DriverIRQHandler(); +} + +WEAK void UART0_LON_IRQHandler(void) +{ UART0_LON_DriverIRQHandler(); +} + +WEAK void UART0_RX_TX_IRQHandler(void) +{ UART0_RX_TX_DriverIRQHandler(); +} + +WEAK void UART0_ERR_IRQHandler(void) +{ UART0_ERR_DriverIRQHandler(); +} + +WEAK void UART1_RX_TX_IRQHandler(void) +{ UART1_RX_TX_DriverIRQHandler(); +} + +WEAK void UART1_ERR_IRQHandler(void) +{ UART1_ERR_DriverIRQHandler(); +} + +WEAK void UART2_RX_TX_IRQHandler(void) +{ UART2_RX_TX_DriverIRQHandler(); +} + +WEAK void UART2_ERR_IRQHandler(void) +{ UART2_ERR_DriverIRQHandler(); +} + +WEAK void UART3_RX_TX_IRQHandler(void) +{ UART3_RX_TX_DriverIRQHandler(); +} + +WEAK void UART3_ERR_IRQHandler(void) +{ UART3_ERR_DriverIRQHandler(); +} + +WEAK void ADC0_IRQHandler(void) +{ ADC0_DriverIRQHandler(); +} + +WEAK void CMP0_IRQHandler(void) +{ CMP0_DriverIRQHandler(); +} + +WEAK void CMP1_IRQHandler(void) +{ CMP1_DriverIRQHandler(); +} + +WEAK void FTM0_IRQHandler(void) +{ FTM0_DriverIRQHandler(); +} + +WEAK void FTM1_IRQHandler(void) +{ FTM1_DriverIRQHandler(); +} + +WEAK void FTM2_IRQHandler(void) +{ FTM2_DriverIRQHandler(); +} + +WEAK void CMT_IRQHandler(void) +{ CMT_DriverIRQHandler(); +} + +WEAK void RTC_IRQHandler(void) +{ RTC_DriverIRQHandler(); +} + +WEAK void RTC_Seconds_IRQHandler(void) +{ RTC_Seconds_DriverIRQHandler(); +} + +WEAK void PIT0_IRQHandler(void) +{ PIT0_DriverIRQHandler(); +} + +WEAK void PIT1_IRQHandler(void) +{ PIT1_DriverIRQHandler(); +} + +WEAK void PIT2_IRQHandler(void) +{ PIT2_DriverIRQHandler(); +} + +WEAK void PIT3_IRQHandler(void) +{ PIT3_DriverIRQHandler(); +} + +WEAK void PDB0_IRQHandler(void) +{ PDB0_DriverIRQHandler(); +} + +WEAK void USB0_IRQHandler(void) +{ USB0_DriverIRQHandler(); +} + +WEAK void USBDCD_IRQHandler(void) +{ USBDCD_DriverIRQHandler(); +} + +WEAK void Reserved71_IRQHandler(void) +{ Reserved71_DriverIRQHandler(); +} + +WEAK void DAC0_IRQHandler(void) +{ DAC0_DriverIRQHandler(); +} + +WEAK void MCG_IRQHandler(void) +{ MCG_DriverIRQHandler(); +} + +WEAK void LPTMR0_IRQHandler(void) +{ LPTMR0_DriverIRQHandler(); +} + +WEAK void PORTA_IRQHandler(void) +{ PORTA_DriverIRQHandler(); +} + +WEAK void PORTB_IRQHandler(void) +{ PORTB_DriverIRQHandler(); +} + +WEAK void PORTC_IRQHandler(void) +{ PORTC_DriverIRQHandler(); +} + +WEAK void PORTD_IRQHandler(void) +{ PORTD_DriverIRQHandler(); +} + +WEAK void PORTE_IRQHandler(void) +{ PORTE_DriverIRQHandler(); +} + +WEAK void SWI_IRQHandler(void) +{ SWI_DriverIRQHandler(); +} + +WEAK void SPI2_IRQHandler(void) +{ SPI2_DriverIRQHandler(); +} + +WEAK void UART4_RX_TX_IRQHandler(void) +{ UART4_RX_TX_DriverIRQHandler(); +} + +WEAK void UART4_ERR_IRQHandler(void) +{ UART4_ERR_DriverIRQHandler(); +} + +WEAK void UART5_RX_TX_IRQHandler(void) +{ UART5_RX_TX_DriverIRQHandler(); +} + +WEAK void UART5_ERR_IRQHandler(void) +{ UART5_ERR_DriverIRQHandler(); +} + +WEAK void CMP2_IRQHandler(void) +{ CMP2_DriverIRQHandler(); +} + +WEAK void FTM3_IRQHandler(void) +{ FTM3_DriverIRQHandler(); +} + +WEAK void DAC1_IRQHandler(void) +{ DAC1_DriverIRQHandler(); +} + +WEAK void ADC1_IRQHandler(void) +{ ADC1_DriverIRQHandler(); +} + +WEAK void I2C2_IRQHandler(void) +{ I2C2_DriverIRQHandler(); +} + +WEAK void CAN0_ORed_Message_buffer_IRQHandler(void) +{ CAN0_DriverIRQHandler(); +} + +WEAK void CAN0_Bus_Off_IRQHandler(void) +{ CAN0_DriverIRQHandler(); +} + +WEAK void CAN0_Error_IRQHandler(void) +{ CAN0_DriverIRQHandler(); +} + +WEAK void CAN0_Tx_Warning_IRQHandler(void) +{ CAN0_DriverIRQHandler(); +} + +WEAK void CAN0_Rx_Warning_IRQHandler(void) +{ CAN0_DriverIRQHandler(); +} + +WEAK void CAN0_Wake_Up_IRQHandler(void) +{ CAN0_DriverIRQHandler(); +} + +WEAK void SDHC_IRQHandler(void) +{ SDHC_DriverIRQHandler(); +} + +WEAK void ENET_1588_Timer_IRQHandler(void) +{ ENET_1588_Timer_DriverIRQHandler(); +} + +WEAK void ENET_Transmit_IRQHandler(void) +{ ENET_Transmit_DriverIRQHandler(); +} + +WEAK void ENET_Receive_IRQHandler(void) +{ ENET_Receive_DriverIRQHandler(); +} + +WEAK void ENET_Error_IRQHandler(void) +{ ENET_Error_DriverIRQHandler(); +} + +//***************************************************************************** + +#if defined (DEBUG) +#pragma GCC pop_options +#endif // (DEBUG) diff --git a/usb/device/class/usb_device_audio.c b/usb/device/class/usb_device_audio.c new file mode 100644 index 0000000..88c7978 --- /dev/null +++ b/usb/device/class/usb_device_audio.c @@ -0,0 +1,1817 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device.h" + +#include "usb_device_class.h" + +#if ((defined(USB_DEVICE_CONFIG_AUDIO)) && (USB_DEVICE_CONFIG_AUDIO > 0U)) +#include "usb_device_audio.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static usb_status_t USB_DeviceAudioAllocateHandle(usb_device_audio_struct_t **handle); +static usb_status_t USB_DeviceAudioFreeHandle(usb_device_audio_struct_t *handle); +usb_status_t USB_DeviceAudioInterruptIn(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam); +usb_status_t USB_DeviceAudioIsochronousIn(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam); +usb_status_t USB_DeviceAudioIsochronousOut(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam); +usb_status_t USB_DeviceAudioStreamEndpointsInit(usb_device_audio_struct_t *audioHandle); +usb_status_t USB_DeviceAudioStreamEndpointsDeinit(usb_device_audio_struct_t *audioHandle); +usb_status_t USB_DeviceAudioControlEndpointsInit(usb_device_audio_struct_t *audioHandle); +usb_status_t USB_DeviceAudioControlEndpointsDeinit(usb_device_audio_struct_t *audioHandle); +usb_status_t USB_DeviceAudioGetCurAudioFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); +usb_status_t USB_DeviceAudioGetMinAudioFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); +usb_status_t USB_DeviceAudioGetMaxAudioFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); +usb_status_t USB_DeviceAudioGetResAudioFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); +usb_status_t USB_DeviceAudioSetControlTerminal(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); +usb_status_t USB_DeviceAudioSetCurAudioFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); +usb_status_t USB_DeviceAudioSetControlTerminal(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); +usb_status_t USB_DeviceAudioSetCurAudioFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); +usb_status_t USB_DeviceAudioSetMinAudioFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); +usb_status_t USB_DeviceAudioSetMaxAudioFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); +usb_status_t USB_DeviceAudioSetResAudioFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); +usb_status_t USB_DeviceAudioSetFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); +usb_status_t USB_DeviceAudioSetRequestEndpoint(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); +usb_status_t USB_DeviceAudioGetRequestEndpoint(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); +usb_status_t USB_DeviceAudioGetControlTerminal(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); +usb_status_t USB_DeviceAudioGetFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); +usb_status_t USB_DeviceAudioSetRequestInterface(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); +usb_status_t USB_DeviceAudioGetRequestInterface(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_audio_struct_t + s_UsbDeviceAudioHandle[USB_DEVICE_CONFIG_AUDIO]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Allocate a device audio class handle. + * + * This function allocates a device audio class handle. + * + * @param handle It is out parameter, is used to return pointer of the device audio class handle to the caller. + * + * @retval kStatus_USB_Success Get a device audio class handle successfully. + * @retval kStatus_USB_Busy Cannot allocate a device audio class handle. + */ +static usb_status_t USB_DeviceAudioAllocateHandle(usb_device_audio_struct_t **handle) +{ + int32_t count; + USB_OSA_SR_ALLOC(); + + USB_OSA_ENTER_CRITICAL(); + for (count = 0; count < USB_DEVICE_CONFIG_AUDIO; count++) + { + if (NULL == s_UsbDeviceAudioHandle[count].handle) + { + *handle = &s_UsbDeviceAudioHandle[count]; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + } + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Busy; +} + +/*! + * @brief Free a device audio class handle. + * + * This function frees a device audio class handle. + * + * @param handle The device audio class handle. + * + * @retval kStatus_USB_Success Free device audio class handle successfully. + */ +static usb_status_t USB_DeviceAudioFreeHandle(usb_device_audio_struct_t *handle) +{ + USB_OSA_SR_ALLOC(); + + USB_OSA_ENTER_CRITICAL(); + handle->handle = NULL; + handle->configStruct = (usb_device_class_config_struct_t *)NULL; + handle->configuration = 0U; + handle->controlAlternate = 0U; + handle->streamAlternate = 0U; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; +} + +/*! + * @brief Interrupt IN endpoint callback function. + * + * This callback function is used to notify uplayer the transfser result of a transfer. + * This callback pointer is passed when the interrupt IN pipe initialized. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The result of the interrupt IN pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the audio class handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioInterruptIn(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_audio_struct_t *audioHandle; + usb_status_t error = kStatus_USB_Error; + + /* Get the audio class handle */ + audioHandle = (usb_device_audio_struct_t *)callbackParam; + + if (!audioHandle) + { + return kStatus_USB_InvalidHandle; + } + + if ((NULL != audioHandle->configStruct) && (audioHandle->configStruct->classCallback)) + { + /* Notify the application control data sent by calling the audio class callback. + classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, + kUSB_DeviceAudioEventControlSendResponse, message); + } + + return error; +} + +/*! + * @brief ISO IN endpoint callback function. + * + * This callback function is used to notify uplayer the transfser result of a transfer. + * This callback pointer is passed when the ISO IN pipe initialized. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The result of the ISO IN pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the audio class handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioIsochronousIn(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_audio_struct_t *audioHandle; + usb_status_t error = kStatus_USB_Error; + + /* Get the audio class handle */ + audioHandle = (usb_device_audio_struct_t *)callbackParam; + if (!audioHandle) + { + return kStatus_USB_InvalidHandle; + } + audioHandle->streamInPipeBusy = 0U; + if ((NULL != audioHandle->configStruct) && (audioHandle->configStruct->classCallback)) + { + /* Notify the application stream data sent by calling the audio class callback. + classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, + kUSB_DeviceAudioEventStreamSendResponse, message); + } + + return error; +} + +/*! + * @brief ISO OUT endpoint callback function. + * + * This callback function is used to notify uplayer the transfser result of a transfer. + * This callback pointer is passed when the ISO OUT pipe initialized. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The result of the ISO OUT pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the audio class handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioIsochronousOut(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_audio_struct_t *audioHandle; + usb_status_t error = kStatus_USB_Error; + + /* Get the audio class handle */ + audioHandle = (usb_device_audio_struct_t *)callbackParam; + if (!audioHandle) + { + return kStatus_USB_InvalidHandle; + } + audioHandle->streamOutPipeBusy = 0U; + + if ((NULL != audioHandle->configStruct) && (audioHandle->configStruct->classCallback)) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, + kUSB_DeviceAudioEventStreamRecvResponse, message); + } + return error; +} + +/*! + * @brief Initialize the stream endpoints of the audio class. + * + * This callback function is used to initialize the stream endpoints of the audio class. + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioStreamEndpointsInit(usb_device_audio_struct_t *audioHandle) +{ + usb_device_interface_list_t *interfaceList; + usb_device_interface_struct_t *interface = (usb_device_interface_struct_t *)NULL; + usb_status_t error = kStatus_USB_Error; + + /* Check the configuration is valid or not. */ + if (!audioHandle->configuration) + { + return error; + } + + /* Check the configuration is valid or not. */ + if (audioHandle->configuration > audioHandle->configStruct->classInfomation->configurations) + { + return error; + } + + if (NULL == audioHandle->configStruct->classInfomation->interfaceList) + { + return error; + } + + /* Get the interface list of the new configuration. */ + interfaceList = &audioHandle->configStruct->classInfomation->interfaceList[audioHandle->configuration - 1]; + + /* Find stream interface by using the alternate setting of the interface. */ + for (int count = 0U; count < interfaceList->count; count++) + { + if ((USB_DEVICE_CONFIG_AUDIO_CLASS_CODE == interfaceList->interfaces[count].classCode) && + (USB_DEVICE_AUDIO_STREAM_SUBCLASS == interfaceList->interfaces[count].subclassCode)) + { + for (int index = 0; index < interfaceList->interfaces[count].count; index++) + { + if (interfaceList->interfaces[count].interface[index].alternateSetting == audioHandle->streamAlternate) + { + interface = &interfaceList->interfaces[count].interface[index]; + break; + } + } + audioHandle->streamInterfaceNumber = interfaceList->interfaces[count].interfaceNumber; + break; + } + } + if (!interface) + { + return error; + } + /* Keep new stream interface handle. */ + audioHandle->streamInterfaceHandle = interface; + + /* Initialize the endpoints of the new interface. */ + for (int count = 0U; count < interface->endpointList.count; count++) + { + usb_device_endpoint_init_struct_t epInitStruct; + usb_device_endpoint_callback_struct_t epCallback; + epInitStruct.zlt = 0U; + epInitStruct.interval = interface->endpointList.endpoint[count].interval; + epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress; + epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize; + epInitStruct.transferType = interface->endpointList.endpoint[count].transferType; + + if ((USB_ENDPOINT_ISOCHRONOUS == (epInitStruct.transferType & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK)) && + (USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))) + { + epCallback.callbackFn = USB_DeviceAudioIsochronousIn; + } + else + { + epCallback.callbackFn = USB_DeviceAudioIsochronousOut; + } + epCallback.callbackParam = audioHandle; + + error = USB_DeviceInitEndpoint(audioHandle->handle, &epInitStruct, &epCallback); + } + return error; +} + +/*! + * @brief De-initialize the stream endpoints of the audio class. + * + * This callback function is used to de-initialize the stream endpoints of the audio class. + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioStreamEndpointsDeinit(usb_device_audio_struct_t *audioHandle) +{ + usb_status_t error = kStatus_USB_Error; + usb_device_endpoint_callback_message_struct_t message; + + if (!audioHandle->streamInterfaceHandle) + { + return error; + } + /* De-initialize all stream endpoints of the interface */ + for (int count = 0U; count < audioHandle->streamInterfaceHandle->endpointList.count; count++) + { + error = USB_DeviceDeinitEndpoint( + audioHandle->handle, audioHandle->streamInterfaceHandle->endpointList.endpoint[count].endpointAddress); + } + + for (int count = 0U; count < audioHandle->streamInterfaceHandle->endpointList.count; count++) + { + if ((audioHandle->streamInterfaceHandle->endpointList.endpoint[count].endpointAddress & + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT == + USB_IN) + { + if (audioHandle->streamInPipeBusy) + { + message.length = USB_UNINITIALIZED_VAL_32; + USB_DeviceAudioIsochronousIn(audioHandle->handle, &message, audioHandle); + } + } + else + { + if (audioHandle->streamOutPipeBusy) + { + message.length = USB_UNINITIALIZED_VAL_32; + USB_DeviceAudioIsochronousOut(audioHandle->handle, &message, audioHandle); + } + } + } + + audioHandle->streamInterfaceHandle = NULL; + return error; +} + +/*! + * @brief Initialize the control endpoints of the audio class. + * + * This callback function is used to initialize the control endpoints of the audio class. + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioControlEndpointsInit(usb_device_audio_struct_t *audioHandle) +{ + usb_device_interface_list_t *interfaceList; + usb_device_interface_struct_t *interface = (usb_device_interface_struct_t *)NULL; + usb_status_t error = kStatus_USB_Error; + + /* Check the configuration is valid or not. */ + if (!audioHandle->configuration) + { + return error; + } + + /* Check the configuration is valid or not. */ + if (audioHandle->configuration > audioHandle->configStruct->classInfomation->configurations) + { + return error; + } + + if (NULL == audioHandle->configStruct->classInfomation->interfaceList) + { + return error; + } + + /* Get the control interface list of the new configuration. */ + interfaceList = &audioHandle->configStruct->classInfomation->interfaceList[audioHandle->configuration - 1]; + + /* Find control interface by using the alternate setting of the interface. */ + for (int count = 0U; count < interfaceList->count; count++) + { + if ((USB_DEVICE_CONFIG_AUDIO_CLASS_CODE == interfaceList->interfaces[count].classCode) && + (USB_DEVICE_AUDIO_CONTROL_SUBCLASS == interfaceList->interfaces[count].subclassCode)) + { + for (int index = 0U; index < interfaceList->interfaces[count].count; index++) + { + if (interfaceList->interfaces[count].interface[index].alternateSetting == audioHandle->controlAlternate) + { + interface = &interfaceList->interfaces[count].interface[index]; + break; + } + } + audioHandle->controlInterfaceNumber = interfaceList->interfaces[count].interfaceNumber; + break; + } + } + if (!interface) + { + return error; + } + /* Keep new control interface handle. */ + audioHandle->controlInterfaceHandle = interface; + + /* Initialize the control endpoints of the new interface. */ + for (int count = 0U; count < interface->endpointList.count; count++) + { + usb_device_endpoint_init_struct_t epInitStruct; + usb_device_endpoint_callback_struct_t epCallback; + epInitStruct.zlt = 0U; + epInitStruct.interval = interface->endpointList.endpoint[count].interval; + epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress; + epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize; + epInitStruct.transferType = interface->endpointList.endpoint[count].transferType; + + if ((USB_ENDPOINT_INTERRUPT == (epInitStruct.transferType & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK)) && + (USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))) + { + epCallback.callbackFn = USB_DeviceAudioInterruptIn; + } + else + { + continue; + } + epCallback.callbackParam = audioHandle; + + error = USB_DeviceInitEndpoint(audioHandle->handle, &epInitStruct, &epCallback); + } + return error; +} + +/*! + * @brief De-initialize the control endpoints of the audio class. + * + * This callback function is used to de-initialize the control endpoints of the audio class. + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioControlEndpointsDeinit(usb_device_audio_struct_t *audioHandle) +{ + usb_status_t error = kStatus_USB_Error; + + if (!audioHandle->controlInterfaceHandle) + { + return error; + } + /* De-initialize all control endpoints of the interface */ + for (int count = 0U; count < audioHandle->controlInterfaceHandle->endpointList.count; count++) + { + error = USB_DeviceDeinitEndpoint( + audioHandle->handle, audioHandle->controlInterfaceHandle->endpointList.endpoint[count].endpointAddress); + } + audioHandle->controlInterfaceHandle = NULL; + return error; +} + +/*! + * @brief Handle the audio device current volume/control feature unit request. + * + * This callback function provides flexibility to add class and vendor specific requests + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioGetCurAudioFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_Error; + uint8_t controlSelector = (controlRequest->setup->wValue >> 0x08) & 0xFFU; + uint32_t audioCommand = 0U; + + /* Select SET request Control Feature Unit Module */ + switch (controlSelector) + { + case USB_DEVICE_AUDIO_MUTE_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_CUR_MUTE_CONTROL; + break; + case USB_DEVICE_AUDIO_VOLUME_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_CUR_VOLUME_CONTROL; + break; + case USB_DEVICE_AUDIO_BASS_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_CUR_BASS_CONTROL; + break; + case USB_DEVICE_AUDIO_MID_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_CUR_MID_CONTROL; + break; + case USB_DEVICE_AUDIO_TREBLE_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_CUR_TREBLE_CONTROL; + break; + case USB_DEVICE_AUDIO_GRAPHIC_EQUALIZER_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_CUR_GRAPHIC_EQUALIZER_CONTROL; + break; + case USB_DEVICE_AUDIO_AUTOMATIC_GAIN_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_CUR_AUTOMATIC_GAIN_CONTROL; + break; + case USB_DEVICE_AUDIO_DELAY_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_CUR_DELAY_CONTROL; + break; + case USB_DEVICE_AUDIO_BASS_BOOST_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_CUR_BASS_BOOST_CONTROL; + break; + case USB_DEVICE_AUDIO_LOUDNESS_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_CUR_LOUDNESS_CONTROL; + break; + default: + break; + } + if ((audioCommand) && (NULL != audioHandle->configStruct) && (audioHandle->configStruct->classCallback)) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest); + } + + return error; +} + +/*! + * @brief Handle the audio device minimum volume/control feature unit request. + * + * This callback function provides flexibility to add class and vendor specific requests + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioGetMinAudioFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_Error; + uint8_t controlSelector = (controlRequest->setup->wValue >> 0x08) & 0xFFU; + uint32_t audioCommand = 0; + + /* Select SET request Control Feature Unit Module */ + switch (controlSelector) + { + case USB_DEVICE_AUDIO_VOLUME_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_MIN_VOLUME_CONTROL; + break; + case USB_DEVICE_AUDIO_BASS_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_MIN_BASS_CONTROL; + break; + case USB_DEVICE_AUDIO_MID_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_MIN_MID_CONTROL; + break; + case USB_DEVICE_AUDIO_TREBLE_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_MIN_TREBLE_CONTROL; + break; + case USB_DEVICE_AUDIO_GRAPHIC_EQUALIZER_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_MIN_GRAPHIC_EQUALIZER_CONTROL; + break; + case USB_DEVICE_AUDIO_DELAY_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_MIN_DELAY_CONTROL; + break; + default: + break; + } + if ((audioCommand) && (NULL != audioHandle->configStruct) && (audioHandle->configStruct->classCallback)) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest); + } + return error; +} + +/*! + * @brief Handle the audio device maximum volume/control feature unit request. + * + * This callback function provides flexibility to add class and vendor specific requests + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioGetMaxAudioFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_Error; + uint8_t controlSelector = (controlRequest->setup->wValue >> 0x08) & 0xFFU; + uint32_t audioCommand = 0; + + /* Select SET request Control Feature Unit Module */ + switch (controlSelector) + { + case USB_DEVICE_AUDIO_VOLUME_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_MAX_VOLUME_CONTROL; + break; + case USB_DEVICE_AUDIO_BASS_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_MAX_BASS_CONTROL; + break; + case USB_DEVICE_AUDIO_MID_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_MAX_MID_CONTROL; + break; + case USB_DEVICE_AUDIO_TREBLE_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_MAX_TREBLE_CONTROL; + break; + case USB_DEVICE_AUDIO_GRAPHIC_EQUALIZER_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_MAX_GRAPHIC_EQUALIZER_CONTROL; + break; + case USB_DEVICE_AUDIO_DELAY_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_MAX_DELAY_CONTROL; + break; + default: + break; + } + if ((audioCommand) && (NULL != audioHandle->configStruct) && (audioHandle->configStruct->classCallback)) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest); + } + return error; +} + +/*! + * @brief Handle the audio device res volume/control feature unit request. + * + * This callback function provides flexibility to add class and vendor specific requests + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioGetResAudioFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_Error; + uint8_t controlSelector = (controlRequest->setup->wValue >> 0x08) & 0xFFU; + uint32_t audioCommand = 0; + + /* Select SET request Control Feature Unit Module */ + switch (controlSelector) + { + case USB_DEVICE_AUDIO_VOLUME_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_RES_VOLUME_CONTROL; + break; + case USB_DEVICE_AUDIO_BASS_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_RES_BASS_CONTROL; + break; + case USB_DEVICE_AUDIO_MID_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_RES_MID_CONTROL; + break; + case USB_DEVICE_AUDIO_TREBLE_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_RES_TREBLE_CONTROL; + break; + case USB_DEVICE_AUDIO_GRAPHIC_EQUALIZER_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_RES_GRAPHIC_EQUALIZER_CONTROL; + break; + case USB_DEVICE_AUDIO_DELAY_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_RES_DELAY_CONTROL; + break; + default: + break; + } + if ((audioCommand) && (NULL != audioHandle->configStruct) && (audioHandle->configStruct->classCallback)) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit*/ + error = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest); + } + + return error; +} + +/*! + * @brief Handle the audio device set control terminal request. + * + * This callback function provides flexibility to add class and vendor specific requests + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioSetControlTerminal(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_Error; + + return error; +} + +/*! + * @brief Handle the audio device set current volume/control feature unit request. + * + * This callback function provides flexibility to add class and vendor specific requests + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioSetCurAudioFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_Error; + uint8_t controlSelector = (controlRequest->setup->wValue >> 0x08) & 0xFFU; + uint32_t audioCommand = 0; + + switch (controlSelector) + { + case USB_DEVICE_AUDIO_MUTE_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_CUR_MUTE_CONTROL; + break; + case USB_DEVICE_AUDIO_VOLUME_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_CUR_VOLUME_CONTROL; + break; + case USB_DEVICE_AUDIO_BASS_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_CUR_BASS_CONTROL; + break; + case USB_DEVICE_AUDIO_MID_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_CUR_MID_CONTROL; + break; + case USB_DEVICE_AUDIO_TREBLE_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_CUR_TREBLE_CONTROL; + break; + case USB_DEVICE_AUDIO_GRAPHIC_EQUALIZER_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_CUR_GRAPHIC_EQUALIZER_CONTROL; + break; + case USB_DEVICE_AUDIO_AUTOMATIC_GAIN_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_CUR_AUTOMATIC_GAIN_CONTROL; + break; + case USB_DEVICE_AUDIO_DELAY_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_CUR_DELAY_CONTROL; + break; + case USB_DEVICE_AUDIO_BASS_BOOST_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_CUR_BASS_BOOST_CONTROL; + break; + case USB_DEVICE_AUDIO_LOUDNESS_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_CUR_LOUDNESS_CONTROL; + break; + default: + break; + } + if ((audioCommand) && (NULL != audioHandle->configStruct) && (audioHandle->configStruct->classCallback)) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest); + } + return error; +} + +/*! + * @brief Handle the audio device set minimum volume/control feature unit request. + * + * This callback function provides flexibility to add class and vendor specific requests + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioSetMinAudioFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_Error; + uint8_t controlSelector = (controlRequest->setup->wValue >> 0x08) & 0xFFU; + uint32_t audioCommand = 0; + switch (controlSelector) + { + case USB_DEVICE_AUDIO_VOLUME_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_MIN_VOLUME_CONTROL; + break; + case USB_DEVICE_AUDIO_BASS_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_MIN_BASS_CONTROL; + break; + case USB_DEVICE_AUDIO_MID_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_MIN_MID_CONTROL; + break; + case USB_DEVICE_AUDIO_TREBLE_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_MIN_TREBLE_CONTROL; + break; + case USB_DEVICE_AUDIO_GRAPHIC_EQUALIZER_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_MIN_GRAPHIC_EQUALIZER_CONTROL; + break; + case USB_DEVICE_AUDIO_DELAY_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_MIN_DELAY_CONTROL; + break; + default: + break; + } + if ((audioCommand) && (NULL != audioHandle->configStruct) && (audioHandle->configStruct->classCallback)) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest); + } + + return error; +} + +/*! + * @brief Handle the audio device maximum volume/control feature unit request. + * + * This callback function provides flexibility to add class and vendor specific requests + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioSetMaxAudioFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_Error; + uint8_t controlSelector = (controlRequest->setup->wValue >> 0x08) & 0xFFU; + uint32_t audioCommand = 0; + switch (controlSelector) + { + case USB_DEVICE_AUDIO_VOLUME_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_MAX_VOLUME_CONTROL; + break; + case USB_DEVICE_AUDIO_BASS_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_MAX_BASS_CONTROL; + break; + case USB_DEVICE_AUDIO_MID_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_MAX_MID_CONTROL; + break; + case USB_DEVICE_AUDIO_TREBLE_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_MAX_TREBLE_CONTROL; + break; + case USB_DEVICE_AUDIO_GRAPHIC_EQUALIZER_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_MAX_GRAPHIC_EQUALIZER_CONTROL; + break; + case USB_DEVICE_AUDIO_DELAY_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_MAX_DELAY_CONTROL; + break; + default: + break; + } + if ((audioCommand) && (NULL != audioHandle->configStruct) && (audioHandle->configStruct->classCallback)) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest); + } + + return error; +} + +/*! + * @brief Handle the audio device set res volume/control feature unit request. + * + * This callback function provides flexibility to add class and vendor specific requests + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioSetResAudioFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_Error; + uint8_t controlSelector = (controlRequest->setup->wValue >> 0x08) & 0xFFU; + uint32_t audioCommand = 0; + switch (controlSelector) + { + case USB_DEVICE_AUDIO_VOLUME_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_RES_VOLUME_CONTROL; + break; + case USB_DEVICE_AUDIO_BASS_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_RES_BASS_CONTROL; + break; + case USB_DEVICE_AUDIO_MID_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_RES_MID_CONTROL; + break; + case USB_DEVICE_AUDIO_TREBLE_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_RES_TREBLE_CONTROL; + break; + case USB_DEVICE_AUDIO_GRAPHIC_EQUALIZER_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_RES_GRAPHIC_EQUALIZER_CONTROL; + break; + case USB_DEVICE_AUDIO_DELAY_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_RES_DELAY_CONTROL; + break; + default: + break; + } + if ((audioCommand) && (NULL != audioHandle->configStruct) && (audioHandle->configStruct->classCallback)) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest); + } + return error; +} + +/*! + * @brief Handle the audio device set feature unit request. + * + * This callback function provides flexibility to add class and vendor specific requests + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioSetFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_Error; + /* Select SET request Control Feature Unit Module */ + switch (controlRequest->setup->bRequest) + { + case USB_DEVICE_AUDIO_SET_CUR_VOLUME_REQUEST: + error = USB_DeviceAudioSetCurAudioFeatureUnit(audioHandle, controlRequest); + break; + case USB_DEVICE_AUDIO_SET_MIN_VOLUME_REQUEST: + error = USB_DeviceAudioSetMinAudioFeatureUnit(audioHandle, controlRequest); + break; + case USB_DEVICE_AUDIO_SET_MAX_VOLUME_REQUEST: + error = USB_DeviceAudioSetMaxAudioFeatureUnit(audioHandle, controlRequest); + break; + case USB_DEVICE_AUDIO_SET_RES_VOLUME_REQUEST: + error = USB_DeviceAudioSetResAudioFeatureUnit(audioHandle, controlRequest); + break; + default: + break; + } + return error; +} + +/*! + * @brief Handle the audio device set request endpoint. + * + * This callback function provides flexibility to add class and vendor specific requests + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioSetRequestEndpoint(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_Error; + uint8_t controlSelector = (controlRequest->setup->wValue >> 0x08) & 0xFFU; + uint32_t audioCommand = 0; + + /* Select SET request Control Feature Unit Module */ + switch (controlRequest->setup->bRequest) + { + case USB_DEVICE_AUDIO_SET_CUR_VOLUME_REQUEST: + switch (controlSelector) + { + case USB_DEVICE_AUDIO_SAMPLING_FREQ_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_CUR_SAMPLING_FREQ_CONTROL; + break; + case USB_DEVICE_AUDIO_PITCH_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_CUR_PITCH_CONTROL; + break; + default: + break; + } + break; + case USB_DEVICE_AUDIO_SET_MIN_VOLUME_REQUEST: + switch (controlSelector) + { + case USB_DEVICE_AUDIO_SAMPLING_FREQ_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_MIN_SAMPLING_FREQ_CONTROL; + break; + default: + break; + } + break; + case USB_DEVICE_AUDIO_SET_MAX_VOLUME_REQUEST: + switch (controlSelector) + { + case USB_DEVICE_AUDIO_SAMPLING_FREQ_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_MAX_SAMPLING_FREQ_CONTROL; + break; + default: + break; + } + break; + case USB_DEVICE_AUDIO_SET_RES_VOLUME_REQUEST: + switch (controlSelector) + { + case USB_DEVICE_AUDIO_SAMPLING_FREQ_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_SET_RES_SAMPLING_FREQ_CONTROL; + break; + default: + break; + } + break; + + default: + break; + } + if ((audioCommand) && (NULL != audioHandle->configStruct) && (audioHandle->configStruct->classCallback)) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest); + } + return error; +} + +/*! + * @brief Handle the audio device get request endpoint. + * + * This callback function provides flexibility to add class and vendor specific requests + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioGetRequestEndpoint(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_Error; + uint8_t controlSelector = (controlRequest->setup->wValue >> 0x08) & 0xFFU; + uint32_t audioCommand = 0; + /* Select SET request Control Feature Unit Module */ + switch (controlRequest->setup->bRequest) + { + case USB_DEVICE_AUDIO_GET_CUR_VOLUME_REQUEST: + switch (controlSelector) + { + case USB_DEVICE_AUDIO_SAMPLING_FREQ_CONTROL_SELECTOR: + + audioCommand = USB_DEVICE_AUDIO_GET_CUR_SAMPLING_FREQ_CONTROL; + break; + default: + break; + } + break; + case USB_DEVICE_AUDIO_GET_MIN_VOLUME_REQUEST: + switch (controlSelector) + { + case USB_DEVICE_AUDIO_SAMPLING_FREQ_CONTROL_SELECTOR: + + audioCommand = USB_DEVICE_AUDIO_GET_MIN_SAMPLING_FREQ_CONTROL; + break; + default: + break; + } + break; + case USB_DEVICE_AUDIO_GET_MAX_VOLUME_REQUEST: + switch (controlSelector) + { + case USB_DEVICE_AUDIO_SAMPLING_FREQ_CONTROL_SELECTOR: + + audioCommand = USB_DEVICE_AUDIO_GET_MAX_SAMPLING_FREQ_CONTROL; + break; + default: + break; + } + break; + case USB_DEVICE_AUDIO_GET_RES_VOLUME_REQUEST: + switch (controlSelector) + { + case USB_DEVICE_AUDIO_SAMPLING_FREQ_CONTROL_SELECTOR: + audioCommand = USB_DEVICE_AUDIO_GET_RES_SAMPLING_FREQ_CONTROL; + + break; + default: + break; + } + break; + + default: + break; + } + if ((audioCommand) && (NULL != audioHandle->configStruct) && (audioHandle->configStruct->classCallback)) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, controlRequest); + } + return error; +} + +/*! + * @brief Handle the audio device get control terminal request. + * + * This callback function provides flexibility to add class and vendor specific requests + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioGetControlTerminal(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_Error; + + return error; +} + +/*! + * @brief Handle the audio device get feature unit request. + * + * This callback function provides flexibility to add class and vendor specific requests + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioGetFeatureUnit(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_Error; + /* Select SET request Control Feature Unit Module */ + switch (controlRequest->setup->bRequest) + { + case USB_DEVICE_AUDIO_GET_CUR_VOLUME_REQUEST: + error = USB_DeviceAudioGetCurAudioFeatureUnit(audioHandle, controlRequest); + break; + case USB_DEVICE_AUDIO_GET_MIN_VOLUME_REQUEST: + error = USB_DeviceAudioGetMinAudioFeatureUnit(audioHandle, controlRequest); + break; + case USB_DEVICE_AUDIO_GET_MAX_VOLUME_REQUEST: + error = USB_DeviceAudioGetMaxAudioFeatureUnit(audioHandle, controlRequest); + break; + case USB_DEVICE_AUDIO_GET_RES_VOLUME_REQUEST: + error = USB_DeviceAudioGetResAudioFeatureUnit(audioHandle, controlRequest); + break; + default: + break; + } + return error; +} + +/*! + * @brief Handle the audio device set request interface. + * + * This callback function provides flexibility to add class and vendor specific requests + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioSetRequestInterface(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest) +{ + int32_t i; + usb_device_audio_entities_struct_t *entity_list; + usb_status_t error = kStatus_USB_Error; + uint8_t entityId = (uint8_t)(controlRequest->setup->wIndex >> 0x08); + + entity_list = (usb_device_audio_entities_struct_t *)audioHandle->controlInterfaceHandle->classSpecific; + for (i = 0; i < entity_list->count; i++) + { + if (entityId == entity_list->entity[i].entityId) + { + switch (entity_list->entity[i].entityType) + { + case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_OUTPUT_TERMINAL: + /*Select SET Request Control Input Terminal Module */ + error = USB_DeviceAudioSetControlTerminal(audioHandle, controlRequest); + break; + case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_FEATURE_UNIT: + /* Select SET request Control Feature Unit Module */ + error = USB_DeviceAudioSetFeatureUnit(audioHandle, controlRequest); + break; + default: + break; + } + } + } + return error; +} + +/*! + * @brief Handle the audio device get request interface. + * + * This callback function provides flexibility to add class and vendor specific requests + * + * @param audioHandle The device audio class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioGetRequestInterface(usb_device_audio_struct_t *audioHandle, + usb_device_control_request_struct_t *controlRequest) +{ + int32_t i; + usb_device_audio_entities_struct_t *entity_list; + usb_status_t error = kStatus_USB_Error; + uint8_t entityId = (uint8_t)(controlRequest->setup->wIndex >> 0x08); + + entity_list = (usb_device_audio_entities_struct_t *)audioHandle->controlInterfaceHandle->classSpecific; + for (i = 0; i < entity_list->count; i++) + { + if (entityId == entity_list->entity[i].entityId) + { + switch (entity_list->entity[i].entityType) + { + case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_INPUT_TERMINAL: + error = USB_DeviceAudioGetControlTerminal(audioHandle, controlRequest); + break; + case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_FEATURE_UNIT: + error = USB_DeviceAudioGetFeatureUnit(audioHandle, controlRequest); + break; + default: + break; + } + } + } + return error; +} + +/*! + * @brief Handle the event passed to the audio class. + * + * This function handles the event passed to the audio class. + * + * @param handle The audio class handle, got from the usb_device_class_config_struct_t::classHandle. + * @param event The event codes. Please refer to the enumeration usb_device_class_event_t. + * @param param The param type is determined by the event code. + * + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The device handle not be found. + * @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe will be stalled by the caller. + */ +usb_status_t USB_DeviceAudioEvent(void *handle, uint32_t event, void *param) +{ + usb_device_audio_struct_t *audioHandle; + usb_status_t error = kStatus_USB_Error; + uint16_t interfaceAlternate; + uint8_t *temp8; + uint8_t alternate; + + if ((!param) || (!handle)) + { + return kStatus_USB_InvalidHandle; + } + + /* Get the audio class handle. */ + audioHandle = (usb_device_audio_struct_t *)handle; + + switch (event) + { + case kUSB_DeviceClassEventDeviceReset: + /* Bus reset, clear the configuration. */ + audioHandle->configuration = 0; + audioHandle->streamOutPipeBusy = 0; + audioHandle->streamInPipeBusy = 0; + break; + case kUSB_DeviceClassEventSetConfiguration: + /* Get the new configuration. */ + temp8 = ((uint8_t *)param); + if (!audioHandle->configStruct) + { + break; + } + if (*temp8 == audioHandle->configuration) + { + break; + } + /* De-initialize the endpoints when current configuration is none zero. */ + if (audioHandle->configuration) + { + error = USB_DeviceAudioControlEndpointsDeinit(audioHandle); + error = USB_DeviceAudioStreamEndpointsDeinit(audioHandle); + } + /* Save new configuration. */ + audioHandle->configuration = *temp8; + /* Clear the alternate setting value. */ + audioHandle->controlAlternate = 0; + /* Clear the alternate setting value. */ + audioHandle->streamAlternate = 0; + audioHandle->controlInterfaceHandle = NULL; + audioHandle->streamInterfaceHandle = NULL; + /* Initialize the control endpoints of the new current configuration by using the alternate setting 0. */ + error = USB_DeviceAudioControlEndpointsInit(audioHandle); + /* Initialize the stream endpoints of the new current configuration by using the alternate setting 0. */ + error = USB_DeviceAudioStreamEndpointsInit(audioHandle); + break; + case kUSB_DeviceClassEventSetInterface: + if (!audioHandle->configStruct) + { + break; + } + /* Get the new alternate setting of the interface */ + interfaceAlternate = *((uint16_t *)param); + /* Get the alternate setting value */ + alternate = (uint8_t)(interfaceAlternate & 0xFFU); + + /* Whether the interface belongs to the class. */ + if (audioHandle->controlInterfaceNumber == ((uint8_t)(interfaceAlternate >> 8U))) + { + /* When the interface is control interface. */ + /* Only handle new alternate setting. */ + if (alternate == audioHandle->controlAlternate) + { + break; + } + /* De-initialize old endpoints */ + error = USB_DeviceAudioControlEndpointsDeinit(audioHandle); + audioHandle->controlAlternate = alternate; + /* Initialize new endpoints */ + error = USB_DeviceAudioControlEndpointsInit(audioHandle); + } + else if (audioHandle->streamInterfaceNumber == ((uint8_t)(interfaceAlternate >> 8U))) + { + /* When the interface is stream interface. */ + /* Only handle new alternate setting. */ + if (alternate == audioHandle->streamAlternate) + { + break; + } + /* De-initialize old endpoints */ + error = USB_DeviceAudioStreamEndpointsDeinit(audioHandle); + audioHandle->streamAlternate = alternate; + /* Initialize new endpoints */ + error = USB_DeviceAudioStreamEndpointsInit(audioHandle); + } + else + { + } + break; + case kUSB_DeviceClassEventSetEndpointHalt: + if (!audioHandle->configStruct) + { + break; + } + /* Get the endpoint address */ + temp8 = ((uint8_t *)param); + if (audioHandle->controlInterfaceHandle) + { + for (int count = 0U; count < audioHandle->controlInterfaceHandle->endpointList.count; count++) + { + if (*temp8 == audioHandle->controlInterfaceHandle->endpointList.endpoint[count].endpointAddress) + { + /* Only stall the endpoint belongs to control interface of the class */ + error = USB_DeviceStallEndpoint(audioHandle->handle, *temp8); + } + } + } + if (audioHandle->streamInterfaceHandle) + { + for (int count = 0U; count < audioHandle->streamInterfaceHandle->endpointList.count; count++) + { + if (*temp8 == audioHandle->streamInterfaceHandle->endpointList.endpoint[count].endpointAddress) + { + /* Only stall the endpoint belongs to stream interface of the class */ + error = USB_DeviceStallEndpoint(audioHandle->handle, *temp8); + } + } + } + break; + case kUSB_DeviceClassEventClearEndpointHalt: + if (!audioHandle->configStruct) + { + break; + } + /* Get the endpoint address */ + temp8 = ((uint8_t *)param); + if (audioHandle->controlInterfaceHandle) + { + for (int count = 0U; count < audioHandle->controlInterfaceHandle->endpointList.count; count++) + { + if (*temp8 == audioHandle->controlInterfaceHandle->endpointList.endpoint[count].endpointAddress) + { + /* Only un-stall the endpoint belongs to control interface of the class */ + error = USB_DeviceUnstallEndpoint(audioHandle->handle, *temp8); + } + } + } + if (audioHandle->streamInterfaceHandle) + { + for (int count = 0U; count < audioHandle->streamInterfaceHandle->endpointList.count; count++) + { + if (*temp8 == audioHandle->streamInterfaceHandle->endpointList.endpoint[count].endpointAddress) + { + /* Only un-stall the endpoint belongs to stream interface of the class */ + error = USB_DeviceUnstallEndpoint(audioHandle->handle, *temp8); + } + } + } + break; + case kUSB_DeviceClassEventClassRequest: +#if USBCFG_AUDIO_CLASS_2_0 + if (param) + { + /* Handle the audio class specific request. */ + usb_device_control_request_struct_t *controlRequest = (usb_device_control_request_struct_t *)param; + uint8_t i; + usb_device_audio_entities_struct_t *entity_list; + uint8_t entityId = (uint8_t)(controlRequest->setup->wIndex >> 0x08); + uint32_t audioCommand = 0; + uint8_t interface_index = (uint8_t)controlRequest->setup->wIndex; + + if (audioHandle->controlInterfaceNumber == interface_index) + { + entity_list = + (usb_device_audio_entities_struct_t *)audioHandle->controlInterfaceHandle->classSpecific; + for (i = 0; i < entity_list->count; i++) + { + if (entityId == entity_list->entity[i].entityId) + { + switch (entity_list->entity[i].entityType) + { + case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_OUTPUT_TERMINAL: + break; + case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_FEATURE_UNIT: + if (((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == + USB_REQUEST_TYPE_DIR_IN)) + { + switch (controlRequest->setup->wValue >> 8) + { + case USB_DEVICE_AUDIO_FU_MUTE_CONTROL: + audioCommand = USB_DEVICE_AUDIO_GET_CUR_MUTE_CONTROL_AUDIO20; + break; + case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL: + if (controlRequest->setup->bRequest == USB_DEVICE_AUDIO_REQUEST_CUR) + { + audioCommand = USB_DEVICE_AUDIO_GET_CUR_VOLUME_CONTROL_AUDIO20; + } + else if (controlRequest->setup->bRequest == + USB_DEVICE_AUDIO_REQUEST_RANGE) + { + audioCommand = USB_DEVICE_AUDIO_GET_RANGE_VOLUME_CONTROL_AUDIO20; + } + else + { + } + break; + default: + break; + } + } + else if (((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == + USB_REQUEST_TYPE_DIR_OUT)) + { + switch (controlRequest->setup->wValue >> 8) + { + case USB_DEVICE_AUDIO_FU_MUTE_CONTROL: + audioCommand = USB_DEVICE_AUDIO_SET_CUR_MUTE_CONTROL_AUDIO20; + break; + case USB_DEVICE_AUDIO_FU_VOLUME_CONTROL: + if (controlRequest->setup->bRequest == USB_DEVICE_AUDIO_REQUEST_CUR) + { + audioCommand = USB_DEVICE_AUDIO_SET_CUR_VOLUME_CONTROL_AUDIO20; + } + break; + default: + break; + } + } + + break; + case USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_CLOCK_SOURCE_UNIT: + if (((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == + USB_REQUEST_TYPE_DIR_IN)) + { + switch (controlRequest->setup->wValue >> 8) + { + case USB_DEVICE_AUDIO_CS_SAM_FREQ_CONTROL: + if (controlRequest->setup->bRequest == USB_DEVICE_AUDIO_REQUEST_CUR) + { + audioCommand = USB_DEVICE_AUDIO_GET_CUR_SAM_FREQ_CONTROL; + } + else if (controlRequest->setup->bRequest == + USB_DEVICE_AUDIO_REQUEST_RANGE) + { + audioCommand = USB_DEVICE_AUDIO_GET_RANGE_SAM_FREQ_CONTROL; + } + else + { + } + break; + case USB_DEVICE_AUDIO_CS_CLOCK_VALID_CONTROL: + audioCommand = USB_DEVICE_AUDIO_GET_CUR_CLOCK_VALID_CONTROL; + break; + default: + break; + } + } + else if (((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == + USB_REQUEST_TYPE_DIR_OUT)) + { + switch (controlRequest->setup->wValue >> 8) + { + case USB_DEVICE_AUDIO_CS_SAM_FREQ_CONTROL: + audioCommand = USB_DEVICE_AUDIO_SET_CUR_SAM_FREQ_CONTROL; + break; + case USB_DEVICE_AUDIO_CS_CLOCK_VALID_CONTROL: + audioCommand = USB_DEVICE_AUDIO_SET_CUR_CLOCK_VALID_CONTROL; + break; + default: + break; + } + } + else + { + } + break; + default: + break; + } + } + } + if ((audioCommand) && (NULL != audioHandle->configStruct) && + (audioHandle->configStruct->classCallback)) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit*/ + error = audioHandle->configStruct->classCallback((class_handle_t)audioHandle, audioCommand, + controlRequest); + } + } + } + break; + +#else + if (param) + { + /* Handle the audio class specific request. */ + usb_device_control_request_struct_t *controlRequest = (usb_device_control_request_struct_t *)param; + if ((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != + USB_REQUEST_TYPE_RECIPIENT_INTERFACE) + { + if (USB_REQUEST_TYPE_TYPE_CLASS == + (controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK)) + { + switch (controlRequest->setup->bmRequestType) + { + case USB_DEVICE_AUDIO_SET_REQUEST_ENDPOINT: + error = USB_DeviceAudioSetRequestEndpoint(audioHandle, controlRequest); + break; + case USB_DEVICE_AUDIO_GET_REQUEST_ENDPOINT: + error = USB_DeviceAudioGetRequestEndpoint(audioHandle, controlRequest); + break; + default: + break; + } + } + } + else + { + uint8_t interface_index = (uint8_t)controlRequest->setup->wIndex; + + if (audioHandle->controlInterfaceNumber == interface_index) + { + if (USB_REQUEST_TYPE_TYPE_CLASS == + (controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK)) + { + switch (controlRequest->setup->bmRequestType) + { + case USB_DEVICE_AUDIO_SET_REQUEST_INTERFACE: + error = USB_DeviceAudioSetRequestInterface(audioHandle, controlRequest); + break; + case USB_DEVICE_AUDIO_GET_REQUEST_INTERFACE: + error = USB_DeviceAudioGetRequestInterface(audioHandle, controlRequest); + break; + default: + break; + } + } + } + } + } + break; +#endif + default: + break; + } + return error; +} + +/*! + * @brief Initialize the audio class. + * + * This function is used to initialize the audio class. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param config The class configuration information. + * @param handle It is out parameter, is used to return pointer of the audio class handle to the caller. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioInit(uint8_t controllerId, usb_device_class_config_struct_t *config, class_handle_t *handle) +{ + usb_device_audio_struct_t *audioHandle; + usb_status_t error = kStatus_USB_Error; + + /* Allocate a audio class handle. */ + error = USB_DeviceAudioAllocateHandle(&audioHandle); + + if (kStatus_USB_Success != error) + { + return error; + } + + /* Get the device handle according to the controller id. */ + error = USB_DeviceClassGetDeviceHandle(controllerId, &audioHandle->handle); + + if (kStatus_USB_Success != error) + { + return error; + } + + if (!audioHandle->handle) + { + return kStatus_USB_InvalidHandle; + } + /* Save the configuration of the class. */ + audioHandle->configStruct = config; + /* Clear the configuration value. */ + audioHandle->configuration = 0U; + audioHandle->streamAlternate = 0xffU; + audioHandle->controlAlternate = 0xffU; + + *handle = (class_handle_t)audioHandle; + return error; +} + +/*! + * @brief De-initialize the device audio class. + * + * The function de-initializes the device audio class. + * + * @param handle The ccid class handle got from usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceAudioDeinit(class_handle_t handle) +{ + usb_device_audio_struct_t *audioHandle; + usb_status_t error = kStatus_USB_Error; + + audioHandle = (usb_device_audio_struct_t *)handle; + + if (!audioHandle) + { + return kStatus_USB_InvalidHandle; + } + error = USB_DeviceAudioStreamEndpointsDeinit(audioHandle); + error = USB_DeviceAudioControlEndpointsDeinit(audioHandle); + USB_DeviceAudioFreeHandle(audioHandle); + return error; +} + +/*! + * @brief Send data through a specified endpoint. + * + * The function is used to send data through a specified endpoint. + * The function calls USB_DeviceSendRequest internally. + * + * @param handle The audio class handle got from usb_device_class_config_struct_t::classHandle. + * @param endpointAddress Endpoint index. + * @param buffer The memory address to hold the data need to be sent. + * @param length The data length need to be sent. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value just means if the sending request is successful or not; the transfer done is notified by + * usb_device_audio_stream_in or usb_device_audio_control_in. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceAudioSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length) +{ + usb_device_audio_struct_t *audioHandle; + usb_status_t error = kStatus_USB_Error; + + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + audioHandle = (usb_device_audio_struct_t *)handle; + + if (audioHandle->streamInPipeBusy) + { + return kStatus_USB_Busy; + } + audioHandle->streamInPipeBusy = 1U; + + error = USB_DeviceSendRequest(audioHandle->handle, ep, buffer, length); + if (kStatus_USB_Success != error) + { + audioHandle->streamInPipeBusy = 0U; + } + return error; +} + +/*! + * @brief Receive data through a specified endpoint. + * + * The function is used to receive data through a specified endpoint. + * The function calls USB_DeviceRecvRequest internally. + * + * @param handle The audio class handle got from usb_device_class_config_struct_t::classHandle. + * @param endpointAddress Endpoint index. + * @param buffer The memory address to save the received data. + * @param length The data length want to be received. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value just means if the receiving request is successful or not; the transfer done is notified by + * usb_device_audio_stream_out. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceAudioRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length) +{ + usb_device_audio_struct_t *audioHandle; + usb_status_t error = kStatus_USB_Error; + + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + audioHandle = (usb_device_audio_struct_t *)handle; + + if (audioHandle->streamOutPipeBusy) + { + return kStatus_USB_Busy; + } + audioHandle->streamOutPipeBusy = 1U; + + error = USB_DeviceRecvRequest(audioHandle->handle, ep, buffer, length); + if (kStatus_USB_Success != error) + { + audioHandle->streamOutPipeBusy = 0U; + } + return error; +} + +#endif diff --git a/usb/device/class/usb_device_audio.h b/usb/device/class/usb_device_audio.h new file mode 100644 index 0000000..f2e0f37 --- /dev/null +++ b/usb/device/class/usb_device_audio.h @@ -0,0 +1,394 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_AUDIO_H__ +#define __USB_DEVICE_AUDIO_H__ + +/*! + * @addtogroup usb_device_audio_drv + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Enables/disables the Audio Class 2.0 */ +#if USB_DEVICE_CONFIG_AUDIO +#define USBCFG_AUDIO_CLASS_2_0 0 +#endif + +/*! + * @name USB Audio class codes + * @{ + */ + +/*! @brief Audio device class code */ +#define USB_DEVICE_CONFIG_AUDIO_CLASS_CODE (0x01) + +/*! @brief Audio device subclass code */ +#define USB_DEVICE_AUDIO_STREAM_SUBCLASS (0x02) +#define USB_DEVICE_AUDIO_CONTROL_SUBCLASS (0x01) + +/*! @brief Audio device class-specific descriptor type */ +#define USB_DESCRIPTOR_TYPE_AUDIO_CS_INTERFACE (0x24) + +/*! @brief Audio device class-specific control interface descriptor subtype */ +#define USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_HEADER (0x01) +#define USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_INPUT_TERMINAL (0x02) +#define USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_OUTPUT_TERMINAL (0x03) +#define USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_FEATURE_UNIT (0x06) + +/*! @brief Audio device class-specific stream interface descriptor subtype */ +#define USB_DESCRIPTOR_SUBTYPE_AUDIO_STREAMING_GENERAL (0x01) +#define USB_DESCRIPTOR_SUBTYPE_AUDIO_STREAMING_FORMAT_TYPE (0x02) + +/*! @brief Audio device class-specific GET CUR COMMAND */ +#define USB_DEVICE_AUDIO_GET_CUR_MUTE_CONTROL (0x8101) +#define USB_DEVICE_AUDIO_GET_CUR_VOLUME_CONTROL (0x8102) +#define USB_DEVICE_AUDIO_GET_CUR_BASS_CONTROL (0x8103) +#define USB_DEVICE_AUDIO_GET_CUR_MID_CONTROL (0x8104) +#define USB_DEVICE_AUDIO_GET_CUR_TREBLE_CONTROL (0x8105) +#define USB_DEVICE_AUDIO_GET_CUR_GRAPHIC_EQUALIZER_CONTROL (0x8106) +#define USB_DEVICE_AUDIO_GET_CUR_AUTOMATIC_GAIN_CONTROL (0x8107) +#define USB_DEVICE_AUDIO_GET_CUR_DELAY_CONTROL (0x8108) +#define USB_DEVICE_AUDIO_GET_CUR_BASS_BOOST_CONTROL (0x8109) +#define USB_DEVICE_AUDIO_GET_CUR_LOUDNESS_CONTROL (0x810A) + +/*! @brief Audio device class-specific GET MIN COMMAND */ +#define USB_DEVICE_AUDIO_GET_MIN_VOLUME_CONTROL (0x8202) +#define USB_DEVICE_AUDIO_GET_MIN_BASS_CONTROL (0x8203) +#define USB_DEVICE_AUDIO_GET_MIN_MID_CONTROL (0x8204) +#define USB_DEVICE_AUDIO_GET_MIN_TREBLE_CONTROL (0x8205) +#define USB_DEVICE_AUDIO_GET_MIN_GRAPHIC_EQUALIZER_CONTROL (0x8206) +#define USB_DEVICE_AUDIO_GET_MIN_DELAY_CONTROL (0x8208) + +/*! @brief Audio device class-specific GET MAX COMMAND */ +#define USB_DEVICE_AUDIO_GET_MAX_VOLUME_CONTROL (0x8302) +#define USB_DEVICE_AUDIO_GET_MAX_BASS_CONTROL (0x8303) +#define USB_DEVICE_AUDIO_GET_MAX_MID_CONTROL (0x8304) +#define USB_DEVICE_AUDIO_GET_MAX_TREBLE_CONTROL (0x8305) +#define USB_DEVICE_AUDIO_GET_MAX_GRAPHIC_EQUALIZER_CONTROL (0x8306) +#define USB_DEVICE_AUDIO_GET_MAX_DELAY_CONTROL (0x8308) + +/*! @brief Audio device class-specific GET RES COMMAND */ +#define USB_DEVICE_AUDIO_GET_RES_VOLUME_CONTROL (0x8402) +#define USB_DEVICE_AUDIO_GET_RES_BASS_CONTROL (0x8403) +#define USB_DEVICE_AUDIO_GET_RES_MID_CONTROL (0x8404) +#define USB_DEVICE_AUDIO_GET_RES_TREBLE_CONTROL (0x8405) +#define USB_DEVICE_AUDIO_GET_RES_GRAPHIC_EQUALIZER_CONTROL (0x8406) +#define USB_DEVICE_AUDIO_GET_RES_DELAY_CONTROL (0x8408) + +/*! @brief Audio device class-specific SET CUR COMMAND */ +#define USB_DEVICE_AUDIO_SET_CUR_MUTE_CONTROL (0x0101) +#define USB_DEVICE_AUDIO_SET_CUR_VOLUME_CONTROL (0x0102) +#define USB_DEVICE_AUDIO_SET_CUR_BASS_CONTROL (0x0103) +#define USB_DEVICE_AUDIO_SET_CUR_MID_CONTROL (0x0104) +#define USB_DEVICE_AUDIO_SET_CUR_TREBLE_CONTROL (0x0105) +#define USB_DEVICE_AUDIO_SET_CUR_GRAPHIC_EQUALIZER_CONTROL (0x0106) +#define USB_DEVICE_AUDIO_SET_CUR_AUTOMATIC_GAIN_CONTROL (0x0107) +#define USB_DEVICE_AUDIO_SET_CUR_DELAY_CONTROL (0x0108) +#define USB_DEVICE_AUDIO_SET_CUR_BASS_BOOST_CONTROL (0x0109) +#define USB_DEVICE_AUDIO_SET_CUR_LOUDNESS_CONTROL (0x010A) +#define USB_DEVICE_AUDIO_SET_CUR_PITCH_CONTROL (0x010D) + +/*! @brief Audio device class-specific SET MIN COMMAND */ +#define USB_DEVICE_AUDIO_SET_MIN_VOLUME_CONTROL (0x0202) +#define USB_DEVICE_AUDIO_SET_MIN_BASS_CONTROL (0x0203) +#define USB_DEVICE_AUDIO_SET_MIN_MID_CONTROL (0x0204) +#define USB_DEVICE_AUDIO_SET_MIN_TREBLE_CONTROL (0x0205) +#define USB_DEVICE_AUDIO_SET_MIN_GRAPHIC_EQUALIZER_CONTROL (0x0206) +#define USB_DEVICE_AUDIO_SET_MIN_DELAY_CONTROL (0x0208) + +/*! @brief Audio device class-specific SET MAX COMMAND */ +#define USB_DEVICE_AUDIO_SET_MAX_VOLUME_CONTROL (0x0302) +#define USB_DEVICE_AUDIO_SET_MAX_BASS_CONTROL (0x0303) +#define USB_DEVICE_AUDIO_SET_MAX_MID_CONTROL (0x0304) +#define USB_DEVICE_AUDIO_SET_MAX_TREBLE_CONTROL (0x0305) +#define USB_DEVICE_AUDIO_SET_MAX_GRAPHIC_EQUALIZER_CONTROL (0x0306) +#define USB_DEVICE_AUDIO_SET_MAX_DELAY_CONTROL (0x0308) + +/*! @brief Audio device class-specific SET RES COMMAND */ +#define USB_DEVICE_AUDIO_SET_RES_VOLUME_CONTROL (0x0402) +#define USB_DEVICE_AUDIO_SET_RES_BASS_CONTROL (0x0403) +#define USB_DEVICE_AUDIO_SET_RES_MID_CONTROL (0x0404) +#define USB_DEVICE_AUDIO_SET_RES_TREBLE_CONTROL (0x0405) +#define USB_DEVICE_AUDIO_SET_RES_GRAPHIC_EQUALIZER_CONTROL (0x0406) +#define USB_DEVICE_AUDIO_SET_RES_DELAY_CONTROL (0x0408) + +/*! @brief Audio device class-specific GET SAMPLING FREQ CONTROL COMMAND */ +#define USB_DEVICE_AUDIO_GET_CUR_SAMPLING_FREQ_CONTROL (0x810C) +#define USB_DEVICE_AUDIO_GET_MIN_SAMPLING_FREQ_CONTROL (0x820C) +#define USB_DEVICE_AUDIO_GET_MAX_SAMPLING_FREQ_CONTROL (0x830C) +#define USB_DEVICE_AUDIO_GET_RES_SAMPLING_FREQ_CONTROL (0x840C) + +/*! @brief Audio device class-specific SET SAMPLING FREQ CONTROL COMMAND */ +#define USB_DEVICE_AUDIO_SET_CUR_SAMPLING_FREQ_CONTROL (0x010C) +#define USB_DEVICE_AUDIO_SET_MIN_SAMPLING_FREQ_CONTROL (0x020C) +#define USB_DEVICE_AUDIO_SET_MAX_SAMPLING_FREQ_CONTROL (0x030C) +#define USB_DEVICE_AUDIO_SET_RES_SAMPLING_FREQ_CONTROL (0x040C) + +#if USBCFG_AUDIO_CLASS_2_0 +/*! @brief Audio 2.0 device class-specific SET/GET SAMPLING FREQ CONTROL COMMAND */ +#define USB_DEVICE_AUDIO_SET_CUR_SAM_FREQ_CONTROL (0x0501) +#define USB_DEVICE_AUDIO_SET_CUR_CLOCK_VALID_CONTROL (0x0502) +#define USB_DEVICE_AUDIO_GET_CUR_SAM_FREQ_CONTROL (0x8501) +#define USB_DEVICE_AUDIO_GET_RANGE_SAM_FREQ_CONTROL (0x9501) +#define USB_DEVICE_AUDIO_GET_CUR_CLOCK_VALID_CONTROL (0x8502) +#define USB_DEVICE_AUDIO_GET_CUR_MUTE_CONTROL_AUDIO20 (0x8503) +#define USB_DEVICE_AUDIO_SET_CUR_MUTE_CONTROL_AUDIO20 (0x0503) +#define USB_DEVICE_AUDIO_GET_CUR_VOLUME_CONTROL_AUDIO20 (0x8504) +#define USB_DEVICE_AUDIO_GET_RANGE_VOLUME_CONTROL_AUDIO20 (0x9504) +#define USB_DEVICE_AUDIO_SET_CUR_VOLUME_CONTROL_AUDIO20 (0x0504) +#endif + +#if USBCFG_AUDIO_CLASS_2_0 +#define USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_CLOCK_SOURCE_UNIT (0x0A) +#define USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_CLOCK_SELECTOR_UNIT (0x0B) +#define USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_CLOCK_MULTIPLIER_UNIT (0x0C) +#define USB_DESCRIPTOR_SUBTYPE_AUDIO_CONTROL_SAMPLE_RATE_CONVERTER_UNIT (0x0D) + +#define USB_DEVICE_AUDIO_CS_CONTROL_UNDEFINED (0x00) +#define USB_DEVICE_AUDIO_CS_SAM_FREQ_CONTROL (0x01) +#define USB_DEVICE_AUDIO_CS_CLOCK_VALID_CONTROL (0x02) +#define USB_DEVICE_AUDIO_REQUEST_CUR (0x01) +#define USB_DEVICE_AUDIO_REQUEST_RANGE (0x02) +#define USB_DEVICE_AUDIO_FU_MUTE_CONTROL (0x01) +#define USB_DEVICE_AUDIO_FU_VOLUME_CONTROL (0x02) + +#endif + +/* Commands for USB device AUDIO Class specific request */ +#define USB_DEVICE_AUDIO_SET_CUR_VOLUME_REQUEST (0x01) +#define USB_DEVICE_AUDIO_SET_MIN_VOLUME_REQUEST (0x02) +#define USB_DEVICE_AUDIO_SET_MAX_VOLUME_REQUEST (0x03) +#define USB_DEVICE_AUDIO_SET_RES_VOLUME_REQUEST (0x04) + +#define USB_DEVICE_AUDIO_GET_CUR_VOLUME_REQUEST (0x81) +#define USB_DEVICE_AUDIO_GET_MIN_VOLUME_REQUEST (0x82) +#define USB_DEVICE_AUDIO_GET_MAX_VOLUME_REQUEST (0x83) +#define USB_DEVICE_AUDIO_GET_RES_VOLUME_REQUEST (0x84) + +/* Commands for USB device AUDIO terminal control selector */ +#define USB_DEVICE_AUDIO_COPY_PROTECT_CONTROL_SELECTOR (0x01) + +/* Commands for USB device AUDIO feature unit control selector */ +#define USB_DEVICE_AUDIO_MUTE_CONTROL_SELECTOR (0x01) +#define USB_DEVICE_AUDIO_VOLUME_CONTROL_SELECTOR (0x02) +#define USB_DEVICE_AUDIO_BASS_CONTROL_SELECTOR (0x03) +#define USB_DEVICE_AUDIO_MID_CONTROL_SELECTOR (0x04) +#define USB_DEVICE_AUDIO_TREBLE_CONTROL_SELECTOR (0x05) +#define USB_DEVICE_AUDIO_GRAPHIC_EQUALIZER_CONTROL_SELECTOR (0x06) +#define USB_DEVICE_AUDIO_AUTOMATIC_GAIN_CONTROL_SELECTOR (0x07) +#define USB_DEVICE_AUDIO_DELAY_CONTROL_SELECTOR (0x08) +#define USB_DEVICE_AUDIO_BASS_BOOST_CONTROL_SELECTOR (0x09) +#define USB_DEVICE_AUDIO_LOUDNESS_CONTROL_SELECTOR (0x0A) + +/* Commands for USB device AUDIO endpoint control selector */ +#define USB_DEVICE_AUDIO_SAMPLING_FREQ_CONTROL_SELECTOR (0x01) +#define USB_DEVICE_AUDIO_PITCH_CONTROL_SELECTOR (0x02) +/*! @}*/ + +/*! + * @name USB Audio class setup request types + * @{ + */ +/*! @brief Audio device class setup request set type */ +#define USB_DEVICE_AUDIO_SET_REQUEST_INTERFACE (0x21) +#define USB_DEVICE_AUDIO_SET_REQUEST_ENDPOINT (0x22) + +/*! @brief Audio device class setup request get type */ +#define USB_DEVICE_AUDIO_GET_REQUEST_INTERFACE (0xA1) +#define USB_DEVICE_AUDIO_GET_REQUEST_ENDPOINT (0xA2) +/*! @}*/ + +/*! @brief Available common EVENT types in audio class callback */ +typedef enum +{ + kUSB_DeviceAudioEventStreamSendResponse = 0x01U, /*!< Send data completed or cancelled etc in stream pipe */ + kUSB_DeviceAudioEventStreamRecvResponse, /*!< Data received or cancelled etc in stream pipe */ + kUSB_DeviceAudioEventControlSendResponse, /*!< Send data completed or cancelled etc in audio control pipe */ +} usb_device_audio_event_t; + +/*! + * @brief The audio device class-specific information. + * The structure is used to pass the audio entity information filled by application. + * Such as + * entity id (unit or terminal ID), + * entity type (unit or terminal type), + * and terminal type if the entity is a terminal. + */ +typedef struct _usb_device_audio_entity_struct +{ + uint8_t entityId; + uint8_t entityType; + uint16_t terminalType; +} usb_device_audio_entity_struct_t; + +/*! + * @brief The audio device class-specific information list. + * The structure is used to pass the audio entity informations filled by the application. + * The type of each entity is usb_device_audio_entity_struct_t. + * The structure pointer is kept in the usb_device_interface_struct_t::classSpecific, + * such as, if there are three entities (an out terminal, camera terminal, and processing unit), + * the value of the count field is 3 and the entity field saves the every entity information. + */ +typedef struct _usb_device_audio_entities_struct +{ + usb_device_audio_entity_struct_t *entity; + uint8_t count; +} usb_device_audio_entities_struct_t; + +/*! @brief The audio device class status structure */ +typedef struct _usb_device_audio_struct +{ + usb_device_handle handle; /*!< The device handle */ + usb_device_class_config_struct_t *configStruct; /*!< The configuration of the class. */ + usb_device_interface_struct_t *controlInterfaceHandle; /*!< Current control interface handle */ + usb_device_interface_struct_t *streamInterfaceHandle; /*!< Current stream interface handle */ + uint8_t configuration; /*!< Current configuration */ + uint8_t controlInterfaceNumber; /*!< The control interface number of the class */ + uint8_t controlAlternate; /*!< Current alternate setting of the control interface */ + uint8_t streamInterfaceNumber; /*!< The stream interface number of the class */ + uint8_t streamAlternate; /*!< Current alternate setting of the stream interface */ + uint8_t streamInPipeBusy; /*!< Stream IN pipe busy flag */ + uint8_t streamOutPipeBusy; /*!< Stream OUT pipe busy flag */ +} usb_device_audio_struct_t; + +#if USBCFG_AUDIO_CLASS_2_0 +STRUCT_PACKED +struct _usb_device_control_range_layout3_struct +{ + uint16_t wNumSubRanges; + uint32_t wMIN; + uint32_t wMAX; + uint32_t wRES; +} STRUCT_UNPACKED; +typedef struct _usb_device_control_range_layout3_struct usb_device_control_range_layout3_struct_t; +STRUCT_PACKED +struct _usb_device_control_range_layout2_struct +{ + uint16_t wNumSubRanges; + uint16_t wMIN; + uint16_t wMAX; + uint16_t wRES; +} STRUCT_UNPACKED; +typedef struct _usb_device_control_range_layout2_struct usb_device_control_range_layout2_struct_t; +#endif + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @name USB Audio Class Driver + * @{ + */ +/*! + * @brief Initializes the USB audio class. + * + * This function obtains a USB device handle according to the controller ID, initializes the audio class + * with the class configuration parameters, and creates the mutex for each pipe. + * + * @param controllerId The ID of the controller. The value can be chosen from the kUSB_ControllerKhci0, + * kUSB_ControllerKhci1, kUSB_ControllerEhci0, or kUSB_ControllerEhci1. + * @param config The user configuration structure of type usb_device_class_config_struct_t. The user + * populates the members of this structure and passes the pointer of this structure + * into this function. + * @param handle An out parameter. The class handle of the audio class. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success The audio class is initialized successfully. + * @retval kStatus_USB_Busy No audio device handle available for allocation. + * @retval kStatus_USB_InvalidHandle The audio device handle allocation failure. + * @retval kStatus_USB_InvalidParameter The USB device handle allocation failure. + */ +extern usb_status_t USB_DeviceAudioInit(uint8_t controllerId, + usb_device_class_config_struct_t *config, + class_handle_t *handle); + +/*! + * @brief Deinitializes the USB audio class. + * + * This function destroys the mutex for each pipe, deinitializes each endpoint of the audio class, and frees + * the audio class handle. + * + * @param handle The class handle of the audio class. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success The audio class is deinitialized successfully. + * @retval kStatus_USB_Error The endpoint deinitialization failure. + * @retval kStatus_USB_InvalidHandle The audio device handle or the audio class handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number of the audio class handle is invalid. + */ +extern usb_status_t USB_DeviceAudioDeinit(class_handle_t handle); + +/*! + * @brief Handles the USB audio class event. + * + * This function responds to various events including the common device events and the class-specific events. + * For class-specific events, it calls the class callback defined in the application to deal with the class-specific + * event. + * + * @param handle The class handle of the audio class. + * @param event The event type. + * @param param The class handle of the audio class. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success The audio class is deinitialized successfully. + * @retval kStatus_USB_Error The configure structure of the audio class handle is invalid. + * @retval kStatus_USB_InvalidHandle The audio device handle or the audio class handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number of the audio class handle is invalid. + * @retval Others The error code returned by class callback in application. + */ +extern usb_status_t USB_DeviceAudioEvent(void *handle, uint32_t event, void *param); + +/*! + * @brief Primes the endpoint to send a packet to the host. + * + * This function checks whether the endpoint is sending packet, then it primes the endpoint + * with the buffer address and the buffer length if the pipe is not busy. Otherwise, it ignores this transfer by + * returning an error code. + * + * @param handle The class handle of the audio class. + * @param ep The endpoint number of the transfer. + * @param buffer The pointer to the buffer to be transferred. + * @param length The length of the buffer to be transferred. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Prime to send packet successfully. + * @retval kStatus_USB_Busy The endpoint is busy in transferring. + * @retval kStatus_USB_InvalidHandle The audio device handle or the audio class handle is invalid. + * @retval kStatus_USB_ControllerNotFound The controller interface is invalid. + * + * @note The function can only be called in the same context. + */ +extern usb_status_t USB_DeviceAudioSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length); + +/*! + * @brief Primes the endpoint to receive a packet from the host. + * + * This function checks whether the endpoint is receiving packet, then it primes the endpoint + * with the buffer address and the buffer length if the pipe is not busy. Otherwise, it ignores this transfer by + * returning an error code. + * + * @param handle The class handle of the audio class. + * @param ep The endpoint number of the transfer. + * @param buffer The pointer to the buffer to be transferred. + * @param length The length of the buffer to be transferred. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Prime to receive packet successfully. + * @retval kStatus_USB_Busy The endpoint is busy in transferring. + * @retval kStatus_USB_InvalidHandle The audio device handle or the audio class handle is invalid. + * @retval kStatus_USB_ControllerNotFound The controller interface is invalid. + * + * @note The function can only be called in the same context. + */ +extern usb_status_t USB_DeviceAudioRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length); + +/*! @}*/ + +/*! @}*/ + +#endif /* __USB_DEVICE_AUDIO_H__ */ diff --git a/usb/device/class/usb_device_ccid.c b/usb/device/class/usb_device_ccid.c new file mode 100644 index 0000000..76b7046 --- /dev/null +++ b/usb/device/class/usb_device_ccid.c @@ -0,0 +1,1101 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device.h" + +#include "usb_device_class.h" + +#if ((defined(USB_DEVICE_CONFIG_CCID)) && (USB_DEVICE_CONFIG_CCID > 0U)) +#include "usb_device_ccid.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +static usb_status_t USB_DeviceCcidAllocateHandle(usb_device_ccid_struct_t **handle); +static usb_status_t USB_DeviceCcidFreeHandle(usb_device_ccid_struct_t *handle); +static usb_status_t USB_DeviceCcidRemoveTransfer(usb_device_ccid_transfer_struct_t **transfer_queue, + usb_device_ccid_transfer_struct_t **transfer); +static usb_status_t USB_DeviceCcidAddTransfer(usb_device_ccid_transfer_struct_t **transfer_queue, + usb_device_ccid_transfer_struct_t *transfer); +static usb_status_t USB_DeviceCcidInterruptIn(usb_device_handle deviceHandle, + usb_device_endpoint_callback_message_struct_t *event, + void *callbackParam); +static usb_status_t USB_DeviceCcidBulkIn(usb_device_handle deviceHandle, + usb_device_endpoint_callback_message_struct_t *event, + void *callbackParam); +static usb_status_t USB_DeviceCcidBulkOut(usb_device_handle deviceHandle, + usb_device_endpoint_callback_message_struct_t *event, + void *callbackParam); +static usb_status_t USB_DeviceCcidEndpointsInit(usb_device_ccid_struct_t *ccidHandle); +static usb_status_t USB_DeviceCcidEndpointsDeinit(usb_device_ccid_struct_t *ccidHandle); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_ccid_struct_t + s_UsbDeviceCcidHandle[USB_DEVICE_CONFIG_CCID]; + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @brief Allocate a device ccid class handle. + * + * This function allocates a device ccid class handle. + * + * @param handle It is out parameter, is used to return pointer of the device ccid class handle to the caller. + * + * @retval kStatus_USB_Success Get a device ccid class handle successfully. + * @retval kStatus_USB_Busy Cannot allocate a device ccid class handle. + */ +static usb_status_t USB_DeviceCcidAllocateHandle(usb_device_ccid_struct_t **handle) +{ + int32_t count; + for (count = 0U; count < USB_DEVICE_CONFIG_CCID; count++) + { + if (NULL == s_UsbDeviceCcidHandle[count].handle) + { + *handle = &s_UsbDeviceCcidHandle[count]; + return kStatus_USB_Success; + } + } + + return kStatus_USB_Busy; +} + +/*! + * @brief Free a device ccid class handle. + * + * This function frees a device ccid class handle. + * + * @param handle The device ccid class handle. + * + * @retval kStatus_USB_Success Free device ccid class handle successfully. + */ +static usb_status_t USB_DeviceCcidFreeHandle(usb_device_ccid_struct_t *handle) +{ + handle->handle = NULL; + handle->configStruct = (usb_device_class_config_struct_t *)NULL; + handle->configuration = 0U; + handle->alternate = 0U; + return kStatus_USB_Success; +} + +/*! + * @brief Remove a transfer node from a queue. + * + * This function removes a transfer node from a queue. + * + * @param transfer_queue A pointer points to a queue pointer. + * @param transfer It is an OUT parameter, return the transfer node pointer. + * + * @retval kStatus_USB_Success Free device ccid class handle successfully. + * @retval kStatus_USB_Busy Can not get transfer node due to the queue is empty. + */ +static usb_status_t USB_DeviceCcidRemoveTransfer(usb_device_ccid_transfer_struct_t **transfer_queue, + usb_device_ccid_transfer_struct_t **transfer) +{ + USB_OSA_SR_ALLOC(); + + if ((NULL == transfer_queue) || (NULL == transfer)) + { + return kStatus_USB_InvalidParameter; + } + + USB_OSA_ENTER_CRITICAL(); + *transfer = *transfer_queue; + if (*transfer_queue) + { + *transfer_queue = (*transfer_queue)->next; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Busy; +} + +/*! + * @brief Add a transfer node to a queue. + * + * This function adds a transfer node to a queue. + * + * @param transfer_queue A pointer points to a queue pointer. + * @param transfer The transfer node pointer. + * + * @retval kStatus_USB_Success Free device ccid class handle successfully. + * @retval kStatus_USB_Error The transfer node has been added. + */ +static usb_status_t USB_DeviceCcidAddTransfer(usb_device_ccid_transfer_struct_t **transfer_queue, + usb_device_ccid_transfer_struct_t *transfer) +{ + usb_device_ccid_transfer_struct_t *p; + usb_device_ccid_transfer_struct_t *q; + USB_OSA_SR_ALLOC(); + + if (NULL == transfer_queue) + { + return kStatus_USB_InvalidParameter; + } + p = *transfer_queue; + q = *transfer_queue; + + USB_OSA_ENTER_CRITICAL(); + while (p) + { + q = p; + if (p == transfer) + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Error; + } + p = p->next; + } + transfer->next = NULL; + if (q) + { + q->next = transfer; + } + else + { + *transfer_queue = transfer; + } + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; +} + +/*! + * @brief Interrupt IN endpoint callback function. + * + * This callback function is used to notify uplayer the transfser result of a transfer. + * This callback pointer is passed when the interrupt IN pipe initialized. + * + * @param deviceHandle The device handle. It equals the value returned from USB_DeviceInit. + * @param event The result of the interrupt IN pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the ccid class handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceCcidInterruptIn(usb_device_handle deviceHandle, + usb_device_endpoint_callback_message_struct_t *event, + void *callbackParam) +{ + usb_device_ccid_struct_t *ccidHandle = (usb_device_ccid_struct_t *)callbackParam; + usb_device_ccid_notification_struct_t notification; + usb_status_t error = kStatus_USB_Error; + USB_OSA_SR_ALLOC(); + + if (((NULL == deviceHandle) || (NULL == callbackParam) || (NULL == event)) || (NULL == event->buffer)) + { + return kStatus_USB_Error; + } + + /* Save the transed buffer address and length */ + notification.buffer = event->buffer; + notification.length = event->length; + usb_device_ccid_notify_slot_chnage_notification_t *ccidNotify = + (usb_device_ccid_notify_slot_chnage_notification_t *)event->buffer; + + if (USB_DEVICE_CCID_RDR_TO_PC_NOTIFYSLOTCHANGE == ccidNotify->bMessageType) + { + if (ccidHandle->configStruct->classCallback) + { + /* Notify the up layer, the slot change notification sent. + classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + ccidHandle->configStruct->classCallback((class_handle_t)ccidHandle, kUSB_DeviceCcidEventSlotChangeSent, + ¬ification); + } + } + else if (USB_DEVICE_CCID_RDR_TO_PC_HARDWAREERROR == ccidNotify->bMessageType) + { + if (ccidHandle->configStruct->classCallback) + { + /* Notify the up layer, the hardware error notification sent. + classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + ccidHandle->configStruct->classCallback((class_handle_t)ccidHandle, kUSB_DeviceCcidEventHardwareErrorSent, + ¬ification); + } + } + else + { + } + USB_OSA_ENTER_CRITICAL(); + if ((ccidHandle->configuration) && (ccidHandle->endpointInterruptIn)) + { + /* If there is a blocking slot changed notification, send it to the host */ + if (ccidHandle->slotsChanged) + { + ccidHandle->slotsSendingChangeBuffer[0] = ccidHandle->slotsChangeBuffer[0]; + for (uint8_t i = 1U; i < sizeof(ccidHandle->slotsChangeBuffer); i++) + { + ccidHandle->slotsSendingChangeBuffer[i] = ccidHandle->slotsChangeBuffer[i]; + ccidHandle->slotsChangeBuffer[i] &= ~0xAAU; + } + error = USB_DeviceSendRequest(ccidHandle->handle, ccidHandle->endpointInterruptIn, + ccidHandle->slotsSendingChangeBuffer, + sizeof(ccidHandle->slotsSendingChangeBuffer)); + if (kStatus_USB_Success == error) + { + ccidHandle->slotsChanged = 0U; + ccidHandle->interruptInBusy = 1U; + } + else + { + ccidHandle->interruptInBusy = 0U; + } + } + else + { + ccidHandle->interruptInBusy = 0U; + } + } + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; +} + +/*! + * @brief Bulk IN endpoint callback function. + * + * This callback function is used to notify uplayer the transfser result of a transfer. + * This callback pointer is passed when the Bulk IN pipe initialized. + * + * @param deviceHandle The device handle. It equals the value returned from USB_DeviceInit. + * @param event The result of the Bulk IN pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the ccid class handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceCcidBulkIn(usb_device_handle deviceHandle, + usb_device_endpoint_callback_message_struct_t *event, + void *callbackParam) +{ + usb_device_ccid_struct_t *ccidHandle = (usb_device_ccid_struct_t *)callbackParam; + usb_device_ccid_transfer_struct_t *transfer; + usb_status_t error = kStatus_USB_Error; + if (((NULL == deviceHandle) || (NULL == callbackParam) || (NULL == event)) || (NULL == event->buffer) || + (USB_UNINITIALIZED_VAL_32 == event->length)) + { + return kStatus_USB_Error; + } + + /* Remove the transed transfer from the busy queue. */ + if (kStatus_USB_Success == USB_DeviceCcidRemoveTransfer(&ccidHandle->transferHead, &transfer)) + { + if (ccidHandle->configStruct->classCallback) + { + /* Notify the up layer, the response sent. + classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + ccidHandle->configStruct->classCallback((class_handle_t)ccidHandle, kUSB_DeviceCcidEventResponseSent, + transfer->buffer); + } + /* Add the transfer node to the idle queue */ + USB_DeviceCcidAddTransfer(&ccidHandle->transferFree, transfer); + } + + /* Clear the bulk IN pipe busy flag. */ + ccidHandle->bulkInBusy = 0U; + /* If there is a blocking transfer, send it to the host */ + if (ccidHandle->transferHead) + { + error = USB_DeviceSendRequest(ccidHandle->handle, ccidHandle->endpointBulkIn, ccidHandle->transferHead->buffer, + ccidHandle->transferHead->length); + if (kStatus_USB_Success == error) + { + ccidHandle->bulkInBusy = 1U; + } + } + return error; +} + +/*! + * @brief Bulk OUT endpoint callback function. + * + * This callback function is used to notify uplayer the transfser result of a transfer. + * This callback pointer is passed when the Bulk OUT pipe initialized. + * + * @param deviceHandle The device handle. It equals the value returned from USB_DeviceInit. + * @param event The result of the Bulk OUT pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the ccid class handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceCcidBulkOut(usb_device_handle deviceHandle, + usb_device_endpoint_callback_message_struct_t *event, + void *callbackParam) +{ + usb_device_ccid_struct_t *ccidHandle; + usb_device_ccid_common_command_t *commonRequest; + usb_device_ccid_transfer_struct_t *transfer = NULL; + usb_status_t usbError = kStatus_USB_InvalidRequest; + uint8_t response_error = USB_DEVICE_CCID_SLOT_ERROR_COMMAND_NOT_SUPPORTED; + + if (((NULL == deviceHandle) || (NULL == callbackParam) || (NULL == event)) || (NULL == event->buffer) || + (USB_UNINITIALIZED_VAL_32 == event->length)) + { + return kStatus_USB_Error; + } + ccidHandle = (usb_device_ccid_struct_t *)callbackParam; + commonRequest = (usb_device_ccid_common_command_t *)event->buffer; + + /* Check the slot is valid or not */ + if ((ccidHandle->slots <= commonRequest->bSlot) || + (event->length < + (USB_LONG_FROM_LITTLE_ENDIAN_DATA(commonRequest->dwLength) + USB_DEVICE_CCID_COMMAND_HEADER_LENGTH))) + { + if (ccidHandle->slots <= commonRequest->bSlot) + { + response_error = USB_DEVICE_CCID_SLOT_ERROR_SLOT_NOT_EXIST; + } + else + { + response_error = USB_DEVICE_CCID_SLOT_ERROR_BAD_LENGTH; + } + } + else + { + /* If the slot is valid, handle the host's request */ + ccidHandle->slotsSequenceNumber[commonRequest->bSlot] = commonRequest->bSeq; + switch (commonRequest->bMessageType) + { + case USB_DEVICE_CCID_PC_TO_RDR_ICCPOWERON: + case USB_DEVICE_CCID_PC_TO_RDR_ICCPOWEROFF: + case USB_DEVICE_CCID_PC_TO_RDR_GETSLOTSTATUS: + case USB_DEVICE_CCID_PC_TO_RDR_XFRBLOCK: + case USB_DEVICE_CCID_PC_TO_RDR_GETPARAMETERS: + case USB_DEVICE_CCID_PC_TO_RDR_RESETPARAMETERS: + case USB_DEVICE_CCID_PC_TO_RDR_SETPARAMETERS: + case USB_DEVICE_CCID_PC_TO_RDR_ESCAPE: + case USB_DEVICE_CCID_PC_TO_RDR_ICCCLOCK: + case USB_DEVICE_CCID_PC_TO_RDR_T0APDU: + case USB_DEVICE_CCID_PC_TO_RDR_SECURE: + case USB_DEVICE_CCID_PC_TO_RDR_MECHANICAL: + case USB_DEVICE_CCID_PC_TO_RDR_ABORT: + case USB_DEVICE_CCID_PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY: + if (ccidHandle->configStruct->classCallback) + { + usb_device_ccid_command_struct_t command; + command.commandBuffer = event->buffer; + command.commandLength = event->length; + /* Notify the up layer, the command received, and then the application need to handle the command. + classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + usbError = ccidHandle->configStruct->classCallback((class_handle_t)ccidHandle, + kUSB_DeviceCcidEventCommandReceived, &command); + if (kStatus_USB_Success == usbError) + { + /* Get a new transfer node from the idle queue */ + if (kStatus_USB_Success == USB_DeviceCcidRemoveTransfer(&ccidHandle->transferFree, &transfer)) + { + /* Save the response buffer and data length to the transfer node */ + transfer->buffer = command.responseBuffer; + transfer->length = command.responseLength; + /* Add the transfer node to the busy queue */ + USB_DeviceCcidAddTransfer(&ccidHandle->transferHead, transfer); + if (!ccidHandle->bulkInBusy) + { + /* If the bulk IN pipe is idle, send the response data to the host */ + if (kStatus_USB_Success == USB_DeviceSendRequest(ccidHandle->handle, + ccidHandle->endpointBulkIn, + transfer->buffer, transfer->length)) + { + ccidHandle->bulkInBusy = 1U; + } + } + } + } + } + break; + default: + break; + } + } + + /* Response the host when the command failed. */ + if (kStatus_USB_Success != usbError) + { + if (kStatus_USB_Success == USB_DeviceCcidRemoveTransfer(&ccidHandle->transferFree, &transfer)) + { + usb_device_ccid_slot_status_struct_t slotStatus; + transfer->buffer = (uint8_t *)&transfer->response; + transfer->length = sizeof(transfer->response); + transfer->response.bMessageType = USB_DEVICE_CCID_RDR_TO_PC_SLOTSTATUS; + USB_LONG_TO_LITTLE_ENDIAN_DATA(0U, transfer->response.dwLength); + transfer->response.bSlot = commonRequest->bSlot; + transfer->response.bSeq = commonRequest->bSeq; + slotStatus.clockStatus = USB_DEVICE_CCID_CLCOK_STATUS_CLOCK_STOPPED_UNKNOWN; + slotStatus.slot = commonRequest->bSlot; + slotStatus.present = USB_DEVICE_CCID_SLOT_STATUS_ICC_NOT_PRESENT; + if (ccidHandle->configStruct->classCallback) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit*/ + ccidHandle->configStruct->classCallback((class_handle_t)ccidHandle, kUSB_DeviceCcidEventGetSlotStatus, + &slotStatus); + } + transfer->response.bStatus = slotStatus.present | USB_DEVICE_CCID_SLOT_STATUS_COMMAND_STATUS_FAILED; + transfer->response.bError = response_error; + transfer->response.bClockStatus = slotStatus.clockStatus; + USB_DeviceCcidAddTransfer(&ccidHandle->transferHead, transfer); + if (!ccidHandle->bulkInBusy) + { + usbError = USB_DeviceSendRequest(ccidHandle->handle, ccidHandle->endpointBulkIn, transfer->buffer, + transfer->length); + if (kStatus_USB_Success == usbError) + { + ccidHandle->bulkInBusy = 1U; + } + } + } + } + /* Prime next transfer to receive a command from the host */ + if (ccidHandle->endpointBulkOut) + { + USB_DeviceRecvRequest(ccidHandle->handle, ccidHandle->endpointBulkOut, ccidHandle->commandBuffer, + sizeof(ccidHandle->commandBuffer)); + } + return usbError; +} + +/*! + * @brief Initialize the endpoints of the ccid class. + * + * This callback function is used to initialize the endpoints of the ccide class. + * + * @param ccidHandle The device ccid class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceCcidEndpointsInit(usb_device_ccid_struct_t *ccidHandle) +{ + usb_device_interface_list_t *interfaceList; + usb_device_interface_struct_t *interface = (usb_device_interface_struct_t *)NULL; + usb_status_t error = kStatus_USB_Error; + + /* Check the configuration is valid or not. */ + if (!ccidHandle->configuration) + { + return error; + } + + if (ccidHandle->configuration > ccidHandle->configStruct->classInfomation->configurations) + { + return error; + } + + /* Get the interface list of the new configuration. */ + if (NULL == ccidHandle->configStruct->classInfomation->interfaceList) + { + return error; + } + interfaceList = &ccidHandle->configStruct->classInfomation->interfaceList[ccidHandle->configuration - 1U]; + + /* Find stream interface by using the alternate setting of the interface. */ + for (int count = 0U; count < interfaceList->count; count++) + { + if ((USB_DEVICE_CCID_CLASS_CODE == interfaceList->interfaces[count].classCode) && + (USB_DEVICE_CCID_SUBCLASS_CODE == interfaceList->interfaces[count].subclassCode) && + (USB_DEVICE_CCID_PROTOCOL_CODE == interfaceList->interfaces[count].protocolCode)) + { + for (int index = 0U; index < interfaceList->interfaces[count].count; index++) + { + if (interfaceList->interfaces[count].interface[index].alternateSetting == ccidHandle->alternate) + { + interface = &interfaceList->interfaces[count].interface[index]; + break; + } + } + ccidHandle->interfaceNumber = interfaceList->interfaces[count].interfaceNumber; + break; + } + } + if (!interface) + { + /* Return error if the stream interface is not found. */ + return error; + } + /* Keep new interface handle. */ + ccidHandle->interfaceHandle = interface; + /* Initialize the endpoints of the new interface. */ + for (int count = 0U; count < interface->endpointList.count; count++) + { + usb_device_endpoint_init_struct_t epInitStruct; + usb_device_endpoint_callback_struct_t epCallback; + epInitStruct.zlt = 0U; + epInitStruct.interval = interface->endpointList.endpoint[count].interval; + epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress; + epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize; + epInitStruct.transferType = interface->endpointList.endpoint[count].transferType; + + if ((USB_ENDPOINT_BULK == (epInitStruct.transferType & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK)) && + (USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))) + { + epCallback.callbackFn = USB_DeviceCcidBulkIn; + epInitStruct.zlt = 1U; + ccidHandle->endpointBulkIn = epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK; + } + else if ((USB_ENDPOINT_BULK == (epInitStruct.transferType & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK)) && + (USB_OUT == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))) + { + epCallback.callbackFn = USB_DeviceCcidBulkOut; + ccidHandle->endpointBulkOut = epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK; + } + else + { + epCallback.callbackFn = USB_DeviceCcidInterruptIn; + ccidHandle->endpointInterruptIn = + epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK; + } + epCallback.callbackParam = ccidHandle; + + error = USB_DeviceInitEndpoint(ccidHandle->handle, &epInitStruct, &epCallback); + } + return error; +} + +/*! + * @brief De-initialize the endpoints of the ccid class. + * + * This callback function is used to de-initialize the stream endpoints of the ccid class. + * + * @param ccidHandle The device ccid class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceCcidEndpointsDeinit(usb_device_ccid_struct_t *ccidHandle) +{ + usb_status_t error = kStatus_USB_Error; + + if (!ccidHandle->interfaceHandle) + { + return error; + } + /* De-initialize all endpoints of the interface */ + for (int count = 0U; count < ccidHandle->interfaceHandle->endpointList.count; count++) + { + error = USB_DeviceDeinitEndpoint(ccidHandle->handle, + ccidHandle->interfaceHandle->endpointList.endpoint[count].endpointAddress); + } + ccidHandle->endpointBulkIn = 0U; + ccidHandle->endpointBulkOut = 0U; + ccidHandle->endpointInterruptIn = 0U; + ccidHandle->interfaceHandle = NULL; + return error; +} + +/*! + * @brief Handle the event passed to the ccid class. + * + * This function handles the event passed to the ccid class. + * + * @param handle The ccid class handle, got from the usb_device_class_config_struct_t::classHandle. + * @param event The event codes. Please refer to the enumeration usb_device_class_event_t. + * @param param The param type is determined by the event code. + * + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The device handle not be found. + * @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe will be stalled by the caller. + */ +usb_status_t USB_DeviceCcidEvent(void *handle, uint32_t event, void *param) +{ + usb_device_ccid_struct_t *ccidHandle; + usb_device_ccid_notify_slot_chnage_notification_t *ccidNotify; + uint8_t *temp8; + usb_status_t error = kStatus_USB_Error; + uint16_t interfaceAlternate; + uint8_t alternate; + USB_OSA_SR_ALLOC(); + + if ((!param) || (!handle)) + { + return kStatus_USB_InvalidHandle; + } + + /* Get the ccid class handle. */ + ccidHandle = (usb_device_ccid_struct_t *)handle; + + switch (event) + { + case kUSB_DeviceClassEventDeviceReset: + /* Bus reset, clear the configuration. */ + ccidHandle->configuration = 0U; + break; + case kUSB_DeviceClassEventSetConfiguration: + /* Get the new configuration. */ + temp8 = ((uint8_t *)param); + if (!ccidHandle->configStruct) + { + break; + } + if (*temp8 == ccidHandle->configuration) + { + break; + } + + /* De-initialize the endpoints when current configuration is none zero. */ + if (ccidHandle->configuration) + { + error = USB_DeviceCcidEndpointsDeinit(ccidHandle); + } + USB_OSA_ENTER_CRITICAL(); + /* Save new configuration. */ + ccidHandle->configuration = *temp8; + /* Clear the alternate setting value. */ + ccidHandle->alternate = 0U; + + /* Clear BULK IN pipe busy status */ + ccidHandle->bulkInBusy = 0U; + /* Clear Interrupt IN pipe busy status */ + ccidHandle->interruptInBusy = 0U; + /* Clear slot changed status */ + ccidHandle->slotsChanged = 0U; + + /* Reset the idle queue and busy queue */ + ccidHandle->transferFree = &ccidHandle->transfers[0]; + ccidHandle->transferHead = &ccidHandle->transfers[0]; + for (uint8_t i = 1U; i < USB_DEVICE_CONFIG_CCID_TRANSFER_COUNT; i++) + { + ccidHandle->transferHead->next = &ccidHandle->transfers[i]; + ccidHandle->transferHead = &ccidHandle->transfers[i]; + } + ccidHandle->transferHead->next = NULL; + ccidHandle->transferHead = NULL; + + /* Initialize the endpoints of the new current configuration by using the alternate setting 0. */ + error = USB_DeviceCcidEndpointsInit(ccidHandle); + if (ccidHandle->endpointBulkOut) + { + /* Prime a transfer to receive a command from the host */ + USB_DeviceRecvRequest(ccidHandle->handle, ccidHandle->endpointBulkOut, ccidHandle->commandBuffer, + sizeof(ccidHandle->commandBuffer)); + } + + /* Notify the host the slot changed when the interrut IN pipe is valid and there are some ICC present. */ + if (ccidHandle->endpointInterruptIn) + { + uint8_t send_slot_change = 0U; + ccidNotify = (usb_device_ccid_notify_slot_chnage_notification_t *)&ccidHandle->slotsChangeBuffer[0]; + + ccidNotify->bMessageType = USB_DEVICE_CCID_RDR_TO_PC_NOTIFYSLOTCHANGE; + for (uint8_t i = 0U; i < USB_DEVICE_CONFIG_CCID_SLOT_MAX; i++) + { + if (ccidNotify->bmSlotICCState[i >> 2] & (0x01U << ((i % 4U) << 1U))) + { + ccidNotify->bmSlotICCState[i >> 2] |= (0x02U << ((i % 4U) << 1U)); + send_slot_change = 1U; + } + } + if (send_slot_change) + { + ccidHandle->slotsSendingChangeBuffer[0] = ccidHandle->slotsChangeBuffer[0]; + for (uint8_t i = 1U; i < sizeof(ccidHandle->slotsChangeBuffer); i++) + { + ccidHandle->slotsSendingChangeBuffer[i] = ccidHandle->slotsChangeBuffer[i]; + ccidHandle->slotsChangeBuffer[i] &= ~0xAAU; + } + error = USB_DeviceSendRequest(ccidHandle->handle, ccidHandle->endpointInterruptIn, + ccidHandle->slotsSendingChangeBuffer, + sizeof(ccidHandle->slotsSendingChangeBuffer)); + if (kStatus_USB_Success == error) + { + ccidHandle->interruptInBusy = 1U; + } + } + } + USB_OSA_EXIT_CRITICAL(); + break; + case kUSB_DeviceClassEventSetInterface: + if (!ccidHandle->configStruct) + { + break; + } + + /* Get the new alternate setting of the interface */ + interfaceAlternate = *((uint16_t *)param); + /* Get the alternate setting value */ + alternate = (uint8_t)(interfaceAlternate & 0xFFU); + + /* Whether the interface belongs to the class. */ + if (ccidHandle->interfaceNumber != ((uint8_t)(interfaceAlternate >> 8U))) + { + break; + } + if (alternate == ccidHandle->alternate) + { + break; + } + /* De-initialize old endpoints */ + error = USB_DeviceCcidEndpointsDeinit(ccidHandle); + ccidHandle->alternate = alternate; + /* Initialize new endpoints */ + error = USB_DeviceCcidEndpointsInit(ccidHandle); + if (ccidHandle->endpointBulkOut) + { + /* Prime a transfer to receive a command from the host */ + USB_DeviceRecvRequest(ccidHandle->handle, ccidHandle->endpointBulkOut, ccidHandle->commandBuffer, + sizeof(ccidHandle->commandBuffer)); + } + break; + case kUSB_DeviceClassEventSetEndpointHalt: + if ((!ccidHandle->configStruct) || (!ccidHandle->interfaceHandle)) + { + break; + } + /* Get the endpoint address */ + temp8 = ((uint8_t *)param); + for (int count = 0U; count < ccidHandle->interfaceHandle->endpointList.count; count++) + { + if (*temp8 == ccidHandle->interfaceHandle->endpointList.endpoint[count].endpointAddress) + { + /* Only stall the endpoint belongs to the interface of the class */ + error = USB_DeviceStallEndpoint(ccidHandle->handle, *temp8); + } + } + break; + case kUSB_DeviceClassEventClearEndpointHalt: + if ((!ccidHandle->configStruct) || (!ccidHandle->interfaceHandle)) + { + break; + } + /* Get the endpoint address */ + temp8 = ((uint8_t *)param); + for (int count = 0U; count < ccidHandle->interfaceHandle->endpointList.count; count++) + { + if (*temp8 == ccidHandle->interfaceHandle->endpointList.endpoint[count].endpointAddress) + { + /* Only un-stall the endpoint belongs to the interface of the class */ + error = USB_DeviceUnstallEndpoint(ccidHandle->handle, *temp8); + } + } + break; + case kUSB_DeviceClassEventClassRequest: + if (param) + { + /* Handle the ccid class specific request. */ + usb_device_control_request_struct_t *controlRequest = (usb_device_control_request_struct_t *)param; + + if ((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != + USB_REQUEST_TYPE_RECIPIENT_INTERFACE) + { + break; + } + + if ((controlRequest->setup->wIndex & 0xFFU) != ccidHandle->interfaceNumber) + { + break; + } + + switch (controlRequest->setup->bRequest) + { + case USB_DEVICE_CCID_ABORT: + /* Abort a command */ + if (ccidHandle->configStruct->classCallback) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = ccidHandle->configStruct->classCallback((class_handle_t)ccidHandle, + kUSB_DeviceCcidEventCommandAbort, + &controlRequest->setup->wValue); + } + break; + case USB_DEVICE_CCID_GET_CLOCK_FREQUENCIES: + /* Get the clock frequencies */ + if (ccidHandle->configStruct->classCallback) + { + usb_device_ccid_control_request_struct_t ccid_request; + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = ccidHandle->configStruct->classCallback( + (class_handle_t)ccidHandle, kUSB_DeviceCcidEventGetClockFrequencies, &ccid_request); + if (kStatus_USB_Success == error) + { + controlRequest->buffer = ccid_request.buffer; + controlRequest->length = ccid_request.length; + } + } + break; + case USB_DEVICE_CCID_GET_DATA_RATES: + /* Get the data rates */ + if (ccidHandle->configStruct->classCallback) + { + usb_device_ccid_control_request_struct_t ccid_request; + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = ccidHandle->configStruct->classCallback( + (class_handle_t)ccidHandle, kUSB_DeviceCcidEventGetDataRate, &ccid_request); + if (kStatus_USB_Success == error) + { + controlRequest->buffer = ccid_request.buffer; + controlRequest->length = ccid_request.length; + } + } + break; + default: + error = kStatus_USB_InvalidRequest; + break; + } + } + break; + default: + break; + } + return error; +} + +/*! + * @brief Initialize the ccid class. + * + * This function is used to initialize the ccid class. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param config The class configuration information. + * @param handle It is out parameter, is used to return pointer of the video class handle to the caller. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCcidInit(uint8_t controllerId, usb_device_class_config_struct_t *config, class_handle_t *handle) +{ + usb_device_ccid_struct_t *ccidHandle; + usb_status_t error = kStatus_USB_Error; + + /* Allocate a ccid class handle. */ + error = USB_DeviceCcidAllocateHandle(&ccidHandle); + + if (kStatus_USB_Success != error) + { + return error; + } + /* Get the device handle according to the controller id. */ + error = USB_DeviceClassGetDeviceHandle(controllerId, &ccidHandle->handle); + + if (kStatus_USB_Success != error) + { + return error; + } + + if (!ccidHandle->handle) + { + USB_DeviceCcidFreeHandle(ccidHandle); + return kStatus_USB_InvalidHandle; + } + /* Save the configuration of the class. */ + ccidHandle->configStruct = config; + /* Clear the configuration value. */ + ccidHandle->configuration = 0U; + ccidHandle->alternate = 0xffU; + ccidHandle->bulkInBusy = 0U; + ccidHandle->endpointBulkIn = 0U; + ccidHandle->endpointBulkOut = 0U; + ccidHandle->endpointInterruptIn = 0U; + ccidHandle->slots = 0U; + ccidHandle->interruptInBusy = 0U; + ccidHandle->slotsChanged = 0U; + + if (ccidHandle->configStruct->classCallback) + { + /* Get the max slot count of the application. + classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + ccidHandle->configStruct->classCallback((class_handle_t)ccidHandle, kUSB_DeviceCcidEventGetSlotCount, + &ccidHandle->slots); + } + + if (ccidHandle->slots > USB_DEVICE_CONFIG_CCID_SLOT_MAX) + { + USB_DeviceCcidFreeHandle(ccidHandle); + return kStatus_USB_Error; + } + + ccidHandle->transferFree = &ccidHandle->transfers[0]; + ccidHandle->transferHead = &ccidHandle->transfers[0]; + for (uint8_t i = 1U; i < USB_DEVICE_CONFIG_CCID_TRANSFER_COUNT; i++) + { + ccidHandle->transferHead->next = &ccidHandle->transfers[i]; + ccidHandle->transferHead = &ccidHandle->transfers[i]; + } + ccidHandle->transferHead->next = NULL; + ccidHandle->transferHead = NULL; + + *handle = (class_handle_t)ccidHandle; + return error; +} + +/*! + * @brief De-initialize the device ccid class. + * + * The function de-initializes the device ccid class. + * + * @param handle The ccid class handle got from usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCcidDeinit(class_handle_t handle) +{ + usb_device_ccid_struct_t *ccidHandle; + usb_status_t error = kStatus_USB_Error; + + ccidHandle = (usb_device_ccid_struct_t *)handle; + + if (!ccidHandle) + { + return kStatus_USB_InvalidHandle; + } + /* De-initialzie the endpoints. */ + error = USB_DeviceCcidEndpointsDeinit(ccidHandle); + /* Free the ccid class handle. */ + USB_DeviceCcidFreeHandle(ccidHandle); + return error; +} + +/*! + * @brief Notify the slot status changed. + * + * The function is used to notify the slot status changed. This is a un-blocking function, the event + * kUSB_DeviceCcidEventSlotChangeSent + * will be asserted when the transfer completed. + * + * The slot status may not be sent to the host if the interrupt IN pipe is busy. And the status will be save internally, + * and will be sent to the host when the interrupt IN pipe callback called. So, the event + * kUSB_DeviceCcidEventSlotChangeSent + * happened times will not equal to the function call times of this function. + * + * @param handle The ccid class handle got from usb_device_class_config_struct_t::classHandle. + * @param slot The changed slot number. + * @param state The changed slot status. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCcidNotifySlotChange(class_handle_t handle, uint8_t slot, usb_device_ccid_slot_state_t state) +{ + usb_device_ccid_struct_t *ccidHandle; + usb_device_ccid_notify_slot_chnage_notification_t *ccidNotify; + usb_status_t error = kStatus_USB_Error; + USB_OSA_SR_ALLOC(); + + ccidHandle = (usb_device_ccid_struct_t *)handle; + + if (!ccidHandle) + { + return kStatus_USB_InvalidHandle; + } + + if (slot >= USB_DEVICE_CONFIG_CCID_SLOT_MAX) + { + return kStatus_USB_InvalidParameter; + } + + USB_OSA_ENTER_CRITICAL(); + ccidNotify = (usb_device_ccid_notify_slot_chnage_notification_t *)&ccidHandle->slotsChangeBuffer[0]; + + ccidNotify->bMessageType = USB_DEVICE_CCID_RDR_TO_PC_NOTIFYSLOTCHANGE; + ccidNotify->bmSlotICCState[slot >> 2] &= ~(0x03U << ((slot % 4U) << 1U)); + ccidNotify->bmSlotICCState[slot >> 2] |= + ((0x02U | ((kUSB_DeviceCcidSlotStateNoPresent == state) ? 0x00U : 0x01U)) << ((slot % 4U) << 1U)); + + if ((ccidHandle->configuration) && (ccidHandle->endpointInterruptIn)) + { + if (!ccidHandle->interruptInBusy) + { + ccidHandle->slotsSendingChangeBuffer[0] = ccidHandle->slotsChangeBuffer[0]; + for (uint8_t i = 1U; i < sizeof(ccidHandle->slotsChangeBuffer); i++) + { + ccidHandle->slotsSendingChangeBuffer[i] = ccidHandle->slotsChangeBuffer[i]; + ccidHandle->slotsChangeBuffer[i] &= ~0xAAU; + } + error = USB_DeviceSendRequest(ccidHandle->handle, ccidHandle->endpointInterruptIn, + ccidHandle->slotsSendingChangeBuffer, + sizeof(ccidHandle->slotsSendingChangeBuffer)); + if (kStatus_USB_Success == error) + { + ccidHandle->interruptInBusy = 1U; + } + } + else + { + ccidHandle->slotsChanged = 1U; + } + } + USB_OSA_EXIT_CRITICAL(); + return error; +} + +/*! + * @brief Notify the slot status changed. + * + * The function is used to notify the hardware error. This is a un-blocking function, the event + * kUSB_DeviceCcidEventHardwareErrorSent + * will be asserted when the transfer completed. + * + * If the interrupt IN pipe is busy, the function will return an error kStatus_USB_Error. + * + * @param handle The ccid class handle got from usb_device_class_config_struct_t::classHandle. + * @param slot The changed slot number. + * @param errorCode The hardware error code. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCcidNotifyHardwareError(class_handle_t handle, + uint8_t slot, + usb_device_ccid_hardware_error_t errorCode) +{ + usb_device_ccid_struct_t *ccidHandle; + usb_status_t error = kStatus_USB_Error; + USB_OSA_SR_ALLOC(); + + ccidHandle = (usb_device_ccid_struct_t *)handle; + + if (!ccidHandle) + { + return kStatus_USB_InvalidHandle; + } + + if (slot >= USB_DEVICE_CONFIG_CCID_SLOT_MAX) + { + return kStatus_USB_InvalidParameter; + } + + ccidHandle->hardwareError.bMessageType = USB_DEVICE_CCID_RDR_TO_PC_HARDWAREERROR; + ccidHandle->hardwareError.bHardwareErrorCode = errorCode; + ccidHandle->hardwareError.bSlot = slot; + ccidHandle->hardwareError.bSeq = ccidHandle->slotsSequenceNumber[slot]; + + USB_OSA_ENTER_CRITICAL(); + if ((ccidHandle->configuration) && (ccidHandle->endpointInterruptIn)) + { + if (!ccidHandle->interruptInBusy) + { + error = USB_DeviceSendRequest(ccidHandle->handle, ccidHandle->endpointInterruptIn, + (uint8_t *)&ccidHandle->hardwareError, sizeof(ccidHandle->hardwareError)); + if (kStatus_USB_Success == error) + { + ccidHandle->interruptInBusy = 1U; + } + } + } + USB_OSA_EXIT_CRITICAL(); + return error; +} +#endif diff --git a/usb/device/class/usb_device_ccid.h b/usb/device/class/usb_device_ccid.h new file mode 100644 index 0000000..10d2845 --- /dev/null +++ b/usb/device/class/usb_device_ccid.h @@ -0,0 +1,1096 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_CCID_H__ +#define __USB_DEVICE_CCID_H__ + +/*! + * @addtogroup usb_device_ccid_drv + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @name USB CCID device class configuration + * @{ + */ + +/*! @brief MAX slot number of the CCID device. */ +#define USB_DEVICE_CONFIG_CCID_SLOT_MAX (1U) +/*! @brief MAX transfer entity number of the CCID device. */ +#define USB_DEVICE_CONFIG_CCID_TRANSFER_COUNT (4U) +/*! @brief MAX maximum message length of the CCID device. */ +#define USB_DEVICE_CONFIG_CCID_MAX_MESSAGE_LENGTH (271U) + +/*! @}*/ + +/*! @brief CCID device class code */ +#define USB_DEVICE_CCID_CLASS_CODE (0x0BU) +/*! @brief CCID device subclass code */ +#define USB_DEVICE_CCID_SUBCLASS_CODE (0x00U) +/*! @brief CCID device protocol code */ +#define USB_DEVICE_CCID_PROTOCOL_CODE (0x00U) + +/*! + * @name USB CCID device class descriptor + * @{ + */ + +/* CCID device class-specific descriptor length */ +#define USB_DEVICE_CCID_DESCRIPTOR_LENGTH (0x36U) +/* CCID device class-specific descriptor type */ +#define USB_DEVICE_CCID_DESCRIPTOR_TYPE (0x21U) + +/* The voltage support in CCID device class-specific descriptor */ +#define USB_DEVICE_CCID_DESCRIPTOR_VOLTAGE_SUPPORT_BM_5V (0x01U) +#define USB_DEVICE_CCID_DESCRIPTOR_VOLTAGE_SUPPORT_BM_3V (0x02U) +#define USB_DEVICE_CCID_DESCRIPTOR_VOLTAGE_SUPPORT_BM_1V8 (0x04U) + +/* The protocol in CCID device class-specific descriptor */ +#define USB_DEVICE_CCID_DESCRIPTOR_PROTOCOLS_BM_T0 (0x00000001U) +#define USB_DEVICE_CCID_DESCRIPTOR_PROTOCOLS_BM_T1 (0x00000002U) + +/* The mechanical in CCID device class-specific descriptor */ +#define USB_DEVICE_CCID_DESCRIPTOR_MECHANICAL_BM_NO (0x00000000U) +#define USB_DEVICE_CCID_DESCRIPTOR_MECHANICAL_BM_ACCEPT (0x00000001U) +#define USB_DEVICE_CCID_DESCRIPTOR_MECHANICAL_BM_EJECTION (0x00000002U) +#define USB_DEVICE_CCID_DESCRIPTOR_MECHANICAL_BM_CAPTURE (0x00000004U) +#define USB_DEVICE_CCID_DESCRIPTOR_MECHANICAL_BM_LOCK_UNLCOK (0x00000008U) + +/* The features in CCID device class-specific descriptor */ +#define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_NO (0x00000000U) +#define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_AUTO_CONFIG_BASED_ON_ATR (0x00000002U) +#define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_AUTO_ACTIVE_ON_INSERTING (0x00000004U) +#define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_AUTO_VOLTAGE_SELECTION (0x00000008U) +#define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_AUTO_FREQUENCY_CHANGE (0x00000010U) +#define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_AUTO_BAUD_RATE_CHANGE (0x00000020U) +#define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_AUTO_NEGOTIATION (0x00000040U) +#define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_AUTO_PPS (0x00000080U) +#define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_CAN_SET_IN_STOP_MODE (0x00000100U) +#define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_NAD_VLAUE (0x00000200U) +#define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_AUTO_IFSD_EXCHANGE_AS_FIRST (0x00000400U) +#define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_TPDU_LEVEL_EXCHANGES (0x00010000U) +#define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_SHORT_APDU_LEVEL_EXCHANGES (0x00020000U) +#define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_SHORT_EXTENDED_APDU_LEVEL_EXCHANGES (0x00040000U) +#define USB_DEVICE_CCID_DESCRIPTOR_FEATURES_BM_SUPPORT_SUPPEND (0x00100000U) + +/* The PIN support in CCID device class-specific descriptor */ +#define USB_DEVICE_CCID_DESCRIPTOR_PIN_SUPPORT_BM_NO (0x00U) +#define USB_DEVICE_CCID_DESCRIPTOR_PIN_SUPPORT_BM_VERIFICATION_SUPPORTED (0x01U) +#define USB_DEVICE_CCID_DESCRIPTOR_PIN_SUPPORT_BM_MODIFICATION_SUPPORTED (0x02U) + +/*! @}*/ + +/*! @brief CCID device class-specific control pipe requests */ +#define USB_DEVICE_CCID_ABORT (0x01U) +#define USB_DEVICE_CCID_GET_CLOCK_FREQUENCIES (0x02U) +#define USB_DEVICE_CCID_GET_DATA_RATES (0x03U) + +/*! @brief The message type of CCID device class-specific bulk-out pipe (Command pipe) */ +#define USB_DEVICE_CCID_PC_TO_RDR_ICCPOWERON (0x62U) +#define USB_DEVICE_CCID_PC_TO_RDR_ICCPOWEROFF (0x63U) +#define USB_DEVICE_CCID_PC_TO_RDR_GETSLOTSTATUS (0x65U) +#define USB_DEVICE_CCID_PC_TO_RDR_XFRBLOCK (0x6FU) +#define USB_DEVICE_CCID_PC_TO_RDR_GETPARAMETERS (0x6CU) +#define USB_DEVICE_CCID_PC_TO_RDR_RESETPARAMETERS (0x6DU) +#define USB_DEVICE_CCID_PC_TO_RDR_SETPARAMETERS (0x61U) +#define USB_DEVICE_CCID_PC_TO_RDR_ESCAPE (0x6BU) +#define USB_DEVICE_CCID_PC_TO_RDR_ICCCLOCK (0x6EU) +#define USB_DEVICE_CCID_PC_TO_RDR_T0APDU (0x6AU) +#define USB_DEVICE_CCID_PC_TO_RDR_SECURE (0x69U) +#define USB_DEVICE_CCID_PC_TO_RDR_MECHANICAL (0x71U) +#define USB_DEVICE_CCID_PC_TO_RDR_ABORT (0x72U) +#define USB_DEVICE_CCID_PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY (0x73U) + +/*! @brief The message type of CCID device class-specific bulk-in pipe (Response pipe) */ +#define USB_DEVICE_CCID_RDR_TO_PC_DATABLOCK (0x80U) +#define USB_DEVICE_CCID_RDR_TO_PC_SLOTSTATUS (0x81U) +#define USB_DEVICE_CCID_CLCOK_STATUS_CLOCK_RUNNING (0x00U) +#define USB_DEVICE_CCID_CLCOK_STATUS_CLOCK_STOPPED_IN_L (0x01U) +#define USB_DEVICE_CCID_CLCOK_STATUS_CLOCK_STOPPED_IN_H (0x02U) +#define USB_DEVICE_CCID_CLCOK_STATUS_CLOCK_STOPPED_UNKNOWN (0x03U) +#define USB_DEVICE_CCID_RDR_TO_PC_PARAMETERS (0x82U) +#define USB_DEVICE_CCID_PROTOCOL_NUMBER_T0 (0x00U) +#define USB_DEVICE_CCID_PROTOCOL_NUMBER_T1 (0x01U) +#define USB_DEVICE_CCID_RDR_TO_PC_ESCAPE (0x83U) +#define USB_DEVICE_CCID_RDR_TO_PC_DATARATEANDCLOCKFREQUENCY (0x84U) + +/*! @brief The message type of CCID device class-specific interrupt-in pipe */ +#define USB_DEVICE_CCID_RDR_TO_PC_NOTIFYSLOTCHANGE (0x50U) +#define USB_DEVICE_CCID_RDR_TO_PC_HARDWAREERROR (0x51U) + +/*! @brief Reporting slot error and slot status registers in bulk-in messages */ +/* Slot error register when bmCommandStatus = 1U */ +#define USB_DEVICE_CCID_SLOT_ERROR_COMMAND_NOT_SUPPORTED (0x00U) +#define USB_DEVICE_CCID_SLOT_ERROR_BAD_LENGTH (0x01U) +#define USB_DEVICE_CCID_SLOT_ERROR_SLOT_NOT_EXIST (0x05U) +#define USB_DEVICE_CCID_SLOT_ERROR_POWER_SELECT (0x07U) +#define USB_DEVICE_CCID_SLOT_ERROR_PROTOCOL_INVALID (0x07U) +#define USB_DEVICE_CCID_SLOT_ERROR_BAD_LEVEL_PARAMETER (0x08U) +#define USB_DEVICE_CCID_SLOT_ERROR_FI_DI_INVALID (0x0AU) +#define USB_DEVICE_CCID_SLOT_ERROR_INVALID_TCCKTS_PARAMETER (0x0BU) +#define USB_DEVICE_CCID_SLOT_ERROR_GUARD_TIME_NOT_SUPPORTED (0x0CU) +#define USB_DEVICE_CCID_SLOT_ERROR_xWI_INVALID (0x0DU) +#define USB_DEVICE_CCID_SLOT_ERROR_CLOCK_STOP_INVALID (0x0EU) +#define USB_DEVICE_CCID_SLOT_ERROR_IFSC_SIZE_INVALID (0x0FU) +#define USB_DEVICE_CCID_SLOT_ERROR_NAD_VALUE_INVALID (0x10U) + +#define USB_DEVICE_CCID_SLOT_ERROR_CMD_ABORTED (0xFFU) +#define USB_DEVICE_CCID_SLOT_ERROR_ICC_MUTE (0xFEU) +#define USB_DEVICE_CCID_SLOT_ERROR_XFR_PARITY_ERROR (0xFDU) +#define USB_DEVICE_CCID_SLOT_ERROR_XFR_OVERRUN (0xFCU) +#define USB_DEVICE_CCID_SLOT_ERROR_HW_ERROR (0xFBU) +#define USB_DEVICE_CCID_SLOT_ERROR_BAD_ATR_TS (0xF8U) +#define USB_DEVICE_CCID_SLOT_ERROR_BAD_ATR_TCK (0xF7U) +#define USB_DEVICE_CCID_SLOT_ERROR_ICC_PROTOCOL_NOT_SUPPORTED (0xF6U) +#define USB_DEVICE_CCID_SLOT_ERROR_ICC_CLASS_NOT_SUPPORTED (0xF5U) +#define USB_DEVICE_CCID_SLOT_ERROR_PROCEDURE_BYTE_CONFICT (0xF4U) +#define USB_DEVICE_CCID_SLOT_ERROR_DEACTIVATED_PROCTOCL (0xF3U) +#define USB_DEVICE_CCID_SLOT_ERROR_BUSY_WITH_AUTO_SEQUENCE (0xF2U) +#define USB_DEVICE_CCID_SLOT_ERROR_PIN_TIMEOUT (0xF0U) +#define USB_DEVICE_CCID_SLOT_ERROR_PIN_CANCELLED (0xEFU) +#define USB_DEVICE_CCID_SLOT_ERROR_CMD_SLOT_BUSY (0xE0U) + +#define USB_DEVICE_CCID_SLOT_ERROR_CMD_NOT_ABORTED (0xC0U) + +/* CCID slot status code */ +#define USB_DEVICE_CCID_SLOT_STATUS_ICC_STATUS_SHIFT (0x00U) +#define USB_DEVICE_CCID_SLOT_STATUS_ICC_STATUS_MASK (0x03U) +#define USB_DEVICE_CCID_SLOT_STATUS_COMMAND_STATUS_SHIFT (0x06U) +#define USB_DEVICE_CCID_SLOT_STATUS_COMMAND_STATUS_MASK (0xC0U) + +/* bmICCStatus */ +#define USB_DEVICE_CCID_SLOT_STATUS_ICC_PRESENT_ACTIVE (0x00U) +#define USB_DEVICE_CCID_SLOT_STATUS_ICC_PRESENT_INACTIVE (0x01U) +#define USB_DEVICE_CCID_SLOT_STATUS_ICC_NOT_PRESENT (0x02U) + +/* bmCommandStatus */ +#define USB_DEVICE_CCID_SLOT_STATUS_COMMAND_STATUS_PROCESSED_NO_ERROR (0x00U) +#define USB_DEVICE_CCID_SLOT_STATUS_COMMAND_STATUS_FAILED (0x40U) +#define USB_DEVICE_CCID_SLOT_STATUS_COMMAND_STATUS_TIME_EXTENSION_REQUESTED (0x80U) + +/*! @brief The command header length of the bulk-out pipe message. */ +#define USB_DEVICE_CCID_COMMAND_HEADER_LENGTH (0x0AU) +/*! @brief The response header length of the bulk-in pipe message. */ +#define USB_DEVICE_CCID_RESPONSE_HEADER_LENGTH (0x0AU) + +/*! + * @brief Common command structure of the command message in the bulk-out pipe. + * + */ +STRUCT_PACKED +struct _usb_device_ccid_common_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Message-specific data length */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bParameter1; /*!< Parameter1 of the message, message-specific */ + uint8_t bParameter2; /*!< Parameter2 of the message, message-specific */ + uint8_t bParameter3; /*!< Parameter3 of the message, message-specific */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_common_command usb_device_ccid_common_command_t; + +/*! + * @brief ICC power on command structure of the command message in the bulk-out pipe. + * + * A PC_to_RDR_IccPowerOn message to an inactive slot returns an Answer-To-Reset (ATR) data. + * + * The response to this command message is the RDR_to_PC_DataBlock response message and the + * data returned is the Answer To Reset (ATR) data. + */ +STRUCT_PACKED +struct _usb_device_ccid_power_on_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Message-specific data length */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bPowerSelect; /*!< Voltage that is applied to the ICC */ + uint8_t bRFU[2]; /*!< Reserved for Future Use */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_power_on_command usb_device_ccid_power_on_command_t; + +/*! + * @brief ICC power off command structure of the command message in the bulk-out pipe. + * + * The response to this command message is the RDR_to_PC_SlotStatus response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_power_off_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Message-specific data length */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bRFU[3]; /*!< Reserved for Future Use */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_power_off_command usb_device_ccid_power_off_command_t; + +/*! + * @brief Gets the slot status command structure of the command message in the bulk-out pipe. + * + * The response to this command message is the RDR_to_PC_SlotStatus response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_get_slot_status_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Message-specific data length */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bRFU[3]; /*!< Reserved for Future Use */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_get_slot_status_command usb_device_ccid_get_slot_status_command_t; + +/*! + * @brief Transfer data block command structure of the command message in the bulk-out pipe. + * + * The block should never exceed the dwMaxCCIDMessageLength-10 in the Class Descriptor. + * Parameter bBWI is only used by CCIDs which use the character level and TPDU level of exchange + * (as reported in the dwFeatures parameter in the CCID Functional Descriptor) and only for protocol T=1 transfers. + * + * The response to this command message is the RDR_to_PC_DataBlock response message. + * + * @note For reference, the absolute maximum block size for a TPDU T=0 block is 260U bytes (5U bytes command; 255U bytes + * data), + * or for a TPDU T=1 block is 259U bytes, or for a short APDU T=1 block is 261U bytes, or for an extended APDU T=1 block + * is 65544U bytes. + */ +STRUCT_PACKED +struct _usb_device_ccid_transfer_block_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Size of abData field of this message */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bBWI; /*!< Used to extend the CCIDs Block Waiting Timeout for this current transfer */ + uint16_t wLevelParameter; /*!< Use changes depending on the exchange level reported by the class descriptor in + dwFeatures field */ + uint8_t abData[1]; /*!< Data block sent to the CCID */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_transfer_block_command usb_device_ccid_transfer_block_command_t; + +/*! + * @brief Gets the ICC parameter command structure of the command message in the bulk-out pipe. + * + * The response to this command message is the RDR_to_PC_Parameters response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_get_parameters_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Message-specific data length */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bRFU[3]; /*!< Reserved for Future use */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_get_parameters_command usb_device_ccid_get_parameters_command_t; + +/*! + * @brief Resets the ICC parameter command structure of the command message in the bulk-out pipe. + * + * This command resets the slot parameters to their default values. + * + * The response to this command message is the RDR_to_PC_Parameters response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_reset_parameters_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Message-specific data length */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bRFU[3]; /*!< Reserved for Future Use */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_reset_parameters_command usb_device_ccid_reset_parameters_command_t; + +/*! + * @brief Sets the ICC parameter command structure of the command message in the bulk-out pipe. + * + * This command is used to change the parameters for a given slot. + * A CCID which has no automatic features (dwFeatures=0, 100h, 200h, or 300h) depends on the driver to send this command + * to set the protocol and other parameters to the right values necessary to correctly talk to the ICC located in the + * selected slot. + * A CCID which has automatic features automatically sets the protocol and certain parameters based on data received + * from the ICC (ATR, PPS, IFSD, or proprietary algorithms). The level of automatism and design requirements + * determines which parameters the CCID allow the driver to change. + * If this command tries to change a parameter which is not changeable, then the CCID does not change any parameters and + * the RDR_to_PC_GetParameters response returns a Command Failed status and the bError field contains the offset + * of the "offending" parameter. + * + * The response to this command message is the RDR_to_PC_Parameters response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_set_parameters_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Size of abProtocolDataStructure field of this message */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bProtocolNum; /*!< Specifies what protocol data structure follows. 00h = Structure for protocol T=0, 01h = + Structure for protocol T=1 */ + uint8_t bRFU[2]; /*!< Reserved for Future Use */ + uint8_t abProtocolDataStructure[1]; /*!< Protocol Data Structure. For T = 0U, see + usb_device_ccid_set_parameters_t0_command_t, for T = 1U, see + usb_device_ccid_set_parameters_t1_command_t. */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_set_parameters_command usb_device_ccid_set_parameters_command_t; + +/*! + * @brief Sets the ICC(T=0) parameter command structure of the command message in the bulk-out pipe. + * + * Protocol Data Structure for Protocol T=0 (bProtocolNum=0) (dwLength=00000005h). + * + * The response to this command message is the RDR_to_PC_Parameters response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_set_parameters_t0_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< (dwLength = 0x05U) */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bProtocolNum; /*!< Structure for protocol T=0 */ + uint8_t bRFU[2]; /*!< Reserved for Future Use */ + uint8_t bmFindexDindex; /*!< Bit7~4 - Fi, Bit3~0 - Di. */ + uint8_t bmTCCKST0; /*!< Bit1 - Convention used(0U for direct, 1U for inverse), other bits is 0*/ + uint8_t bGuardTimeT0; /*!< Extra guard time between two characters. */ + uint8_t bWaitingIntegerT0; /*!< WI for T= 0U used to define WWT */ + uint8_t bClockStop; /*!< ICC Clock Stop Support */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_set_parameters_t0_command usb_device_ccid_set_parameters_t0_command_t; + +/*! + * @brief Sets the ICC(T=1) parameter command structure of the command message in the bulk-out pipe. + * + * Protocol Data Structure for Protocol T=1 (bProtocolNum=1) (dwLength=00000007h) + * + * The response to this command message is the RDR_to_PC_Parameters response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_set_parameters_t1_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< (dwLength = 0x07U) */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bProtocolNum; /*!< Structure for protocol T=1 */ + uint8_t bRFU[2]; /*!< Reserved for Future Use */ + uint8_t bmFindexDindex; /*!< Bit7~4 - Fi, Bit3~0 - Di. */ + uint8_t bmTCCKST1; /*!< Bit0 - Checksum type(0U for LRC, 1U for CRC). Bit1 - Convention used(0U for direct, 1U for + inverse), Bit7~2 - 0b000100 */ + uint8_t bGuardTimeT1; /*!< Extra guard time. */ + uint8_t bmWaitingIntegersT1; /*!< Bit7~4 - BWI(0~9 valid), Bit3~0 - CWI(0~0xF valid) */ + uint8_t bClockStop; /*!< ICC Clock Stop Support */ + uint8_t bIFSC; /*!< Size of negotiated IFSC */ + uint8_t bNadValue; /*!< Value = 0x00U if CCID doesn't support a value other then the default value. Else value + respects ISO/IEC 7816-3, 9.4.2.1 */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_set_parameters_t1_command usb_device_ccid_set_parameters_t1_command_t; + +/*! @brief Sets the ICC parameter command union of the command message in the bulk-out pipe. */ +typedef union _usb_device_ccid_set_parameters_command_common +{ + usb_device_ccid_set_parameters_command_t common; /*!< Set ICC parameter common structure */ + usb_device_ccid_set_parameters_t0_command_t t0; /*!< Set ICC parameter structure for T0 */ + usb_device_ccid_set_parameters_t1_command_t t1; /*!< Set ICC parameter structure for T1 */ +} usb_device_ccid_set_parameters_command_common_t; + +/*! + * @brief Escape command structure of the command message in the bulk-out pipe. + * + * This command allows the CCID manufacturer to define and access extended features. + * Information sent via this command is processed by the CCID control logic. + * + * The response to this command message is the RDR_to_PC_Escape response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_escape_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Message-specific data length */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bRFU[3]; /*!< Reserved for future use */ + uint8_t abData[1]; /*!< Size of abData field of this message */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_escape_command usb_device_ccid_escape_command_t; + +/*! + * @brief Controls the ICC clock command structure of the command message in the bulk-out pipe. + * + * This command stops or restarts the clock. + * + * The response to this command message is the RDR_to_PC_SlotStatus response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_clock_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Message-specific data length */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bClockCommand; /*!< 0x00U - Restart clock, 0x01U - Stop clock in the state shown in the bClockStop field of + the PC_to_RDR_SetParameters command and RDR_to_PC_Parameters message.*/ + uint8_t bRFU[2]; /*!< Reserved for future use */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_clock_command usb_device_ccid_clock_command_t; + +/*! + * @brief Controls the ICC clock command structure of the command message in the bulk-out pipe. + * + * This command changes the parameters used to perform the transportation of APDU messages by the T=0 protocol. + * It effects the CLA (class) byte used when issuing a Get Response command or a Envelope command to the ICC. + * + * This command is slot-specific. It only effects the slot specified in the bSlot field. + * Slots, when not powered, do not change back to using the default behaviour defined in the CCID class descriptor. + * Any newly inserted ICC has the default behaviour until this command is issued for its slot. + * + * The response to this command message is the RDR_to_PC_SlotStatus response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_t0_apdu_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Message-specific data length */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bmChanges; /*!< + * The value is bitwise OR operation. + * Bit 0U is associated with field bClassGetResponse + * Bit 1U is associated with field bClassEnvelope + * Other bits are RFU. */ + uint8_t bClassGetResponse; /*!< Value to force the class byte of the header in a get response command */ + uint8_t bClassEnvelope; /*!< Value to force the class byte of the header in a envelope command */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_t0_apdu_command usb_device_ccid_t0_apdu_command_t; + +/*! + * @brief Secures the command structure of the command message in the bulk-out pipe. + * + * This is a command message to allow entering the PIN for verification or modification. + * + * The response to this command message is the RDR_to_PC_DataBlock response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_secure_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Size of abData field of this message */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bBWI; /*!< Used to extend the CCIDs Block Waiting Timeout for this current transfer */ + uint16_t wLevelParameter; /*!< Use changes depending on the exchange level reported by CCID in the functional + descriptor */ + uint8_t abData[1]; /*!< + * The value depends of wLevelParameters. + * When wLevelParameters is 0000h or 0001h abData = abPINOperationDataStructure. + * For other values of wLevelParameters this field is the continuation of the previously sent + * PC_to_RDR_Secure. + */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_secure_command usb_device_ccid_secure_command_t; + +/*! + * @brief Secures the PIN operation command structure of the command message in the bulk-out pipe. + * + * This is a command message to allow entering the PIN for verification or modification. + * + * The response to this command message is the RDR_to_PC_DataBlock response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_secure_pin_operation_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< 1U + Size of abPINDataStructure field of this message */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bBWI; /*!< Used to extend the CCIDs Block Waiting Timeout for this current transfer */ + uint16_t wLevelParameter; /*!< Use changes depending on the exchange level reported by CCID in the functional + descriptor */ + uint8_t bPINOperation; /*!< + * Used to indicate the PIN operation: + * 00h: PIN Verification + * 01h: PIN Modification + * 02h: Transfer PIN from secure CCID buffer + * 03h: Wait ICC response + * 04h: Cancel PIN function + * 05h: Re-send last I-Block, valid only if T = 1. + * 06h: Send next part of APDU, valid only T = 1. + */ + uint8_t abPINDataStructure[1]; /* PIN Verification Data Structure or PIN Modification Data Structure */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_secure_pin_operation_command usb_device_ccid_secure_pin_operation_command_t; + +/*! + * @brief Secures the PIN verification operation command structure of the command message in the bulk-out pipe. + * + * This is a command message to allow entering the PIN for verification. + * + * The response to this command message is the RDR_to_PC_DataBlock response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_seucre_pin_verification_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< 12U + Size of abPINApdu field of this message */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bBWI; /*!< Used to extend the CCIDs Block Waiting Timeout for this current transfer */ + uint16_t wLevelParameter; /*!< Use changes depending on the exchange level reported by CCID in the functional + descriptor */ + uint8_t bPINOperation; /*!< + * Used to indicate the PIN operation: + * 00h: PIN Verification + * 01h: PIN Modification + * 02h: Transfer PIN from secure CCID buffer + * 03h: Wait ICC response + * 04h: Cancel PIN function + * 05h: Re-send last I-Block, valid only if T = 1. + * 06h: Send next part of APDU, valid only T = 1. + */ + uint8_t bTimeOut; /*!< Number of seconds */ + uint8_t bmFormatString; /*!< Several parameters for the PIN format options */ + uint8_t bmPINBlockString; /*!< Defines the length in bytes of the PIN block to present in the APDU command */ + uint8_t bmPINLengthFormat; /*!< Allows the insertion of the PIN length in the APDU command */ + uint16_t wPINMaxExtraDigit; /*!< Bit15~8 - Minimum PIN size in digit, Bit7~0 - Maximum PIN size in digit */ + uint8_t bEntryValidationCondition; /*!< The value is a bit wise OR operation. 01h - Maximum size reached, 02h - + Validation key pressed, 04h - Timeout occurred*/ + uint8_t bNumberMessage; /*!< Number of messages to display for the PIN Verification management. */ + uint16_t wLangId; /*!< Language used to display the messages.*/ + uint8_t bMsgIndex; /*!< Message index in the Reader CCID message table (should be 00h). */ + uint8_t bTeoPrologue; /*!< T=1 I-block prologue field to use. */ + uint8_t abPINApdu[1]; /*!< APDU to send to the ICC */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_seucre_pin_verification_command usb_device_ccid_seucre_pin_verification_command_t; + +/*! + * @brief Secures the PIN modification operation command structure of the command message in the bulk-out pipe. + * + * This is a command message to allow entering the PIN for modification. + * + * The response to this command message is the RDR_to_PC_DataBlock response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_secure_pin_modification_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< 20U + Size of abPINApdu field of this message */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bBWI; /*!< Used to extend the CCIDs Block Waiting Timeout for this current transfer */ + uint16_t wLevelParameter; /*!< Use changes depending on the exchange level reported by CCID in the functional + descriptor */ + uint8_t bPINOperation; /*!< + * Used to indicate the PIN operation: + * 00h: PIN Verification + * 01h: PIN Modification + * 02h: Transfer PIN from secure CCID buffer + * 03h: Wait ICC response + * 04h: Cancel PIN function + * 05h: Re-send last I-Block, valid only if T = 1. + * 06h: Send next part of APDU, valid only T = 1. + */ + uint8_t bTimeOut; /*!< Number of seconds */ + uint8_t bmFormatString; /*!< Several parameters for the PIN format options */ + uint8_t bmPINBlockString; /*!< Define the length of the PIN to present in the APDU command */ + uint8_t bmPINLengthFormat; /*!< Allows the length PIN insertion in the APDU command */ + uint8_t bInsertionOffsetOld; /*!< Insertion position offset in byte for the current PIN */ + uint8_t bInsertionOffsetNew; /*!< Insertion position offset in byte for the new PIN */ + uint16_t wPINMaxExtraDigit; /*!< Bit15~8 - Minimum PIN size in digit, Bit7~0 - Maximum PIN size in digit */ + uint8_t bConfirmPIN; /*!< Indicates if a confirmation is requested before acceptance of a new PIN */ + uint8_t bEntryValidationCondition; /*!< The value is a bit wise OR operation. 01h - Maximum size reached, 02h - + Validation key pressed, 04h - Timeout occurred*/ + uint8_t bNumberMessage; /*!< Number of messages to display for the PIN Verification management. */ + uint16_t wLangId; /*!< Language used to display the messages.*/ + uint8_t bMsgIndex1; /*!< Message index in the Reader message table(should be 00h or 01h). */ + uint8_t bMsgIndex2; /*!< Message index in the Reader message table(should be 01h or 02h). */ + uint8_t bMsgIndex3; /*!< Message index in the Reader message table(should be 02h). */ + uint8_t bTeoPrologue[3]; /*!< T=1 I-block prologue field to use. */ + uint8_t abPINApdu[1]; /*!< APDU to send to the ICC */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_secure_pin_modification_command usb_device_ccid_secure_pin_modification_command_t; + +/*! + * @brief Manages the motorized type CCID functionality command structure of the command message in the bulk-out pipe. + * + * This command is used to manage motorized type CCID functionality. + * + * The response to this command message is the RDR_to_PC_SlotStatus response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_mechanical_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Message-specific data length */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bFunction; /*!< This value corresponds to the mechanical function being requested */ + uint8_t bRFU[2]; /*!< Reserved for Future Use */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_mechanical_command usb_device_ccid_mechanical_command_t; + +/*! + * @brief Aborts the command structure of the command message in the bulk-out pipe. + * + * This command is used with the control pipe abort request to tell the + * CCID to stop any current transfer at the specified slot and return to a state + * where the slot is ready to accept a new command pipe Bulk-OUT message. + * + * The response to this command message is the RDR_to_PC_SlotStatus response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_abort_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Message-specific data length */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bRFU[3]; /*!< Reserved for future use */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_abort_command usb_device_ccid_abort_command_t; + +/*! + * @brief Sets data rate and clock frequency command structure of the command message in the bulk-out pipe. + * + * This command is used to manually set the data rate and clock frequency of a specific slot. + * + * The response to this command message is the RDR_to_PC_SlotStatus response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_set_data_rate_and_clock_frequency_command +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Message-specific data length(8U bytes) */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for command */ + uint8_t bRFU[3]; /*!< Reserved for Future Use */ + uint32_t dwClockFrequency; /*!< ICC clock frequency in kHz. This is an integer value */ + uint32_t dwDataRate; /*!< ICC data rate in BPD */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_set_data_rate_and_clock_frequency_command + usb_device_ccid_set_data_rate_and_clock_frequency_command_t; + +/*! + * @brief Common response structure to respond a command message in the bulk-in pipe. + * + */ +STRUCT_PACKED +struct _usb_device_ccid_common_response +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Message-specific data length */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for the corresponding command */ + uint8_t bStatus; /*!< Slot status register */ + uint8_t bError; /*!< Slot error register */ + uint8_t bParameter1; /*!< Parameter1 of the message, message-specific */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_common_response usb_device_ccid_common_response_t; + +/*! + * @brief Data block response structure to respond a command message in the bulk-in pipe. + * + * The device in response to the following command messages: "PC_to_RDR_IccPowerOn", "PC_to_RDR_Secure" and + * "PC_to_RDR_XfrBlock" sends this response message. + * For "PC_to_RDR_IccPowerOn" this response message is the answer to reset (ATR) data associated with the ICC power on. + * In other use cases, the response message has the following format: the response data contains the + * optional data returned by the ICC, followed by the 2U byte-size status words SW1-SW2. + */ +STRUCT_PACKED +struct _usb_device_ccid_data_block_response +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Message-specific data length */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for the corresponding command */ + uint8_t bStatus; /*!< Slot status register */ + uint8_t bError; /*!< Slot error register */ + uint8_t bChainParameter; /*!< Use changes depending on the exchange level reported by the class descriptor in + dwFeatures field */ + uint8_t abData[1]; /*!< This field contains the data returned by the CCID. */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_data_block_response usb_device_ccid_data_block_response_t; + +/*! + * @brief Sends a slot status response structure to respond a command message in the bulk-in pipe. + * + * The device in response to the following command messages: "PC_to_RDR_IccPowerOff", "PC_to_RDR_GetSlotStatus", + * "PC_to_RDR_IccClock", "PC_to_RDR_T0APDU" and, "PC_to_RDR_Mechanical" sends this response message. + * Also, the device sends this response message when it has completed aborting a slot after receiving + * both the Class Specific ABORT request and PC_to_RDR_Abort command message. + */ +STRUCT_PACKED +struct _usb_device_ccid_slot_status_response +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Message-specific data length */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for the corresponding command */ + uint8_t bStatus; /*!< Slot status register */ + uint8_t bError; /*!< Slot error register */ + uint8_t + bClockStatus; /*!< 0x00U - Clock running, 0x01U - Clock stopped in L, 0x02U - clock stopped in H, and 0x03U - + clock stopped in an unknown state.*/ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_slot_status_response usb_device_ccid_slot_status_response_t; + +/*! + * @brief ICC parameter response structure to respond a command message in the bulk-in pipe. + * + * The device in response to the following command messages: "PC_to_RDR_GetParameters", "PC_to_RDR_ResetParameters", + * and, "PC_to_RDR_SetParameters" sends this response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_parameters_response +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Size of abProtocolDataStructure field of this message */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for the corresponding command */ + uint8_t bStatus; /*!< Slot status register */ + uint8_t bError; /*!< Slot error register */ + uint8_t bProtocolNum; /*!< 0x00U = Structure for protocol T=0, 0x01U = Structure for protocol T=1 */ + uint8_t abProtocolDataStructure[1]; /*!< Protocol Data Structure */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_parameters_response usb_device_ccid_parameters_response_t; + +/*! + * @brief ICC T0 parameter response structure to respond a command message in the bulk-in pipe. + * + * The device in response to the following command messages: "PC_to_RDR_GetParameters", "PC_to_RDR_ResetParameters", + * and, "PC_to_RDR_SetParameters" sends this response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_parameters_T0_response +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< The value is 0x05U */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for the corresponding command */ + uint8_t bStatus; /*!< Slot status register */ + uint8_t bError; /*!< Slot error register */ + uint8_t bProtocolNum; /*!< 0x00U = Structure for protocol T=0 */ + uint8_t bmFindexDindex; /*!< Bit7~4 - Fi, Bit3~0 - Di. */ + uint8_t bmTCCKST0; /*!< Bit1 - Convention used(0U for direct, 1U for inverse), other bits is 0*/ + uint8_t bGuardTimeT0; /*!< Extra guard time between two characters. */ + uint8_t bWaitingIntegerT0; /*!< WI for T= 0U used to define WWT */ + uint8_t bClockStop; /*!< ICC Clock Stop Support */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_parameters_T0_response usb_device_ccid_parameters_T0_response_t; + +/*! + * @brief ICC T1 parameter response structure to response a command message in the bulk-in pipe. + * + * The device in response to the following command messages: "PC_to_RDR_GetParameters", "PC_to_RDR_ResetParameters", + * and, "PC_to_RDR_SetParameters" sends this response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_parameters_T1_response +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< The value is 0x07U */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for the corresponding command */ + uint8_t bStatus; /*!< Slot status register */ + uint8_t bError; /*!< Slot error register */ + uint8_t bProtocolNum; /*!< 0x00U = Structure for protocol T=1 */ + uint8_t bmFindexDindex; /*!< Bit7~4 - Fi, Bit3~0 - Di. */ + uint8_t bmTCCKST1; /*!< Bit0 - Checksum type(0U for LRC, 1U for CRC). Bit1 - Convention used(0U for direct, 1U for + inverse), Bit7~2 - 0b000100 */ + uint8_t bGuardTimeT1; /*!< Extra guard time. */ + uint8_t bmWaitingIntegersT1; /*!< Bit7~4 - BWI(0~9 valid), Bit3~0 - CWI(0~0xF valid) */ + uint8_t bClockStop; /*!< ICC Clock Stop Support */ + uint8_t bIFSC; /*!< Size of negotiated IFSC */ + uint8_t bNadValue; /*!< Value = 0x00U if CCID doesn't support a value other then the default value. Else value + respects ISO/IEC 7816-3, 9.4.2.1 */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_parameters_T1_response usb_device_ccid_parameters_T1_response_t; + +/*! @brief ICC parameter response union to response a command message in the bulk-in pipe. */ +typedef union _usb_device_ccid_parameters_response_common +{ + usb_device_ccid_parameters_response_t common; /*!< Response ICC parameter common structure */ + usb_device_ccid_parameters_T0_response_t t0; /*!< Response ICC parameter structure for T0 */ + usb_device_ccid_parameters_T1_response_t t1; /*!< Response ICC parameter structure for T1 */ +} usb_device_ccid_parameters_response_common_t; + +/*! + * @brief Response structure to respond the "PC_to_RDR_Escape" command message in the bulk-in pipe. + * + * The device in response to the following command messages: "PC_to_RDR_Escape" sends this response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_escape_response +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Size of abData field of this message */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for the corresponding command */ + uint8_t bStatus; /*!< Slot status register */ + uint8_t bError; /*!< Slot error register */ + uint8_t bRFU; /*!< Reserved for Future Use */ + uint8_t abData[1]; /*!< Data sent from CCID */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_escape_response usb_device_ccid_escape_response_t; + +/*! + * @brief Response structure to respond the "PC_to_RDR_SetDataRateAndClockFrequency" command message in the bulk-in + * pipe. + * + * The device in response to the following command messages: "PC_to_RDR_SetDataRateAndClockFrequency" sends this + * response message. + */ +STRUCT_PACKED +struct _usb_device_ccid_data_rate_and_clock_frequency_response +{ + uint8_t bMessageType; /*!< The message type */ + uint32_t dwLength; /*!< Message-specific data length */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number for the corresponding command */ + uint8_t bStatus; /*!< Slot status register */ + uint8_t bError; /*!< Slot error register */ + uint8_t bRFU; /*!< Reserved for Future Use */ + uint32_t dwClockFrequency; /*!< Current setting of the ICC clock frequency in KHz. This is an integer value */ + uint32_t dwDataRate; /*!< Current setting of the ICC data rate in bps. This is an integer value */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_data_rate_and_clock_frequency_response + usb_device_ccid_data_rate_and_clock_frequency_response_t; + +/*! @brief Notification structure to notify Host the CCID device slot changed */ +STRUCT_PACKED +struct _usb_device_ccid_notify_slot_chnage_notification +{ + uint8_t bMessageType; /*!< The message type */ + uint8_t bmSlotICCState[1]; /*!< This field is reported on byte granularity. */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_notify_slot_chnage_notification usb_device_ccid_notify_slot_chnage_notification_t; + +/*! @brief Notification structure to notify Host a hardware error happened in the CCID device */ +STRUCT_PACKED +struct _usb_device_ccid_hardware_error_notification +{ + uint8_t bMessageType; /*!< The message type */ + uint8_t bSlot; /*!< Identifies the slot number for this command */ + uint8_t bSeq; /*!< Sequence number of bulk out command when the hardware error occurred */ + uint8_t bHardwareErrorCode; /*!< 0x01U - Over current. */ +} STRUCT_UNPACKED; +typedef struct _usb_device_ccid_hardware_error_notification usb_device_ccid_hardware_error_notification_t; + +/*! @brief The definition to make the length aligned to 4-bytes */ +#define USB_DEVICE_CCID_BUFFER_4BYTE_ALIGN(n) (((n - 1U) & 0xFFFFFFFCU) + 0x00000004U) + +/*! @brief USB device CCID transfer structure */ +typedef struct _usb_device_ccid_transfer_struct +{ + struct _usb_device_ccid_transfer_struct *next; /*!< Next transfer pointer */ + uint8_t *buffer; /*!< The transfer buffer address need to be sent */ + uint32_t length; /*!< The transfer length */ + usb_device_ccid_slot_status_response_t response; /*!< Response buffer is used when dwLength = 0. */ +} usb_device_ccid_transfer_struct_t; + +/*! @brief Available common EVENT types in CCID class callback */ +typedef enum _usb_device_ccid_event +{ + kUSB_DeviceCcidEventCommandReceived = 0x01U, /*!< Command received or cancelled in BULK OUT pipe */ + kUSB_DeviceCcidEventResponseSent, /*!< Response sent in BULK IN pipe */ + kUSB_DeviceCcidEventGetSlotCount, /*!< Get the slot count */ + kUSB_DeviceCcidEventGetSlotStatus, /*!< Get the slot status, including clock status, ICC present.*/ + kUSB_DeviceCcidEventCommandAbort, /*!< Command abort request received from control pipe*/ + kUSB_DeviceCcidEventGetClockFrequencies, /*!< Get the clock frequencies */ + kUSB_DeviceCcidEventGetDataRate, /*!< Get the data rate */ + kUSB_DeviceCcidEventSlotChangeSent, /*!< Slot changed notification send completed */ + kUSB_DeviceCcidEventHardwareErrorSent, /*!< Hardware error notification send completed */ +} usb_device_ccid_event_t; + +/*! @brief The structure is used to get data rates or clock frequencies if the event is + * kUSB_DeviceCcidEventGetClockFrequencies or kUSB_DeviceCcidEventGetDataRate*/ +typedef struct _usb_device_ccid_control_request_struct +{ + uint8_t *buffer; /*!< The buffer address */ + uint32_t length; /*!< The data length */ +} usb_device_ccid_control_request_struct_t; + +/*! @brief The structure is used to keep the transferred buffer and transferred length if the event is + * kUSB_DeviceCcidEventSlotChangeSent or kUSB_DeviceCcidEventHardwareErrorSent*/ +typedef struct _usb_device_ccid_notification_struct +{ + uint8_t *buffer; /*!< The transferred buffer address */ + uint32_t length; /*!< The transferred data length */ +} usb_device_ccid_notification_struct_t; + +/*! @brief The structure is used to keep the command data and length and get response data and length if the event is + * kUSB_DeviceCcidEventCommandReceived*/ +typedef struct _usb_device_ccid_command_struct +{ + uint8_t *commandBuffer; /*!< The buffer address kept the command from host */ + uint32_t commandLength; /*!< The command length from host */ + uint8_t *responseBuffer; /*!< The response data need to be sent to host */ + uint32_t responseLength; /*!< The response data length */ +} usb_device_ccid_command_struct_t; + +/*! @brief The structure is used to get the slot status if the event is kUSB_DeviceCcidEventGetSlotStatus*/ +typedef struct _usb_device_ccid_slot_status_struct +{ + uint8_t slot; /*!< The slot number need to get */ + uint8_t present; /*!< Is present or not */ + uint8_t clockStatus; /*!< The clock status */ +} usb_device_ccid_slot_status_struct_t; + +/*! @brief Slot status, present or not */ +typedef enum _usb_device_ccid_slot_state +{ + kUSB_DeviceCcidSlotStateNoPresent = 0x00U, /*!< Not present */ + kUSB_DeviceCcidSlotStatePresent = 0x01U /*!< Present */ +} usb_device_ccid_slot_state_t; + +/*! @brief Hardware error status */ +typedef enum _usb_device_ccid_hardware_error +{ + kUSB_DeviceCcidHardwareErrorOverCurrent = 0x01U, /*!< Over current */ +} usb_device_ccid_hardware_error_t; + +/*! @brief The CCID device class status structure */ +typedef struct _usb_device_ccid_struct +{ + usb_device_handle handle; /*!< The device handle */ + usb_device_class_config_struct_t *configStruct; /*!< The configuration of the class. */ + usb_device_interface_struct_t *interfaceHandle; /*!< Current interface handle */ + usb_device_ccid_transfer_struct_t *transferHead; /*!< Transfer queue for busy*/ + usb_device_ccid_transfer_struct_t *transferFree; /*!< Transfer queue for idle*/ + uint8_t commandBuffer[USB_DEVICE_CCID_BUFFER_4BYTE_ALIGN( + USB_DEVICE_CONFIG_CCID_MAX_MESSAGE_LENGTH)]; /*!< Command buffer for getting command data from host */ + usb_device_ccid_transfer_struct_t transfers[USB_DEVICE_CONFIG_CCID_TRANSFER_COUNT]; /*!< Transfer entity */ + uint8_t slotsChangeBuffer[(USB_DEVICE_CONFIG_CCID_SLOT_MAX * 2 - 1U) / 8 + 1U + + 1U]; /*!< The buffer for saving slot status */ + uint8_t slotsSendingChangeBuffer[(USB_DEVICE_CONFIG_CCID_SLOT_MAX * 2 - 1U) / 8 + 1U + + 1U]; /*!< The buffer is used to notify host the slot status changed */ + uint8_t slotsSequenceNumber[USB_DEVICE_CONFIG_CCID_SLOT_MAX]; /*!< Save each slot sequence number */ + usb_device_ccid_hardware_error_notification_t + hardwareError; /*!< The buffer is used to notify host the hardware error happened */ + uint8_t configuration; /*!< Current configuration */ + uint8_t interfaceNumber; /*!< The interface number of the class */ + uint8_t alternate; /*!< Current alternate setting of the interface */ + uint8_t endpointInterruptIn; /*!< The endpoint number of the interrupt IN pipe */ + uint8_t endpointBulkIn; /*!< The endpoint number of the bulk IN pipe */ + uint8_t endpointBulkOut; /*!< The endpoint number of the bulk OUT pipe */ + uint8_t slots; /*!< The slot number of the application */ + uint8_t bulkInBusy; /*!< The bulk IN pipe is busy or not. */ + uint8_t interruptInBusy; /*!< The interrupt IN pipe is busy or not. */ + uint8_t slotsChanged; /*!< The slot status changed */ +} usb_device_ccid_struct_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initialize the CCID class. + * + * This function is used to initialize the CCID class. This function only can be called by #USB_DeviceClassInit. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t. + * @param[in] config The class configuration information. + * @param[out] handle An out parameter used to return pointer of the video class handle to the caller. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DeviceCcidInit(uint8_t controllerId, + usb_device_class_config_struct_t *config, + class_handle_t *handle); + +/*! + * @brief Deinitializes the device CCID class. + * + * The function deinitializes the device CCID class. This function can only be called by #USB_DeviceClassDeinit. + * + * @param[in] handle The CCID class handle received from usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DeviceCcidDeinit(class_handle_t handle); + +/*! + * @brief Handles the event passed to the CCID class. + * + * This function handles the event passed to the CCID class. This function can only be called by #USB_DeviceClassEvent. + * + * @param[in] handle The CCID class handle, received from the usb_device_class_config_struct_t::classHandle. + * @param[in] event The event codes. See the enumeration #usb_device_class_event_t. + * @param[in,out] param The parameter type is determined by the event code. + * + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The device handle not be found. + * @retval kStatus_USB_InvalidRequest The request is invalid and the control pipe is stalled by the caller. + */ +extern usb_status_t USB_DeviceCcidEvent(void *handle, uint32_t event, void *param); + +/*! + * @name USB device CCID class APIs + * @{ + */ + +/*! + * @brief Notifies the slot status changed. + * + * The function is used to notify that the slot status changed. This is a non-blocking function. The event + * kUSB_DeviceCcidEventSlotChangeSent + * is asserted when the transfer completed. + * + * The slot status may not be sent to the host if the interrupt IN pipe is busy. The status is saved internally + * and sent to the host when the interrupt IN pipe callback called. So, the event + * kUSB_DeviceCcidEventSlotChangeSent + * happened times does not equal to the function call times of this function. + * + * @param[in] handle The CCID class handle received from usb_device_class_config_struct_t::classHandle. + * @param[in] slot The changed slot number. + * @param[in] state The changed slot status. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DeviceCcidNotifySlotChange(class_handle_t handle, + uint8_t slot, + usb_device_ccid_slot_state_t state); + +/*! + * @brief Notifies the slot status changed. + * + * The function is used to notify the hardware error. This is a non-blocking function. The event + * kUSB_DeviceCcidEventHardwareErrorSent + * is asserted when the transfer completed. + * + * If the interrupt IN pipe is busy, the function returns an error kStatus_USB_Error. + * + * @param[in] handle The CCID class handle received from usb_device_class_config_struct_t::classHandle. + * @param[in] slot The changed slot number. + * @param[in] errorCode The hardware error code. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DeviceCcidNotifyHardwareError(class_handle_t handle, + uint8_t slot, + usb_device_ccid_hardware_error_t errorCode); + +/*! @}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __USB_DEVICE_CCID_H__ */ diff --git a/usb/device/class/usb_device_cdc_acm.c b/usb/device/class/usb_device_cdc_acm.c new file mode 100644 index 0000000..6436a91 --- /dev/null +++ b/usb/device/class/usb_device_cdc_acm.c @@ -0,0 +1,846 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_device_registers.h" + +#include +#include + +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device.h" + +#include "usb_device_class.h" + +#if USB_DEVICE_CONFIG_CDC_ACM +#include "usb_device_cdc_acm.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define USB_CDC_ACM_ENTER_CRITICAL() \ + USB_OSA_SR_ALLOC(); \ + USB_OSA_ENTER_CRITICAL() + +#define USB_CDC_ACM_EXIT_CRITICAL() USB_OSA_EXIT_CRITICAL() + +/******************************************************************************* +* Variables +******************************************************************************/ +/* CDC ACM device instance */ + +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) + usb_device_cdc_acm_struct_t g_cdcAcmHandle[USB_DEVICE_CONFIG_CDC_ACM]; + +/******************************************************************************* +* Code +******************************************************************************/ + +/*! + * @brief Allocates the CDC ACM device handle. + * + * This function allocates the CDC ACM device handle. + * + * @param handle The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceCdcAcmAllocateHandle(usb_device_cdc_acm_struct_t **handle) +{ + int32_t count; + for (count = 0; count < USB_DEVICE_CONFIG_CDC_ACM; count++) + { + if (NULL == g_cdcAcmHandle[count].handle) + { + *handle = &g_cdcAcmHandle[count]; + return kStatus_USB_Success; + } + } + + return kStatus_USB_Busy; +} + +/*! + * @brief Frees the CDC ACM device handle. + * + * This function frees the CDC ACM device handle. + * + * @param handle The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceCdcAcmFreeHandle(usb_device_cdc_acm_struct_t *handle) +{ + handle->handle = NULL; + handle->configStruct = NULL; + handle->configuration = 0; + handle->alternate = 0; + return kStatus_USB_Success; +} + +/*! + * @brief Responds to the interrupt in endpoint event. + * + * This function responds to the interrupt in endpoint event. + * + * @param handle The device handle of the CDC ACM device. + * @param message The pointer to the message of the endpoint callback. + * @param callbackParam The pointer to the parameter of the callback. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcAcmInterruptIn(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_cdc_acm_struct_t *cdcAcmHandle; + usb_status_t error = kStatus_USB_Error; + cdcAcmHandle = (usb_device_cdc_acm_struct_t *)callbackParam; + if (!cdcAcmHandle) + { + return kStatus_USB_InvalidHandle; + } + + cdcAcmHandle->interruptIn.isBusy = 0; + + if ((NULL != cdcAcmHandle->configStruct) && (cdcAcmHandle->configStruct->classCallback)) + { + /*classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle, + kUSB_DeviceCdcEventSerialStateNotif, message); + } + return error; +} + +/*! + * @brief Responds to the bulk in endpoint event. + * + * This function responds to the bulk in endpoint event. + * + * @param handle The device handle of the CDC ACM device. + * @param message The pointer to the message of the endpoint callback. + * @param callbackParam The pointer to the parameter of the callback. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcAcmBulkIn(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_cdc_acm_struct_t *cdcAcmHandle; + usb_status_t error = kStatus_USB_Error; + cdcAcmHandle = (usb_device_cdc_acm_struct_t *)callbackParam; + + if (!cdcAcmHandle) + { + return kStatus_USB_InvalidHandle; + } + + cdcAcmHandle->bulkIn.isBusy = 0; + + if ((NULL != cdcAcmHandle->configStruct) && (cdcAcmHandle->configStruct->classCallback)) + { + /*classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventSendResponse, + message); + } + return error; +} + +/*! + * @brief Responds to the bulk out endpoint event. + * + * This function responds to the bulk out endpoint event. + * + * @param handle The device handle of the CDC ACM device. + * @param message The pointer to the message of the endpoint callback. + * @param callbackParam The pointer to the parameter of the callback. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcAcmBulkOut(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_cdc_acm_struct_t *cdcAcmHandle; + usb_status_t error = kStatus_USB_Error; + cdcAcmHandle = (usb_device_cdc_acm_struct_t *)callbackParam; + + if (!cdcAcmHandle) + { + return kStatus_USB_InvalidHandle; + } + + cdcAcmHandle->bulkOut.isBusy = 0; + + if ((NULL != cdcAcmHandle->configStruct) && (cdcAcmHandle->configStruct->classCallback)) + { + /*classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventRecvResponse, + message); + } + return error; +} + +/*! + * @brief Initializes the endpoints in CDC ACM class. + * + * This function initializes the endpoints in CDC ACM class. + * + * @param cdcAcmHandle The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcAcmEndpointsInit(usb_device_cdc_acm_struct_t *cdcAcmHandle) +{ + usb_device_interface_list_t *interfaceList; + usb_device_interface_struct_t *interface = NULL; + usb_status_t error = kStatus_USB_Error; + + if (!cdcAcmHandle) + { + return error; + } + + /* return error when configuration is invalid (0 or more than the configuration number) */ + if ((cdcAcmHandle->configuration == 0U) || + (cdcAcmHandle->configuration > cdcAcmHandle->configStruct->classInfomation->configurations)) + { + return error; + } + + interfaceList = &cdcAcmHandle->configStruct->classInfomation->interfaceList[cdcAcmHandle->configuration - 1]; + + for (int count = 0; count < interfaceList->count; count++) + { + if (USB_DEVICE_CONFIG_CDC_COMM_CLASS_CODE == interfaceList->interfaces[count].classCode) + { + for (int index = 0; index < interfaceList->interfaces[count].count; index++) + { + if (interfaceList->interfaces[count].interface[index].alternateSetting == cdcAcmHandle->alternate) + { + interface = &interfaceList->interfaces[count].interface[index]; + break; + } + } + cdcAcmHandle->interfaceNumber = interfaceList->interfaces[count].interfaceNumber; + break; + } + } + if (!interface) + { + return error; + } + cdcAcmHandle->commInterfaceHandle = interface; + for (int count = 0; count < interface->endpointList.count; count++) + { + usb_device_endpoint_init_struct_t epInitStruct; + usb_device_endpoint_callback_struct_t epCallback; + epInitStruct.zlt = 0; + epInitStruct.interval = interface->endpointList.endpoint[count].interval; + epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress; + epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize; + epInitStruct.transferType = interface->endpointList.endpoint[count].transferType; + + if ((USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) && + (USB_ENDPOINT_INTERRUPT == epInitStruct.transferType)) + { + cdcAcmHandle->interruptIn.ep = (epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK); + cdcAcmHandle->interruptIn.isBusy = 0; + cdcAcmHandle->interruptIn.pipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + cdcAcmHandle->interruptIn.pipeStall = 0U; + cdcAcmHandle->interruptIn.pipeDataLen = 0U; + epCallback.callbackFn = USB_DeviceCdcAcmInterruptIn; + } + + epCallback.callbackParam = cdcAcmHandle; + + error = USB_DeviceInitEndpoint(cdcAcmHandle->handle, &epInitStruct, &epCallback); + } + + for (int count = 0; count < interfaceList->count; count++) + { + if (USB_DEVICE_CONFIG_CDC_DATA_CLASS_CODE == interfaceList->interfaces[count].classCode) + { + for (int index = 0; index < interfaceList->interfaces[count].count; index++) + { + if (interfaceList->interfaces[count].interface[index].alternateSetting == cdcAcmHandle->alternate) + { + interface = &interfaceList->interfaces[count].interface[index]; + break; + } + } + break; + } + } + + cdcAcmHandle->dataInterfaceHandle = interface; + + for (int count = 0; count < interface->endpointList.count; count++) + { + usb_device_endpoint_init_struct_t epInitStruct; + usb_device_endpoint_callback_struct_t epCallback; + epInitStruct.zlt = 0; + epInitStruct.interval = interface->endpointList.endpoint[count].interval; + epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress; + epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize; + epInitStruct.transferType = interface->endpointList.endpoint[count].transferType; + + if ((USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) && + (USB_ENDPOINT_BULK == epInitStruct.transferType)) + { + cdcAcmHandle->bulkIn.ep = (epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK); + cdcAcmHandle->bulkIn.isBusy = 0; + cdcAcmHandle->bulkIn.pipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + cdcAcmHandle->bulkIn.pipeStall = 0U; + cdcAcmHandle->bulkIn.pipeDataLen = 0U; + epCallback.callbackFn = USB_DeviceCdcAcmBulkIn; + } + else if ((USB_OUT == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) && + (USB_ENDPOINT_BULK == epInitStruct.transferType)) + { + cdcAcmHandle->bulkOut.ep = (epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK); + cdcAcmHandle->bulkOut.isBusy = 0; + cdcAcmHandle->bulkOut.pipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + cdcAcmHandle->bulkOut.pipeStall = 0U; + cdcAcmHandle->bulkOut.pipeDataLen = 0U; + epCallback.callbackFn = USB_DeviceCdcAcmBulkOut; + } + else + { + } + epCallback.callbackParam = cdcAcmHandle; + + error = USB_DeviceInitEndpoint(cdcAcmHandle->handle, &epInitStruct, &epCallback); + } + return error; +} + +/*! + * @brief De-initializes the endpoints in CDC ACM class. + * + * This function de-initializes the endpoints in CDC ACM class. + * + * @param cdcAcmHandle The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcAcmEndpointsDeinit(usb_device_cdc_acm_struct_t *cdcAcmHandle) +{ + usb_status_t error = kStatus_USB_Error; + + if ((!cdcAcmHandle->commInterfaceHandle) || (!cdcAcmHandle->dataInterfaceHandle)) + { + return error; + } + for (int count = 0; count < cdcAcmHandle->commInterfaceHandle->endpointList.count; count++) + { + error = USB_DeviceDeinitEndpoint( + cdcAcmHandle->handle, cdcAcmHandle->commInterfaceHandle->endpointList.endpoint[count].endpointAddress); + } + for (int count = 0; count < cdcAcmHandle->dataInterfaceHandle->endpointList.count; count++) + { + error = USB_DeviceDeinitEndpoint( + cdcAcmHandle->handle, cdcAcmHandle->dataInterfaceHandle->endpointList.endpoint[count].endpointAddress); + } + cdcAcmHandle->commInterfaceHandle = NULL; + cdcAcmHandle->dataInterfaceHandle = NULL; + + return error; +} + +/*! +* @brief Handles the CDC ACM class event. +* +* This function responses to various events including the common device events and the class specific events. +* For class specific events, it calls the class callback defined in the application to deal with the class specific +* event. +* +* @param handle The class handle of the CDC ACM class. +* @param event The event type. +* @param param The class handle of the CDC ACM class. +* @return A USB error code or kStatus_USB_Success. +*/ +usb_status_t USB_DeviceCdcAcmEvent(void *handle, uint32_t event, void *param) +{ + usb_device_cdc_acm_struct_t *cdcAcmHandle; + usb_device_cdc_acm_request_param_struct_t reqParam; + usb_status_t error = kStatus_USB_Error; + uint16_t interfaceAlternate; + uint8_t *temp8; + uint8_t alternate; + + if ((!param) || (!handle)) + { + return kStatus_USB_InvalidHandle; + } + + cdcAcmHandle = (usb_device_cdc_acm_struct_t *)handle; + + switch (event) + { + case kUSB_DeviceClassEventDeviceReset: + /* Bus reset, clear the configuration. */ + cdcAcmHandle->configuration = 0; + break; + case kUSB_DeviceClassEventSetConfiguration: + temp8 = ((uint8_t *)param); + if (!cdcAcmHandle->configStruct) + { + break; + } + if (*temp8 == cdcAcmHandle->configuration) + { + break; + } + + error = USB_DeviceCdcAcmEndpointsDeinit(cdcAcmHandle); + cdcAcmHandle->configuration = *temp8; + cdcAcmHandle->alternate = 0; + error = USB_DeviceCdcAcmEndpointsInit(cdcAcmHandle); + if (kStatus_USB_Success != error) + { + usb_echo("kUSB_DeviceClassEventSetConfiguration, USB_DeviceInitEndpoint fail\r\n"); + } + break; + case kUSB_DeviceClassEventSetInterface: + if (!cdcAcmHandle->configStruct) + { + break; + } + + interfaceAlternate = *((uint16_t *)param); + alternate = (uint8_t)(interfaceAlternate & 0xFFU); + + if (cdcAcmHandle->interfaceNumber != ((uint8_t)(interfaceAlternate >> 8U))) + { + break; + } + if (alternate == cdcAcmHandle->alternate) + { + break; + } + error = USB_DeviceCdcAcmEndpointsDeinit(cdcAcmHandle); + cdcAcmHandle->alternate = alternate; + error = USB_DeviceCdcAcmEndpointsInit(cdcAcmHandle); + if (kStatus_USB_Success != error) + { + usb_echo("kUSB_DeviceClassEventSetInterface, USB_DeviceInitEndpoint fail\r\n"); + } + break; + case kUSB_DeviceClassEventSetEndpointHalt: + if ((!cdcAcmHandle->configStruct) || (!cdcAcmHandle->commInterfaceHandle) || + (!cdcAcmHandle->dataInterfaceHandle)) + { + break; + } + temp8 = ((uint8_t *)param); + for (int count = 0; count < cdcAcmHandle->commInterfaceHandle->endpointList.count; count++) + { + if (*temp8 == cdcAcmHandle->commInterfaceHandle->endpointList.endpoint[count].endpointAddress) + { + cdcAcmHandle->interruptIn.pipeStall = 1U; + error = USB_DeviceStallEndpoint(cdcAcmHandle->handle, *temp8); + } + } + for (int count = 0; count < cdcAcmHandle->dataInterfaceHandle->endpointList.count; count++) + { + if (*temp8 == cdcAcmHandle->dataInterfaceHandle->endpointList.endpoint[count].endpointAddress) + { + if (USB_IN == (((*temp8) & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) + { + cdcAcmHandle->bulkIn.pipeStall = 1U; + } + else + { + cdcAcmHandle->bulkOut.pipeStall = 1U; + } + error = USB_DeviceStallEndpoint(cdcAcmHandle->handle, *temp8); + } + } + break; + case kUSB_DeviceClassEventClearEndpointHalt: + if ((!cdcAcmHandle->configStruct) || (!cdcAcmHandle->commInterfaceHandle) || + (!cdcAcmHandle->dataInterfaceHandle)) + { + break; + } + temp8 = ((uint8_t *)param); + for (int count = 0; count < cdcAcmHandle->commInterfaceHandle->endpointList.count; count++) + { + if (*temp8 == cdcAcmHandle->commInterfaceHandle->endpointList.endpoint[count].endpointAddress) + { + error = USB_DeviceUnstallEndpoint(cdcAcmHandle->handle, *temp8); + if (USB_IN == (((*temp8) & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) + { + if (cdcAcmHandle->interruptIn.pipeStall) + { + cdcAcmHandle->interruptIn.pipeStall = 0U; + if ((uint8_t*)USB_UNINITIALIZED_VAL_32 != cdcAcmHandle->interruptIn.pipeDataBuffer) + { + error = USB_DeviceSendRequest(cdcAcmHandle->handle, (cdcAcmHandle->interruptIn.ep), + cdcAcmHandle->interruptIn.pipeDataBuffer, cdcAcmHandle->interruptIn.pipeDataLen); + if (kStatus_USB_Success != error) + { + usb_device_endpoint_callback_message_struct_t endpointCallbackMessage; + endpointCallbackMessage.buffer = cdcAcmHandle->interruptIn.pipeDataBuffer; + endpointCallbackMessage.length = cdcAcmHandle->interruptIn.pipeDataLen; + endpointCallbackMessage.isSetup = 0U; + USB_DeviceCdcAcmBulkIn(cdcAcmHandle->handle,(void*)&endpointCallbackMessage, handle); + } + cdcAcmHandle->interruptIn.pipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + cdcAcmHandle->interruptIn.pipeDataLen = 0U; + } + } + } + + } + } + for (int count = 0; count < cdcAcmHandle->dataInterfaceHandle->endpointList.count; count++) + { + + if (*temp8 == cdcAcmHandle->dataInterfaceHandle->endpointList.endpoint[count].endpointAddress) + { + error = USB_DeviceUnstallEndpoint(cdcAcmHandle->handle, *temp8); + if (USB_IN == (((*temp8) & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) + { + if (cdcAcmHandle->bulkIn.pipeStall) + { + cdcAcmHandle->bulkIn.pipeStall = 0U; + if ((uint8_t*)USB_UNINITIALIZED_VAL_32 != cdcAcmHandle->bulkIn.pipeDataBuffer) + { + error = USB_DeviceSendRequest(cdcAcmHandle->handle, (cdcAcmHandle->bulkIn.ep), + cdcAcmHandle->bulkIn.pipeDataBuffer, cdcAcmHandle->bulkIn.pipeDataLen); + if (kStatus_USB_Success != error) + { + usb_device_endpoint_callback_message_struct_t endpointCallbackMessage; + endpointCallbackMessage.buffer = cdcAcmHandle->bulkIn.pipeDataBuffer; + endpointCallbackMessage.length = cdcAcmHandle->bulkIn.pipeDataLen; + endpointCallbackMessage.isSetup = 0U; + USB_DeviceCdcAcmBulkIn(cdcAcmHandle->handle, (void*)&endpointCallbackMessage, handle); + } + cdcAcmHandle->bulkIn.pipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + cdcAcmHandle->bulkIn.pipeDataLen = 0U; + } + } + } + else + { + if (cdcAcmHandle->bulkOut.pipeStall) + { + cdcAcmHandle->bulkOut.pipeStall = 0U; + if ((uint8_t*)USB_UNINITIALIZED_VAL_32 != cdcAcmHandle->bulkOut.pipeDataBuffer) + { + error = USB_DeviceRecvRequest(cdcAcmHandle->handle, (cdcAcmHandle->bulkOut.ep), + cdcAcmHandle->bulkOut.pipeDataBuffer, cdcAcmHandle->bulkOut.pipeDataLen); + if (kStatus_USB_Success != error) + { + usb_device_endpoint_callback_message_struct_t endpointCallbackMessage; + endpointCallbackMessage.buffer = cdcAcmHandle->bulkOut.pipeDataBuffer; + endpointCallbackMessage.length = cdcAcmHandle->bulkOut.pipeDataLen; + endpointCallbackMessage.isSetup = 0U; + USB_DeviceCdcAcmBulkOut(cdcAcmHandle->handle, (void*)&endpointCallbackMessage, handle); + } + cdcAcmHandle->bulkOut.pipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + cdcAcmHandle->bulkOut.pipeDataLen = 0U; + } + } + } + } + } + break; + case kUSB_DeviceClassEventClassRequest: + if (param) + { + usb_device_control_request_struct_t *controlRequest = (usb_device_control_request_struct_t *)param; + + if ((controlRequest->setup->wIndex & 0xFFU) != cdcAcmHandle->interfaceNumber) + { + break; + } + /* Standard CDC request */ + if (USB_REQUEST_TYPE_TYPE_CLASS == (controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK)) + { + reqParam.buffer = &(controlRequest->buffer); + reqParam.length = &(controlRequest->length); + reqParam.interfaceIndex = controlRequest->setup->wIndex; + reqParam.setupValue = controlRequest->setup->wValue; + reqParam.isSetup = controlRequest->isSetup; + switch (controlRequest->setup->bRequest) + { + case USB_DEVICE_CDC_REQUEST_SEND_ENCAPSULATED_COMMAND: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback( + (class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventSendEncapsulatedCommand, &reqParam); + break; + case USB_DEVICE_CDC_REQUEST_GET_ENCAPSULATED_RESPONSE: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback( + (class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventGetEncapsulatedResponse, &reqParam); + break; + case USB_DEVICE_CDC_REQUEST_SET_COMM_FEATURE: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback( + (class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventSetCommFeature, &reqParam); + break; + case USB_DEVICE_CDC_REQUEST_GET_COMM_FEATURE: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback( + (class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventGetCommFeature, &reqParam); + break; + case USB_DEVICE_CDC_REQUEST_CLEAR_COMM_FEATURE: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback( + (class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventClearCommFeature, &reqParam); + break; + case USB_DEVICE_CDC_REQUEST_GET_LINE_CODING: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback( + (class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventGetLineCoding, &reqParam); + break; + case USB_DEVICE_CDC_REQUEST_SET_LINE_CODING: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback( + (class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventSetLineCoding, &reqParam); + break; + case USB_DEVICE_CDC_REQUEST_SET_CONTROL_LINE_STATE: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback( + (class_handle_t)cdcAcmHandle, kUSB_DeviceCdcEventSetControlLineState, &reqParam); + break; + case USB_DEVICE_CDC_REQUEST_SEND_BREAK: + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = cdcAcmHandle->configStruct->classCallback((class_handle_t)cdcAcmHandle, + kUSB_DeviceCdcEventSendBreak, &reqParam); + break; + default: + error = kStatus_USB_InvalidRequest; + break; + } + } + } + break; + default: + break; + } + return error; +} + +/*! + * @brief Initializes the USB CDC ACM class. + * + * This function obtains a usb device handle according to the controller id, initializes the CDC ACM class + * with the class configure parameters and creates the mutex for each pipe. + * + * @param controllerId The id of the controller. The value can be choosen from kUSB_ControllerKhci0, + * kUSB_ControllerKhci1, kUSB_ControllerEhci0 or kUSB_ControllerEhci1. + * @param config The user configuration structure of type usb_device_class_config_struct_t. The user + * populates the members of this structure and passes the pointer of this structure + * into this function. + * @param handle It is out parameter. The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcAcmInit(uint8_t controllerId, + usb_device_class_config_struct_t *config, + class_handle_t *handle) +{ + usb_device_cdc_acm_struct_t *cdcAcmHandle; + usb_status_t error = kStatus_USB_Error; + + error = USB_DeviceCdcAcmAllocateHandle(&cdcAcmHandle); + + if (kStatus_USB_Success != error) + { + return error; + } + + error = USB_DeviceClassGetDeviceHandle(controllerId, &cdcAcmHandle->handle); + + if (kStatus_USB_Success != error) + { + return error; + } + + if (!cdcAcmHandle->handle) + { + return kStatus_USB_InvalidHandle; + } + cdcAcmHandle->configStruct = config; + cdcAcmHandle->configuration = 0; + cdcAcmHandle->alternate = 0xFF; + + if (kStatus_USB_OSA_Success != USB_OsaMutexCreate(&(cdcAcmHandle->bulkIn.mutex))) + { + usb_echo("mutex create error!"); + } + if (kStatus_USB_OSA_Success != USB_OsaMutexCreate(&(cdcAcmHandle->bulkOut.mutex))) + { + usb_echo("mutex create error!"); + } + if (kStatus_USB_OSA_Success != USB_OsaMutexCreate(&(cdcAcmHandle->interruptIn.mutex))) + { + usb_echo("mutex create error!"); + } + *handle = (class_handle_t)cdcAcmHandle; + return error; +} + +/*! + * @brief De-Initializes the USB CDC ACM class. + * + * This function destroys the mutex for each pipe, deinit each endpoint of the CDC ACM class and free + * the CDC ACM class handle. + * + * @param handle The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcAcmDeinit(class_handle_t handle) +{ + usb_device_cdc_acm_struct_t *cdcAcmHandle; + usb_status_t error = kStatus_USB_Error; + + cdcAcmHandle = (usb_device_cdc_acm_struct_t *)handle; + + if (!cdcAcmHandle) + { + return kStatus_USB_InvalidHandle; + } + if (kStatus_USB_OSA_Success != USB_OsaMutexDestroy((cdcAcmHandle->bulkIn.mutex))) + { + usb_echo("mutex destroy error!"); + } + if (kStatus_USB_OSA_Success != USB_OsaMutexDestroy((cdcAcmHandle->bulkOut.mutex))) + { + usb_echo("mutex destroy error!"); + } + if (kStatus_USB_OSA_Success != USB_OsaMutexDestroy((cdcAcmHandle->interruptIn.mutex))) + { + usb_echo("mutex destroy error!"); + } + error = USB_DeviceCdcAcmEndpointsDeinit(cdcAcmHandle); + USB_DeviceCdcAcmFreeHandle(cdcAcmHandle); + return error; +} + +/*! + * @brief Prime the endpoint to send packet to host. + * + * This function checks whether the endpoint is sending packet, then it primes the endpoint + * with the buffer address and the buffer length if the pipe is not busy. Otherwise, it ignores this transfer by + * returning an error code. + * + * @param handle The class handle of the CDC ACM class. + * @param ep The endpoint number of the transfer. + * @param buffer The pointer to the buffer to be transferred. + * @param length The length of the buffer to be transferred. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcAcmSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length) +{ + usb_device_cdc_acm_struct_t *cdcAcmHandle; + usb_status_t error = kStatus_USB_Error; + usb_device_cdc_acm_pipe_t *cdcAcmPipe = NULL; + + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + cdcAcmHandle = (usb_device_cdc_acm_struct_t *)handle; + + if (cdcAcmHandle->bulkIn.ep == ep) + { + cdcAcmPipe = &(cdcAcmHandle->bulkIn); + } + else if (cdcAcmHandle->interruptIn.ep == ep) + { + cdcAcmPipe = &(cdcAcmHandle->interruptIn); + } + else + { + } + + if (NULL != cdcAcmPipe) + { + if (1U == cdcAcmPipe->isBusy) + { + return kStatus_USB_Busy; + } + cdcAcmPipe->isBusy = 1U; + + if (cdcAcmPipe->pipeStall) + { + cdcAcmPipe->pipeDataBuffer = buffer; + cdcAcmPipe->pipeDataLen = length; + return kStatus_USB_Success; + } + + error = USB_DeviceSendRequest(cdcAcmHandle->handle, ep, buffer, length); + if (kStatus_USB_Success != error) + { + cdcAcmPipe->isBusy = 0U; + } + } + return error; +} + +/*! + * @brief Prime the endpoint to receive packet from host. + * + * This function checks whether the endpoint is receiving packet, then it primes the endpoint + * with the buffer address and the buffer length if the pipe is not busy. Otherwise, it ignores this transfer by + * returning an error code. + * + * @param handle The class handle of the CDC ACM class. + * @param ep The endpoint number of the transfer. + * @param buffer The pointer to the buffer to be transferred. + * @param length The length of the buffer to be transferred. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcAcmRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length) +{ + usb_device_cdc_acm_struct_t *cdcAcmHandle; + usb_status_t error = kStatus_USB_Error; + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + cdcAcmHandle = (usb_device_cdc_acm_struct_t *)handle; + + if (1U == cdcAcmHandle->bulkOut.isBusy) + { + return kStatus_USB_Busy; + } + cdcAcmHandle->bulkOut.isBusy = 1U; + + if (cdcAcmHandle->bulkOut.pipeStall) + { + cdcAcmHandle->bulkOut.pipeDataBuffer = buffer; + cdcAcmHandle->bulkOut.pipeDataLen = length; + return kStatus_USB_Success; + } + + error = USB_DeviceRecvRequest(cdcAcmHandle->handle, ep, buffer, length); + if (kStatus_USB_Success != error) + { + cdcAcmHandle->bulkOut.isBusy = 0U; + } + return error; +} + +#endif /* USB_DEVICE_CONFIG_CDC_ACM */ diff --git a/usb/device/class/usb_device_cdc_acm.h b/usb/device/class/usb_device_cdc_acm.h new file mode 100644 index 0000000..bbfb929 --- /dev/null +++ b/usb/device/class/usb_device_cdc_acm.h @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _USB_DEVICE_CDC_ACM_H_ +#define _USB_DEVICE_CDC_ACM_H_ + +/*! + * @addtogroup cdc_acm + * @{ + */ + +/******************************************************************************* +* Definitions +******************************************************************************/ +#define USB_DEVICE_CONFIG_CDC_ACM_MAX_INSTANCE (1) /*!< The maximum number of CDC device instance. */ +#define USB_DEVICE_CONFIG_CDC_COMM_CLASS_CODE (0x02) /*!< The CDC communication class code. */ +#define USB_DEVICE_CONFIG_CDC_DATA_CLASS_CODE (0x0A) /*!< The CDC data class code. */ + +#define USB_DEVICE_CDC_REQUEST_SEND_ENCAPSULATED_COMMAND \ + (0x00) /*!< The CDC class request code for SEND_ENCAPSULATED_COMMAND. */ +#define USB_DEVICE_CDC_REQUEST_GET_ENCAPSULATED_RESPONSE \ + (0x01) /*!< The CDC class request code for GET_ENCAPSULATED_RESPONSE. */ +#define USB_DEVICE_CDC_REQUEST_SET_COMM_FEATURE (0x02) /*!< The CDC class request code for SET_COMM_FEATURE. */ +#define USB_DEVICE_CDC_REQUEST_GET_COMM_FEATURE (0x03) /*!< The CDC class request code for GET_COMM_FEATURE. */ +#define USB_DEVICE_CDC_REQUEST_CLEAR_COMM_FEATURE (0x04) /*!< The CDC class request code for CLEAR_COMM_FEATURE. */ +#define USB_DEVICE_CDC_REQUEST_SET_AUX_LINE_STATE (0x10) /*!< The CDC class request code for SET_AUX_LINE_STATE. */ +#define USB_DEVICE_CDC_REQUEST_SET_HOOK_STATE (0x11) /*!< The CDC class request code for SET_HOOK_STATE. */ +#define USB_DEVICE_CDC_REQUEST_PULSE_SETUP (0x12) /*!< The CDC class request code for PULSE_SETUP. */ +#define USB_DEVICE_CDC_REQUEST_SEND_PULSE (0x13) /*!< The CDC class request code for SEND_PULSE. */ +#define USB_DEVICE_CDC_REQUEST_SET_PULSE_TIME (0x14) /*!< The CDC class request code for SET_PULSE_TIME. */ +#define USB_DEVICE_CDC_REQUEST_RING_AUX_JACK (0x15) /*!< The CDC class request code for RING_AUX_JACK. */ +#define USB_DEVICE_CDC_REQUEST_SET_LINE_CODING (0x20) /*!< The CDC class request code for SET_LINE_CODING. */ +#define USB_DEVICE_CDC_REQUEST_GET_LINE_CODING (0x21) /*!< The CDC class request code for GET_LINE_CODING. */ +#define USB_DEVICE_CDC_REQUEST_SET_CONTROL_LINE_STATE \ + (0x22) /*!< The CDC class request code for SET_CONTROL_LINE_STATE. */ +#define USB_DEVICE_CDC_REQUEST_SEND_BREAK (0x23) /*!< The CDC class request code for SEND_BREAK. */ +#define USB_DEVICE_CDC_REQUEST_SET_RINGER_PARAMS (0x30) /*!< The CDC class request code for SET_RINGER_PARAMS. */ +#define USB_DEVICE_CDC_REQUEST_GET_RINGER_PARAMS (0x31) /*!< The CDC class request code for GET_RINGER_PARAMS. */ +#define USB_DEVICE_CDC_REQUEST_SET_OPERATION_PARAM (0x32) /*!< The CDC class request code for SET_OPERATION_PARAM. */ +#define USB_DEVICE_CDC_REQUEST_GET_OPERATION_PARAM (0x33) /*!< The CDC class request code for GET_OPERATION_PARAM. */ +#define USB_DEVICE_CDC_REQUEST_SET_LINE_PARAMS (0x34) /*!< The CDC class request code for SET_LINE_PARAMS. */ +#define USB_DEVICE_CDC_REQUEST_GET_LINE_PARAMS (0x35) /*!< The CDC class request code for GET_LINE_PARAMS. */ +#define USB_DEVICE_CDC_REQUEST_DIAL_DIGITS (0x36) /*!< The CDC class request code for DIAL_DIGITS. */ +#define USB_DEVICE_CDC_REQUEST_SET_UNIT_PARAMETER (0x37) /*!< The CDC class request code for SET_UNIT_PARAMETER. */ +#define USB_DEVICE_CDC_REQUEST_GET_UNIT_PARAMETER (0x38) /*!< The CDC class request code for GET_UNIT_PARAMETER. */ +#define USB_DEVICE_CDC_REQUEST_CLEAR_UNIT_PARAMETER \ + (0x39) /*!< The CDC class request code for CLEAR_UNIT_PARAMETER. */ +#define USB_DEVICE_CDC_REQUEST_SET_ETHERNET_MULTICAST_FILTERS \ + (0x40) /*!< The CDC class request code for SET_ETHERNET_MULTICAST_FILTERS. */ +#define USB_DEVICE_CDC_REQUEST_SET_ETHERNET_POW_PATTER_FILTER \ + (0x41) /*!< The CDC class request code for SET_ETHERNET_POW_PATTER_FILTER. */ +#define USB_DEVICE_CDC_REQUEST_GET_ETHERNET_POW_PATTER_FILTER \ + (0x42) /*!< The CDC class request code for GET_ETHERNET_POW_PATTER_FILTER. */ +#define USB_DEVICE_CDC_REQUEST_SET_ETHERNET_PACKET_FILTER \ + (0x43) /*!< The CDC class request code for SET_ETHERNET_PACKET_FILTER. */ +#define USB_DEVICE_CDC_REQUEST_GET_ETHERNET_STATISTIC \ + (0x44) /*!< The CDC class request code for GET_ETHERNET_STATISTIC. */ +#define USB_DEVICE_CDC_REQUEST_SET_ATM_DATA_FORMAT (0x50) /*!< The CDC class request code for SET_ATM_DATA_FORMAT. */ +#define USB_DEVICE_CDC_REQUEST_GET_ATM_DEVICE_STATISTICS \ + (0x51) /*!< The CDC class request code for GET_ATM_DEVICE_STATISTICS. */ +#define USB_DEVICE_CDC_REQUEST_SET_ATM_DEFAULT_VC (0x52) /*!< The CDC class request code for SET_ATM_DEFAULT_VC. */ +#define USB_DEVICE_CDC_REQUEST_GET_ATM_VC_STATISTICS \ + (0x53) /*!< The CDC class request code for GET_ATM_VC_STATISTICS. */ +#define USB_DEVICE_CDC_REQUEST_MDLM_SPECIFIC_REQUESTS_MASK \ + (0x7F) /*!< The CDC class request code for MDLM_SPECIFIC_REQUESTS_MASK. */ + +#define USB_DEVICE_CDC_NOTIF_NETWORK_CONNECTION (0x00) /*!< The CDC class notify code for NETWORK_CONNECTION. */ +#define USB_DEVICE_CDC_NOTIF_RESPONSE_AVAIL (0x01) /*!< The CDC class notify code for RESPONSE_AVAIL. */ +#define USB_DEVICE_CDC_NOTIF_AUX_JACK_HOOK_STATE (0x08) /*!< The CDC class notify code for AUX_JACK_HOOK_STATE. */ +#define USB_DEVICE_CDC_NOTIF_RING_DETECT (0x09) /*!< The CDC class notify code for RING_DETECT. */ +#define USB_DEVICE_CDC_NOTIF_SERIAL_STATE (0x20) /*!< The CDC class notify code for SERIAL_STATE. */ +#define USB_DEVICE_CDC_NOTIF_CALL_STATE_CHANGE (0x28) /*!< The CDC class notify code for CALL_STATE_CHANGE. */ +#define USB_DEVICE_CDC_NOTIF_LINE_STATE_CHANGE (0x29) /*!< The CDC class notify code for LINE_STATE_CHANGE. */ +#define USB_DEVICE_CDC_NOTIF_CONNECTION_SPEED_CHANGE \ + (0x2A) /*!< The CDC class notify code for CONNECTION_SPEED_CHANGE. */ + +#define USB_DEVICE_CDC_FEATURE_ABSTRACT_STATE (0x01) /*!< The CDC class feature select code for ABSTRACT_STATE. */ +#define USB_DEVICE_CDC_FEATURE_COUNTRY_SETTING (0x02) /*!< The CDC class feature select code for COUNTRY_SETTING. */ + +#define USB_DEVICE_CDC_CONTROL_SIG_BITMAP_CARRIER_ACTIVATION \ + (0x02) /*!< The CDC class control signal bitmap value for CARRIER_ACTIVATION. */ +#define USB_DEVICE_CDC_CONTROL_SIG_BITMAP_DTE_PRESENCE \ + (0x01) /*!< The CDC class control signal bitmap value for DTE_PRESENCE. */ +#define USB_DEVICE_CDC_UART_STATE_RX_CARRIER (0x01) /*!< The UART state bitmap value of RX_CARRIER. */ +#define USB_DEVICE_CDC_UART_STATE_TX_CARRIER (0x02) /*!< The UART state bitmap value of TX_CARRIER. */ +#define USB_DEVICE_CDC_UART_STATE_BREAK (0x04) /*!< The UART state bitmap value of BREAK. */ +#define USB_DEVICE_CDC_UART_STATE_RING_SIGNAL (0x08) /*!< The UART state bitmap value of RING_SIGNAL. */ +#define USB_DEVICE_CDC_UART_STATE_FRAMING (0x10) /*!< The UART state bitmap value of FRAMING. */ +#define USB_DEVICE_CDC_UART_STATE_PARITY (0x20) /*!< The UART state bitmap value of PARITY. */ +#define USB_DEVICE_CDC_UART_STATE_OVERRUN (0x40) /*!< The UART state bitmap value of OVERRUN. */ + +/*! @brief Definition of CDC class event. */ +typedef enum _usb_device_cdc_acm_event +{ + kUSB_DeviceCdcEventSendResponse = 0x01, /*!< This event indicates the bulk send transfer is complete or cancelled etc. */ + kUSB_DeviceCdcEventRecvResponse, /*!< This event indicates the bulk receive transfer is complete or cancelled etc.. */ + kUSB_DeviceCdcEventSerialStateNotif, /*!< This event indicates the serial state has been sent to the host. */ + kUSB_DeviceCdcEventSendEncapsulatedCommand, /*!< This event indicates the device received the + SEND_ENCAPSULATED_COMMAND request. */ + kUSB_DeviceCdcEventGetEncapsulatedResponse, /*!< This event indicates the device received the + GET_ENCAPSULATED_RESPONSE request. */ + kUSB_DeviceCdcEventSetCommFeature, /*!< This event indicates the device received the SET_COMM_FEATURE request. */ + kUSB_DeviceCdcEventGetCommFeature, /*!< This event indicates the device received the GET_COMM_FEATURE request. */ + kUSB_DeviceCdcEventClearCommFeature, /*!< This event indicates the device received the CLEAR_COMM_FEATURE request. + */ + kUSB_DeviceCdcEventGetLineCoding, /*!< This event indicates the device received the GET_LINE_CODING request. */ + kUSB_DeviceCdcEventSetLineCoding, /*!< This event indicates the device received the SET_LINE_CODING request. */ + kUSB_DeviceCdcEventSetControlLineState, /*!< This event indicates the device received the SET_CONTRL_LINE_STATE + request. */ + kUSB_DeviceCdcEventSendBreak /*!< This event indicates the device received the SEND_BREAK request. */ +} usb_device_cdc_acm_event_t; + +/*! @brief Definition of parameters for CDC ACM request. */ +typedef struct _usb_device_cdc_acm_request_param_struct +{ + uint8_t **buffer; /*!< The pointer to the address of the buffer for CDC class request. */ + uint32_t *length; /*!< The pointer to the length of the buffer for CDC class request. */ + uint16_t interfaceIndex; /*!< The interface index of the setup packet. */ + uint16_t setupValue; /*!< The wValue field of the setup packet. */ + uint8_t isSetup; /*!< The flag indicates if it is a setup packet, 1: yes, 0: no. */ +} usb_device_cdc_acm_request_param_struct_t; + +/*! @brief Definition of pipe structure. */ +typedef struct _usb_device_cdc_acm_pipe +{ + usb_osa_mutex_handle mutex; /*!< The mutex of the pipe. */ + uint8_t *pipeDataBuffer; /*!< pipe data buffer backup when stall */ + uint32_t pipeDataLen; /*!< pipe data length backup when stall */ + uint8_t pipeStall; /*!< pipe is stall */ + uint8_t ep; /*!< The endpoint number of the pipe. */ + uint8_t isBusy; /*!< 1: The pipe is transferring packet, 0: The pipe is idle. */ +} usb_device_cdc_acm_pipe_t; + +/*! @brief Definition of structure for CDC ACM device. */ +typedef struct _usb_device_cdc_acm_struct +{ + usb_device_handle handle; /*!< The handle of the USB device. */ + usb_device_class_config_struct_t *configStruct; /*!< The class configure structure. */ + usb_device_interface_struct_t *commInterfaceHandle; /*!< The CDC communication interface handle. */ + usb_device_interface_struct_t *dataInterfaceHandle; /*!< The CDC data interface handle. */ + usb_device_cdc_acm_pipe_t bulkIn; /*!< The bulk in pipe for sending packet to host. */ + usb_device_cdc_acm_pipe_t bulkOut; /*!< The bulk out pipe for receiving packet from host. */ + usb_device_cdc_acm_pipe_t interruptIn; /*!< The interrupt in pipe for notifying the device state to host. */ + uint8_t configuration; /*!< The current configuration value. */ + uint8_t interfaceNumber; /*!< The current interface number. */ + uint8_t alternate; /*!< The alternate setting value of the interface. */ + uint8_t hasSentState; /*!< 1: The device has primed the state in interrupt pipe, 0: Not primed the state. */ +} usb_device_cdc_acm_struct_t; + +/******************************************************************************* +* API +******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name USB CDC ACM Class Driver + * @{ + */ +/*! + * @brief Initializes the USB CDC ACM class. + * + * This function obtains a USB device handle according to the controller ID, initializes the CDC ACM class + * with the class configure parameters and creates the mutex for each pipe. + * + * @param controllerId The ID of the controller. The value can be chosen from the kUSB_ControllerKhci0, + * kUSB_ControllerKhci1, kUSB_ControllerEhci0, or kUSB_ControllerEhci1. + * @param config The user configuration structure of type usb_device_class_config_struct_t. The user + * populates the members of this structure and passes the pointer of this structure + * into this function. + * @param handle It is out parameter. The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success The CDC ACM class is initialized successfully. + * @retval kStatus_USB_Busy No CDC ACM device handle available for allocation. + * @retval kStatus_USB_InvalidHandle The CDC ACM device handle allocation failure. + * @retval kStatus_USB_InvalidParameter The USB device handle allocation failure. + */ +extern usb_status_t USB_DeviceCdcAcmInit(uint8_t controllerId, + usb_device_class_config_struct_t *config, + class_handle_t *handle); +/*! + * @brief Deinitializes the USB CDC ACM class. + * + * This function destroys the mutex for each pipe, deinitializes each endpoint of the CDC ACM class and frees + * the CDC ACM class handle. + * + * @param handle The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success The CDC ACM class is de-initialized successfully. + * @retval kStatus_USB_Error The endpoint deinitialization failure. + * @retval kStatus_USB_InvalidHandle The CDC ACM device handle or the CDC ACM class handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number of the CDC ACM class handle is invalid. + */ +extern usb_status_t USB_DeviceCdcAcmDeinit(class_handle_t handle); +/*! + * @brief Handles the CDC ACM class event. + * + * This function responds to various events including the common device events and the class-specific events. + * For class-specific events, it calls the class callback defined in the application to deal with the class-specific + * event. + * + * @param handle The class handle of the CDC ACM class. + * @param event The event type. + * @param param The class handle of the CDC ACM class. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success The CDC ACM class is de-initialized successfully. + * @retval kStatus_USB_Error The configure structure of the CDC ACM class handle is invalid. + * @retval kStatus_USB_InvalidHandle The CDC ACM device handle or the CDC ACM class handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number of the CDC ACM class handle is invalid. + * @retval Others The error code returned by class callback in application. + */ +extern usb_status_t USB_DeviceCdcAcmEvent(void *handle, uint32_t event, void *param); + +/*! + * @brief Primes the endpoint to send packet to host. + * + * This function checks whether the endpoint is sending packet, then it primes the endpoint + * with the buffer address and the buffer length if the pipe is not busy. Otherwise, it ignores this transfer by + * returning an error code. + * + * @param handle The class handle of the CDC ACM class. + * @param ep The endpoint number of the transfer. + * @param buffer The pointer to the buffer to be transferred. + * @param length The length of the buffer to be transferred. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Prime to send packet successfully. + * @retval kStatus_USB_Busy The endpoint is busy in transferring. + * @retval kStatus_USB_InvalidHandle The CDC ACM device handle or the CDC ACM class handle is invalid. + * @retval kStatus_USB_ControllerNotFound The controller interface is invalid. + * + * @note The function can only be called in the same context. + */ +extern usb_status_t USB_DeviceCdcAcmSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length); +/*! + * @brief Primes the endpoint to receive packet from host. + * + * This function checks whether the endpoint is receiving packet, then it primes the endpoint + * with the buffer address and the buffer length if the pipe is not busy. Otherwise, it ignores this transfer by + * returning an error code. + * + * @param handle The class handle of the CDC ACM class. + * @param ep The endpoint number of the transfer. + * @param buffer The pointer to the buffer to be transferred. + * @param length The length of the buffer to be transferred. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Prime to receive packet successfully. + * @retval kStatus_USB_Busy The endpoint is busy in transferring. + * @retval kStatus_USB_InvalidHandle The CDC ACM device handle or the CDC ACM class handle is invalid. + * @retval kStatus_USB_ControllerNotFound The controller interface is invalid. + * + * @note The function can only be called in the same context. + */ +extern usb_status_t USB_DeviceCdcAcmRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length); + +/*! @}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _USB_DEVICE_CDC_ACM_H_ */ diff --git a/usb/device/class/usb_device_cdc_rndis.c b/usb/device/class/usb_device_cdc_rndis.c new file mode 100644 index 0000000..4a3475e --- /dev/null +++ b/usb/device/class/usb_device_cdc_rndis.c @@ -0,0 +1,984 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_device_registers.h" +#include "clock_config.h" +#include "board.h" +//#include "fsl_debug_console.h" + +#include +#include + +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device.h" + +#include "usb_device_class.h" +#include "usb_device_cdc_acm.h" +#if USB_DEVICE_CONFIG_CDC_RNDIS +#include "usb_device_cdc_rndis.h" +/******************************************************************************* + * Definitions + ******************************************************************************/ +#if defined(USB_STACK_BM) +#define USB_CDC_RNDIS_MUTEX_LOCK(_X_) \ + USB_OSA_SR_ALLOC(); \ + USB_OSA_ENTER_CRITICAL() +#define USB_CDC_RNDIS_MUTEX_UNLOCK(_X_) USB_OSA_EXIT_CRITICAL() +#else +#define USB_CDC_RNDIS_MUTEX_LOCK(_X_) USB_OsaMutexLock(_X_) +#define USB_CDC_RNDIS_MUTEX_UNLOCK(_X_) USB_OsaMutexUnlock(_X_) +#endif + +#define NOTIF_PACKET_SIZE (0x08) +#define VENDOR_INFO_SIZE (16) + +/******************************************************************************* +* Prototypes +******************************************************************************/ +usb_status_t USB_DeviceCdcRndisInitializeCommand(usb_device_cdc_rndis_struct_t *handle, + uint8_t **message, + uint32_t *len); +usb_status_t USB_DeviceCdcRndisKeepaliveCommand(usb_device_cdc_rndis_struct_t *handle, + uint8_t **message, + uint32_t *len); +usb_status_t USB_DeviceCdcRndisQueryCommand(usb_device_cdc_rndis_struct_t *handle, uint8_t **message, uint32_t *len); +usb_status_t USB_DeviceCdcRndisSetCommand(usb_device_cdc_rndis_struct_t *handle, uint8_t **message, uint32_t *len); +usb_status_t USB_DeviceCdcRndisIndicateStatusCommand(usb_device_cdc_rndis_struct_t *handle, + uint8_t **message, + uint32_t *len); + +/******************************************************************************* +* Variables +******************************************************************************/ +/* The USB CDC RNDIS device instance. */ +static usb_device_cdc_rndis_struct_t s_cdcRndisHandle[USB_DEVICE_CONFIG_CDC_RNDIS_MAX_INSTANCE]; + +/* The response data for RNDIS notification. */ +USB_DMA_INIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t s_responseAvailableData[NOTIF_PACKET_SIZE] = { + USB_DEVICE_CDC_NOTIF_RESPONSE_AVAIL, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +/* The buffer to store RNDIS request. */ +USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint8_t s_rndisCommand[RNDIS_MAX_EXPECTED_COMMAND_SIZE]; +/* The 4-byte-aligned buffer to store RNDIS response. */ +USB_DMA_NONINIT_DATA_ALIGN(USB_DATA_ALIGN_SIZE) static uint32_t s_responseData[(RNDIS_MAX_EXPECTED_RESPONSE_SIZE + 3) / sizeof(uint32_t)]; + +/* The buffer to store RNDIS device vendor information. */ +static uint8_t s_vendorInfo[VENDOR_INFO_SIZE] = " FSL RNDIS PORT "; + +/* The array of all the OIDs that are supported. */ +static uint32_t s_listSuppOid[RNDIS_NUM_OIDS_SUPPORTED] = {NDIS_OID_GEN_SUPPORTED_LIST, + NDIS_OID_GEN_HARDWARE_STATUS, + NDIS_OID_GEN_MEDIA_SUPPORTED, + NDIS_OID_GEN_MEDIA_IN_USE, + NDIS_OID_GEN_MAXIMUM_FRAME_SIZE, + NDIS_OID_GEN_LINK_SPEED, + NDIS_OID_GEN_TRANSMIT_BLOCK_SIZE, + NDIS_OID_GEN_RECEIVE_BLOCK_SIZE, + NDIS_OID_GEN_VENDOR_ID, + NDIS_OID_GEN_VENDOR_DESCRIPTION, + NDIS_OID_GEN_CURRENT_PACKET_FILTER, + NDIS_OID_GEN_MAXIMUM_TOTAL_SIZE, + NDIS_OID_GEN_MEDIA_CONNECT_STATUS, + NDIS_OID_GEN_XMIT_OK, + NDIS_OID_GEN_RCV_OK, + NDIS_OID_GEN_XMIT_ERROR, + NDIS_OID_GEN_RCV_ERROR, + NDIS_OID_GEN_RCV_NO_BUFFER, + NDIS_OID_802_3_PERMANENT_ADDRESS, + NDIS_OID_802_3_CURRENT_ADDRESS, + NDIS_OID_802_3_MULTICAST_LIST, + NDIS_OID_802_3_MAXIMUM_LIST_SIZE, + NDIS_OID_802_3_RCV_ERROR_ALIGNMENT, + NDIS_OID_802_3_XMIT_ONE_COLLISION, + NDIS_OID_802_3_XMIT_MORE_COLLISIONS}; + +/******************************************************************************* +* Code +******************************************************************************/ + +/*! + * @brief Allocates a handle for USB CDC RNDIS device. + * + * This function allocates a handle for USB CDC RNDIS device. + * + * @param handle The device handle of the CDC RNDIS device. + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceCdcRndisAllocateHandle(usb_device_cdc_rndis_struct_t **handle) +{ + int32_t count; + for (count = 0; count < USB_DEVICE_CONFIG_CDC_RNDIS_MAX_INSTANCE; count++) + { + if (NULL == (void *)s_cdcRndisHandle[count].cdcAcmHandle) + { + *handle = &s_cdcRndisHandle[count]; + return kStatus_USB_Success; + } + } + + return kStatus_USB_Busy; +} + +/*! + * @brief Free the handle for USB CDC RNDIS device. + * + * This function frees the handle for USB CDC RNDIS device. + * + * @param handle The device handle of the CDC RNDIS device. + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceCdcRndisFreeHandle(usb_device_cdc_rndis_struct_t *handle) +{ + handle->cdcAcmHandle = (uint32_t)NULL; + return kStatus_USB_Success; +} + +/*! + * @brief Initializes the USB CDC RNDIS device. + * + * This function initializes the USB CDC RNDIS device. + * + * @param classHandle The class handle of the CDC ACM class. + * @param config The pointer to the configure parameter. + * @param handle The pointer to pointer of the RNDIS device. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcRndisInit(class_handle_t classHandle, + usb_device_cdc_rndis_config_struct_t *config, + usb_device_cdc_rndis_struct_t **handle) +{ + usb_device_cdc_rndis_struct_t *cdcRndisHandle; + usb_status_t error = kStatus_USB_Error; + + error = USB_DeviceCdcRndisAllocateHandle(&cdcRndisHandle); + + if (kStatus_USB_Success != error) + { + return error; + } + + /* Initially RNDIS is in Uninitialized state */ + cdcRndisHandle->cdcAcmHandle = classHandle; + cdcRndisHandle->rndisDeviceState = RNDIS_UNINITIALIZED; + cdcRndisHandle->rndisHwState = NDIS_HARDWARE_STATUS_NOT_READY; + cdcRndisHandle->rndisMediaConnectStatus = NDIS_MEDIA_STATE_UNKNOWN; + cdcRndisHandle->rndisDevMaxTxSize = config->devMaxTxSize; + cdcRndisHandle->rndisCallback = config->rndisCallback; + cdcRndisHandle->rndisCommand = &s_rndisCommand[0]; + cdcRndisHandle->responseData = (uint8_t *)&s_responseData[0]; + if (kStatus_USB_OSA_Success != USB_OsaMutexCreate(&(cdcRndisHandle->statusMutex))) + { + usb_echo("mutex create error!"); + } + *handle = cdcRndisHandle; + return error; +} + +/*! + * @brief De-initializes the USB CDC RNDIS device. + * + * This function de-initializes the USB CDC RNDIS device. + * + * @param handle The pointer the RNDIS device. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcRndisDeinit(usb_device_cdc_rndis_struct_t *handle) +{ + usb_device_cdc_rndis_struct_t *cdcRndisHandle; + usb_status_t error = kStatus_USB_Error; + + cdcRndisHandle = handle; + + if (!cdcRndisHandle) + { + return kStatus_USB_InvalidHandle; + } + if (kStatus_USB_OSA_Success != USB_OsaMutexDestroy(cdcRndisHandle->statusMutex)) + { + usb_echo("mutex destroy error!"); + } + error = USB_DeviceCdcRndisFreeHandle(cdcRndisHandle); + return error; +} + +/*! + * @brief Send notification to host that a response is available. + * + * This function is called to send notification to host that a response is available. + * + * @param handle The pointer the RNDIS device. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcRndisResponseAvailable(usb_device_cdc_rndis_struct_t *handle) +{ + usb_device_cdc_acm_struct_t *cdcAcmHandle; + usb_status_t error = kStatus_USB_Error; + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + cdcAcmHandle = (usb_device_cdc_acm_struct_t *)(handle->cdcAcmHandle); + /* update array for current interface */ + s_responseAvailableData[4] = cdcAcmHandle->interfaceNumber; + + error = USB_DeviceCdcAcmSend((uint32_t)cdcAcmHandle, cdcAcmHandle->interruptIn.ep, s_responseAvailableData, + NOTIF_PACKET_SIZE); + return error; +} + +/*! + * @brief Response to kUSB_DeviceCdcEventSendEncapsulatedCommand. + * + * This function is called in response to kUSB_DeviceCdcEventSendEncapsulatedCommand. + * + * @param handle The pointer the RNDIS device. + * @param message The pointer to the pointer of the message buffer. + * @param len The pointer of the length of the buffer. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcRndisMessageSet(usb_device_cdc_rndis_struct_t *handle, uint8_t **message, uint32_t *len) +{ + uint32_t messageType; + + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + + if (*len > RNDIS_MAX_EXPECTED_COMMAND_SIZE) + { + usb_echo("message length: (%d) exceeds the max: (%d)\n", len, RNDIS_MAX_EXPECTED_COMMAND_SIZE); + return kStatus_USB_Error; + } + + messageType = USB_LONG_TO_LITTLE_ENDIAN(*((uint32_t *)(*message))); + + if (messageType == RNDIS_HALT_MSG) + { + /* No response is send to host on receiving Halt Command */ + USB_DeviceCdcRndisHaltCommand(handle); + } + else + { + USB_DeviceCdcRndisResponseAvailable(handle); + } + + if (messageType == RNDIS_INITIALIZE_MSG) + { + /* Update the NDIS HW status */ + handle->rndisHwState = NDIS_HARDWARE_STATUS_INITIALIZING; + } + + return kStatus_USB_Success; +} + +/*! + * @brief Response to kUSB_DeviceCdcEventGetEncapsulatedResponse. + * + * This function is called in response to kUSB_DeviceCdcEventGetEncapsulatedResponse. + * + * @param handle The pointer the RNDIS device. + * @param message The pointer to the pointer of the message buffer. + * @param len The pointer of the length of the buffer. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcRndisMessageGet(usb_device_cdc_rndis_struct_t *handle, uint8_t **message, uint32_t *len) +{ + uint32_t messageType; + uint32_t controlRequestLen; + + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + controlRequestLen = *len; + *len = 0; + + /* we can avoid one swap operation by using messageType in + PSTN_Rndis_Message_Set instead of messageType, but this gives + cleaner implementation as all manipulations and parsing on command + are done in this function */ + messageType = USB_LONG_TO_LITTLE_ENDIAN(*(uint32_t *)(handle->rndisCommand)); + + switch (messageType) + { + case RNDIS_INITIALIZE_MSG: + /* Preparing for response to RNDIS_INITIALIZE_MSG command + i.e. RNDIS_INITIALIZE_CMPLT data */ + USB_DeviceCdcRndisInitializeCommand(handle, message, len); + break; + case RNDIS_QUERY_MSG: + /* Preparing for response to RNDIS_QUERY_MSG command + i.e. RNDIS_QUERY_CMPLT data */ + /* correct the endianness of OID */ + ((rndis_query_msg_struct_t *)(handle->rndisCommand))->oid = + USB_LONG_TO_LITTLE_ENDIAN(((rndis_query_msg_struct_t *)(handle->rndisCommand))->oid); + USB_DeviceCdcRndisQueryCommand(handle, message, len); + break; + case RNDIS_SET_MSG: + /* Preparing for response to RNDIS_SET_MSG command + i.e. RNDIS_SET_CMPLT data */ + /* Correct the endianness of OID and InformationBufferLength + and InformationBufferOffset*/ + ((rndis_set_msg_struct_t *)(handle->rndisCommand))->oid = + USB_LONG_TO_LITTLE_ENDIAN(((rndis_set_msg_struct_t *)(handle->rndisCommand))->oid); + ((rndis_set_msg_struct_t *)(handle->rndisCommand))->informationBufferLength = + USB_LONG_TO_LITTLE_ENDIAN(((rndis_set_msg_struct_t *)(handle->rndisCommand))->informationBufferLength); + ((rndis_set_msg_struct_t *)(handle->rndisCommand))->informationBufferOffset = + USB_LONG_TO_LITTLE_ENDIAN(((rndis_set_msg_struct_t *)(handle->rndisCommand))->informationBufferOffset); + USB_DeviceCdcRndisSetCommand(handle, message, len); + break; + case RNDIS_RESET_MSG: + /* Preparing for response to RNDIS_RESET_MSG command + i.e. RNDIS_RESET_CMPLT data */ + USB_DeviceCdcRndisResetCommand(handle, message, len); + break; + case RNDIS_INDICATE_STATUS_MSG: + /* Preparing for response to RNDIS_INDICATE_STATUS_MSG + command */ + USB_DeviceCdcRndisIndicateStatusCommand(handle, message, len); + break; + case RNDIS_KEEPALIVE_MSG: + /* Preparing for response to RNDIS_KEEPALIVE_MSG command + i.e. RNDIS_KEEPALIVE_CMPLT data */ + USB_DeviceCdcRndisKeepaliveCommand(handle, message, len); + break; + default: + usb_echo("UNSUPPORTED RNDIS Command : 0x%x\n", messageType); + return kStatus_USB_InvalidRequest; + } + + if (*len > RNDIS_MAX_EXPECTED_RESPONSE_SIZE) + { + usb_echo("MAX_EXPECTED_RESPONSE_SIZE insufficient\n"); + } + + if (controlRequestLen < *len) + { + usb_echo("Error : Device has more data to send than Host needs.\n"); + return kStatus_USB_InvalidRequest; + } + return kStatus_USB_Success; +} + +/*! + * @brief initialize the RNDIS device and prepare data to be sent to host as RNDIS_INITIALIZE_CMPLT. + * + * This function is called to initialize the RNDIS device and prepare + * data to be sent to host as RNDIS_INITIALIZE_CMPLT. + * + * @param handle The pointer the RNDIS device. + * @param message The pointer to the pointer of the message buffer. + * @param len The pointer of the length of the buffer. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcRndisInitializeCommand(usb_device_cdc_rndis_struct_t *handle, + uint8_t **message, + uint32_t *len) +{ + rndis_init_msg_struct_t *rndisInitMsg; + rndis_init_cmplt_struct_t *rndisInitCmplt; + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + rndisInitMsg = (rndis_init_msg_struct_t *)handle->rndisCommand; + rndisInitCmplt = (rndis_init_cmplt_struct_t *)handle->responseData; + + /* preparing for Byte 0-3 : MessageType*/ + rndisInitCmplt->messageType = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_INITIALIZE_CMPLT); + + /* preparing for Byte 4-7 : MessageLength*/ + rndisInitCmplt->messageLength = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_RESPONSE_INITIALIZE_MSG_SIZE); + + /* preparing for Byte 8-11 : RequestID*/ + rndisInitCmplt->requestID = rndisInitMsg->requestID; + + /* preparing for Byte 12-15 : Status*/ + if (handle->rndisDeviceState == RNDIS_UNINITIALIZED) + { + rndisInitCmplt->status = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_STATUS_SUCCESS); + } + else + { + rndisInitCmplt->status = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_STATUS_FAILURE); + } + + /* preparing for Byte 16-19 ; MajorVersion*/ + /* We are currently returning the same driver version to host in + response to initialization command as reported by host driver */ + rndisInitCmplt->majorVersion = rndisInitMsg->majorVersion; + + /* preparing for Byte 20-23 : MinorVersion*/ + rndisInitCmplt->minorVersion = rndisInitMsg->minorVersion; + + /* preparing for Byte 24-27 : DeviceFlags*/ + rndisInitCmplt->deviceFlags = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_DF_CONNECTIONLESS); + + /* preparing for Byte 28-31 : Medium*/ + rndisInitCmplt->medium = USB_LONG_TO_LITTLE_ENDIAN(NDIS_MEDIUM802_3); + + /* preparing for Byte 32-35 : MaxPacketsPerTransfer*/ + /* We are not implementing multiple packet transfer support in our RNDIS */ + rndisInitCmplt->maxPacketsPerTransfer = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_SINGLE_PACKET_TRANSFER); + + /* preparing for Byte 36-39 : MaxTransferSize*/ + /* We are currently returning the same max transfer size to host + as it send to device in its corresponding filed in + initialization command */ + handle->rndisHostMaxTxSize = USB_LONG_TO_LITTLE_ENDIAN(rndisInitMsg->maxTransferSize); + rndisInitCmplt->maxTransferSize = USB_LONG_TO_LITTLE_ENDIAN(handle->rndisDevMaxTxSize); + + /* preparing for Byte 40-43 : PacketAlignmentFactor*/ + rndisInitCmplt->packetAlignmentFactor = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_PACKET_ALIGNMENT_FACTOR); + + /* preparing for Byte 44-47 : AFListOffset*/ + rndisInitCmplt->afListOffset = RNDIS_AF_LIST_OFFSET; + + /* preparing for Byte 48-51 : AFListSize*/ + rndisInitCmplt->afListSize = RNDIS_AF_LIST_SIZE; + + *message = handle->responseData; + *len = RNDIS_RESPONSE_INITIALIZE_MSG_SIZE; + + /* initializing RNDIS variables */ + handle->rndisDeviceState = RNDIS_INITIALIZED; + handle->rndisHwState = NDIS_HARDWARE_STATUS_READY; + handle->rndisMediaConnectStatus = NDIS_MEDIA_STATE_DISCONNECTED; + handle->numFramesTxOk = 0; + handle->numFramesRxOk = 0; + handle->numFramesTxError = 0; + handle->numFramesRxError = 0; + handle->numRecvFramesMissed = 0; + handle->numRecvFramesAlignmentError = 0; + handle->numFramesTxOneCollision = 0; + handle->numFramesTxManyCollision = 0; + return kStatus_USB_Success; +} + +/*! + * @brief check the health of RNDIS device and prepare data to be sent to host as RNDIS_KEEPALIVE_CMPLT. + * + * This function is called to check the health of RNDIS device and prepare + * data to be sent to host as RNDIS_KEEPALIVE_CMPLT. + * + * @param handle The pointer the RNDIS device. + * @param message The pointer to the pointer of the message buffer. + * @param len The pointer of the length of the buffer. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcRndisKeepaliveCommand(usb_device_cdc_rndis_struct_t *handle, uint8_t **message, uint32_t *len) + +{ + rndis_keepalive_msg_struct_t *rndisKeepaliveMsg; + rndis_keepalive_cmplt_struct_t *rndisKeepaliveCmplt; + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + rndisKeepaliveMsg = (rndis_keepalive_msg_struct_t *)handle->rndisCommand; + rndisKeepaliveCmplt = (rndis_keepalive_cmplt_struct_t *)handle->responseData; + + /* preparing for Byte 0-3 : MessageType*/ + rndisKeepaliveCmplt->messageType = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_KEEPALIVE_CMPLT); + + /* preparing for Byte 4-7 : MessageLength*/ + rndisKeepaliveCmplt->messageLength = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_RESPONSE_KEEPALIVE_MSG_SIZE); + + /* preparing for Byte 8-11 : RequestID*/ + rndisKeepaliveCmplt->requestID = rndisKeepaliveMsg->requestID; + + /* preparing for Byte 12-15 : Status*/ + USB_CDC_RNDIS_MUTEX_LOCK(handle->statusMutex); + if (handle->rndisDeviceState == RNDIS_DATA_INITIALIZED) + { + rndisKeepaliveCmplt->status = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_STATUS_SUCCESS); + } + else + { + rndisKeepaliveCmplt->status = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_STATUS_FAILURE); + } + USB_CDC_RNDIS_MUTEX_UNLOCK(handle->statusMutex); + + *message = (uint8_t *)rndisKeepaliveCmplt; + *len = RNDIS_RESPONSE_KEEPALIVE_MSG_SIZE; + return kStatus_USB_Success; +} + +/*! + * @brief Query the RNDIS device for its characteristics or statistics information . + * + * This function is called to query the RNDIS device for its + * characteristics or statistics information or status and prepare + * data to be sent to host as RNDIS_Query_CMPLT. + * + * @param handle The pointer the RNDIS device. + * @param message The pointer to the pointer of the message buffer. + * @param len The pointer of the length of the buffer. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcRndisQueryCommand(usb_device_cdc_rndis_struct_t *handle, uint8_t **message, uint32_t *len) + +{ + rndis_query_msg_struct_t *rndisQueryMsg; + rndis_query_cmplt_struct_t *rndisQueryCmplt; + uint32_t infoBufLen = 0; + uint8_t *infoBuf = NULL; + usb_device_cdc_rndis_request_param_struct_t reqParam; + + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + rndisQueryMsg = (rndis_query_msg_struct_t *)handle->rndisCommand; + rndisQueryCmplt = (rndis_query_cmplt_struct_t *)handle->responseData; + + /* preparing for Byte 0-3 : MessageType*/ + rndisQueryCmplt->messageType = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_QUERY_CMPLT); + + /* preparing for Byte 8-11 : RequestID*/ + rndisQueryCmplt->requestID = rndisQueryMsg->requestID; + + /* preparing for Byte 12-15 : Status*/ + rndisQueryCmplt->status = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_STATUS_SUCCESS); + + /* preparing for Byte 20-23 : InformationBufferOffset*/ + rndisQueryCmplt->informationBufferOffset = USB_LONG_TO_LITTLE_ENDIAN(0x00000010); + + infoBuf = (uint8_t *)(&(rndisQueryCmplt->requestID)) + rndisQueryCmplt->informationBufferOffset; + + switch (rndisQueryMsg->oid) + { + case NDIS_OID_GEN_SUPPORTED_LIST: + { + uint32_t i; + /* List of supported OIDs - Query Mandatory - General Operational Characteristic */ + for (i = 0; i < RNDIS_NUM_OIDS_SUPPORTED; i++) + { + /* change the endianness of data before sending on USB Bus */ + s_listSuppOid[i] = USB_LONG_TO_LITTLE_ENDIAN(s_listSuppOid[i]); + } + infoBufLen = sizeof(s_listSuppOid); + memcpy(infoBuf, s_listSuppOid, infoBufLen); + } + break; + case NDIS_OID_GEN_HARDWARE_STATUS: + /* Hardware status - Query Mandatory - General Operational Characteristic*/ + infoBufLen = sizeof(uint32_t); + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(handle->rndisHwState); + break; + case NDIS_OID_GEN_MEDIA_SUPPORTED: + /* Media types supported (encoded) - Query Mandatory - General Operational Characteristic*/ + infoBufLen = sizeof(uint32_t); + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(NDIS_MEDIUM802_3); + break; + case NDIS_OID_GEN_MEDIA_IN_USE: + /* Media types in use (encoded) - Query Mandatory - General Operational Characteristic*/ + infoBufLen = sizeof(uint32_t); + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(NDIS_MEDIUM802_3); + break; + case NDIS_OID_GEN_MAXIMUM_FRAME_SIZE: + /* Maximum in bytes, frame size - Query Mandatory - General Operational Characteristic*/ + infoBufLen = sizeof(uint32_t); + reqParam.buffer = infoBuf; + reqParam.length = infoBufLen; + if (handle->rndisCallback) + { + /* The rndisCallback is initialized in APPInit and is from the second parameter of + USB_DeviceCdcRndisInit */ + handle->rndisCallback(handle->cdcAcmHandle, kUSB_DeviceCdcEventAppGetMaxFrameSize, &reqParam); + } + + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(*((uint32_t *)infoBuf)); + break; + case NDIS_OID_GEN_LINK_SPEED: + /* Link speed in units of 100 bps - Query Mandatory - General Operational Characteristic*/ + infoBufLen = sizeof(uint32_t); + reqParam.buffer = infoBuf; + reqParam.length = infoBufLen; + if (handle->rndisCallback) + { + /* The rndisCallback is initialized in APPInit and is from the second parameter of + USB_DeviceCdcRndisInit */ + handle->rndisCallback(handle->cdcAcmHandle, kUSB_DeviceCdcEventAppGetLinkSpeed, &reqParam); + } + + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(*((uint32_t *)infoBuf)); + break; + case NDIS_OID_GEN_TRANSMIT_BLOCK_SIZE: + /* Minimum amount of storage, in bytes, that a single packet + occupies in the transmit buffer space of the NIC - + Query Mandatory - General Operational Characteristic*/ + infoBufLen = sizeof(uint32_t); + reqParam.buffer = infoBuf; + reqParam.length = infoBufLen; + if (handle->rndisCallback) + { + /* The rndisCallback is initialized in APPInit and is from the second parameter of + USB_DeviceCdcRndisInit */ + handle->rndisCallback(handle->cdcAcmHandle, kUSB_DeviceCdcEventAppGetSendPacketSize, &reqParam); + } + + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(*((uint32_t *)infoBuf)); + break; + case NDIS_OID_GEN_RECEIVE_BLOCK_SIZE: + /* Amount of storage, in bytes, that a single packet occupies in + the receive buffer space of the NIC - Query Mandatory - General Operational Characteristic*/ + infoBufLen = sizeof(uint32_t); + reqParam.buffer = infoBuf; + reqParam.length = infoBufLen; + if (handle->rndisCallback) + { + /* The rndisCallback is initialized in APPInit and is from the second parameter of + USB_DeviceCdcRndisInit */ + handle->rndisCallback(handle->cdcAcmHandle, kUSB_DeviceCdcEventAppGetRecvPacketSize, &reqParam); + } + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(*((uint32_t *)infoBuf)); + break; + case NDIS_OID_GEN_VENDOR_ID: + /* Vendor NIC code - Query Mandatory - General Operational Characteristic*/ + /* This object specifies a three-byte IEEE-registered vendor code, + followed by a single byte that the vendor assigns to identify + a particular NIC. The IEEE code uniquely identifies the vendor + and is the same as the three bytes appearing at the beginning + of the NIC hardware address.Vendors without an IEEE-registered + code should use the value 0xFFFFFF. */ + infoBufLen = sizeof(uint32_t); + + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN( + (uint32_t)(((uint32_t)RNDIS_VENDOR_ID << 8U) | (uint32_t)RNDIS_NIC_IDENTIFIER_VENDOR)); + break; + case NDIS_OID_GEN_VENDOR_DESCRIPTION: + /* Vendor network card description - Query Mandatory - General Operational Characteristic*/ + infoBufLen = VENDOR_INFO_SIZE; + memcpy(infoBuf, s_vendorInfo, infoBufLen); + break; + case NDIS_OID_GEN_CURRENT_PACKET_FILTER: + /* Current packet filter (encoded) - Query and Set Mandatory - General Operational Characteristic*/ + infoBufLen = sizeof(uint32_t); + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(handle->rndisPacketFilter); + break; + case NDIS_OID_GEN_MAXIMUM_TOTAL_SIZE: + /* Maximum total packet length in bytes - Query Mandatory - General Operational Characteristic*/ + infoBufLen = sizeof(uint32_t); + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(handle->rndisDevMaxTxSize); + break; + case NDIS_OID_GEN_MEDIA_CONNECT_STATUS: + /* Whether the NIC is connected to the network - Query Mandatory - General Operational Characteristic*/ + { + uint32_t mediaConnected; + /* Whether the NIC is connected to the network - Query Mandatory - General Operational Characteristic*/ + infoBufLen = sizeof(uint32_t); + reqParam.buffer = (uint8_t *)&mediaConnected; + reqParam.length = infoBufLen; + if (handle->rndisCallback) + { + /* The rndisCallback is initialized in APPInit and is from the second parameter of + USB_DeviceCdcRndisInit */ + handle->rndisCallback(handle->cdcAcmHandle, kUSB_DeviceCdcEventAppGetLinkSpeed, &reqParam); + } + + if (mediaConnected) + { + handle->rndisMediaConnectStatus = NDIS_MEDIA_STATE_CONNECTED; + } + else + { + handle->rndisMediaConnectStatus = NDIS_MEDIA_STATE_DISCONNECTED; + } + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(handle->rndisMediaConnectStatus); + } + break; + case NDIS_OID_GEN_XMIT_OK: + /* Frames transmitted without errors - Query Mandatory - General Statistics*/ + infoBufLen = sizeof(uint32_t); + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(handle->numFramesTxOk); + break; + case NDIS_OID_GEN_RCV_OK: + /* Frames received without errors - Query Mandatory - General Statistics*/ + infoBufLen = sizeof(uint32_t); + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(handle->numFramesRxOk); + break; + case NDIS_OID_GEN_XMIT_ERROR: + /* Frames not transmitted or transmitted with errors - Query Mandatory - General Statistics*/ + infoBufLen = sizeof(uint32_t); + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(handle->numFramesTxError); + break; + case NDIS_OID_GEN_RCV_ERROR: + /* Frames received with errors - Query Mandatory - General Statistics*/ + infoBufLen = sizeof(uint32_t); + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(handle->numFramesRxError); + break; + case NDIS_OID_GEN_RCV_NO_BUFFER: + /* Frame missed, no buffers - Query Mandatory - General Statistics*/ + infoBufLen = sizeof(uint32_t); + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(handle->numRecvFramesMissed); + break; + case NDIS_OID_802_3_PERMANENT_ADDRESS: + /* Permanent station address - Query Mandatory - Ethernet Operational Characteristic*/ + infoBufLen = RNDIS_ETHER_ADDR_SIZE; + reqParam.buffer = infoBuf; + reqParam.length = infoBufLen; + if (handle->rndisCallback) + { + /* The rndisCallback is initialized in APPInit and is from the second parameter of + USB_DeviceCdcRndisInit */ + handle->rndisCallback(handle->cdcAcmHandle, kUSB_DeviceCdcEventAppGetMacAddress, &reqParam); + } + + break; + case NDIS_OID_802_3_CURRENT_ADDRESS: + { + /* Current station address - Query Mandatory - Ethernet Operational Characteristic*/ + infoBufLen = RNDIS_ETHER_ADDR_SIZE; + reqParam.buffer = infoBuf; + reqParam.length = infoBufLen; + if (handle->rndisCallback) + { + /* The rndisCallback is initialized in APPInit and is from the second parameter of + USB_DeviceCdcRndisInit */ + handle->rndisCallback(handle->cdcAcmHandle, kUSB_DeviceCdcEventAppGetMacAddress, &reqParam); + } + } + break; + case NDIS_OID_802_3_MULTICAST_LIST: + /* Current multicast address list - Query and Set Mandatory - Ethernet Operational Characteristic*/ + infoBufLen = RNDIS_ETHER_ADDR_SIZE; + /* Currently Our RNDIS driver does not support multicast addressing */ + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(0x00000000); + *((uint32_t *)infoBuf + 1) = USB_LONG_TO_LITTLE_ENDIAN(0x00000000); + break; + case NDIS_OID_802_3_MAXIMUM_LIST_SIZE: + /* Maximum size of multicast address list - Query Mandatory - Ethernet Operational Characteristic*/ + infoBufLen = sizeof(uint32_t); + /* Currently Our RNDIS driver does not support multicast addressing */ + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_MULTICAST_LIST_SIZE); + break; + case NDIS_OID_802_3_RCV_ERROR_ALIGNMENT: + /* Frames received with alignment error - Query Mandatory - Ethernet Statistics*/ + infoBufLen = sizeof(uint32_t); + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(handle->numRecvFramesAlignmentError); + break; + case NDIS_OID_802_3_XMIT_ONE_COLLISION: + /* Frames transmitted with one collision - Query Mandatory - Ethernet Statistics*/ + infoBufLen = sizeof(uint32_t); + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(handle->numFramesTxOneCollision); + break; + case NDIS_OID_802_3_XMIT_MORE_COLLISIONS: + /* Frames transmitted with more than one collision - Query Mandatory - Ethernet Statistics*/ + infoBufLen = sizeof(uint32_t); + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(handle->numFramesTxManyCollision); + break; + case NDIS_OID_GEN_PHYSICAL_MEDIUM: + /* Physical media supported by the miniport (encoded)*/ + infoBufLen = sizeof(uint32_t); + *((uint32_t *)infoBuf) = USB_LONG_TO_LITTLE_ENDIAN(NDIS_PHYSICAL_MEDIUM_POWER_LINE); + break; + default: + usb_echo("OID 0x%x NOT SUPPORTED(QUERY)\n", rndisQueryMsg->oid); + rndisQueryCmplt->status = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_STATUS_NOT_SUPPORTED); + break; + } + + *len = RNDIS_RESPONSE_QUERY_MSG_SIZE + infoBufLen; + /* preparing for Byte 4-7 : MessageLength*/ + rndisQueryCmplt->messageLength = USB_LONG_TO_LITTLE_ENDIAN(*len); + /* preparing for Byte 16-19 : InformationBufferLength*/ + rndisQueryCmplt->informationBufferLength = USB_LONG_TO_LITTLE_ENDIAN(infoBufLen); + *message = (uint8_t *)&(rndisQueryCmplt->messageType); + return kStatus_USB_Success; +} + +/*! + * @brief Configure the operational parameters of RNDIS device. + * + * This function is called to Configure the operational parameters of + * RNDIS device. + * + * @param handle The pointer the RNDIS device. + * @param message The pointer to the pointer of the message buffer. + * @param len The pointer of the length of the buffer. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcRndisSetCommand(usb_device_cdc_rndis_struct_t *handle, uint8_t **message, uint32_t *len) + +{ + rndis_set_msg_struct_t *rndisSetMsg; + rndis_set_cmplt_struct_t *rndisSetCmplt; + usb_device_cdc_rndis_request_param_struct_t reqParam; + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + rndisSetMsg = (rndis_set_msg_struct_t *)handle->rndisCommand; + rndisSetCmplt = (rndis_set_cmplt_struct_t *)handle->responseData; + + /* preparing for Byte 0-3 : MessageType*/ + rndisSetCmplt->messageType = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_SET_CMPLT); + + *len = RNDIS_RESPONSE_SET_MSG_SIZE; + /* preparing for Byte 4-7 : MessageLength*/ + rndisSetCmplt->messageLength = USB_LONG_TO_LITTLE_ENDIAN(*len); + + /* preparing for Byte 8-11 : RequestID*/ + rndisSetCmplt->requestID = rndisSetMsg->requestID; + + switch (rndisSetMsg->oid) + { + case NDIS_OID_GEN_CURRENT_PACKET_FILTER: + /* Current packet filter (encoded) - Query and Set Mandatory - General Operational Characteristic*/ + if (rndisSetMsg->informationBufferLength != 4) + { + rndisSetCmplt->status = RNDIS_STATUS_INVALID_DATA; + } + else + { + uint32_t mediaConnected = 0; + + handle->rndisPacketFilter = USB_LONG_TO_LITTLE_ENDIAN( + *((uint32_t *)((uint8_t *)(&rndisSetMsg->requestID) + rndisSetMsg->informationBufferOffset))); + reqParam.buffer = (uint8_t *)&mediaConnected; + reqParam.length = sizeof(mediaConnected); + if (handle->rndisCallback) + { + /* The rndisCallback is initialized in APPInit and is from the second parameter of + USB_DeviceCdcRndisInit */ + handle->rndisCallback(handle->cdcAcmHandle, kUSB_DeviceCdcEventAppGetLinkStatus, &reqParam); + } + + USB_CDC_RNDIS_MUTEX_LOCK(handle->statusMutex); + if ((handle->rndisPacketFilter) && (mediaConnected == 1)) + { + handle->rndisDeviceState = RNDIS_DATA_INITIALIZED; + handle->rndisMediaConnectStatus = NDIS_MEDIA_STATE_CONNECTED; + } + else + { + handle->rndisDeviceState = RNDIS_INITIALIZED; + handle->rndisMediaConnectStatus = NDIS_MEDIA_STATE_DISCONNECTED; + } + USB_CDC_RNDIS_MUTEX_UNLOCK(handle->statusMutex); + } + break; + case NDIS_OID_802_3_MULTICAST_LIST: + /* Current multicast address list - Query and Set Mandatory - Ethernet Operational Characteristic*/ + if (rndisSetMsg->informationBufferLength != RNDIS_ETHER_ADDR_SIZE) + { + rndisSetCmplt->status = RNDIS_STATUS_INVALID_DATA; + } + else + { + uint64_t multiCastList; + multiCastList = + *((uint64_t *)((uint8_t *)(&rndisSetMsg->requestID) + rndisSetMsg->informationBufferOffset)); + if (multiCastList) + { + /* Currently Our RNDIS driver does not support multicast addressing */ + rndisSetCmplt->status = RNDIS_STATUS_NOT_SUPPORTED; + } + } + + break; + default: + usb_echo("OID 0x%x NOT SUPPORTED(SET)\n", rndisSetMsg->oid); + rndisSetCmplt->status = RNDIS_STATUS_NOT_SUPPORTED; + break; + } + /* preparing for Byte 12-15 : Status*/ + rndisSetCmplt->status = USB_LONG_TO_LITTLE_ENDIAN(rndisSetCmplt->status); + *message = (uint8_t *)&(rndisSetCmplt->messageType); + return kStatus_USB_Success; +} + +/*! + * @brief Soft reset the RNDIS device. + * + * This function is called to soft reset the RNDIS device. + * + * @param handle The pointer the RNDIS device. + * @param message The pointer to the pointer of the message buffer. + * @param len The pointer of the length of the buffer. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcRndisResetCommand(usb_device_cdc_rndis_struct_t *handle, uint8_t **message, uint32_t *len) + +{ + rndis_reset_cmplt_struct_t *rndisResetCmplt; + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + rndisResetCmplt = (rndis_reset_cmplt_struct_t *)handle->responseData; + + /* preparing for Byte 0-3 : MessageType*/ + rndisResetCmplt->messageType = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_RESET_CMPLT); + + *len = RNDIS_RESPONSE_RESET_MSG_SIZE; + /* preparing for Byte 4-7 : MessageLength*/ + rndisResetCmplt->messageLength = USB_LONG_TO_LITTLE_ENDIAN(*len); + + /* preparing for Byte 8-11 : Status*/ + rndisResetCmplt->status = USB_LONG_TO_LITTLE_ENDIAN(RNDIS_STATUS_SUCCESS); + + /* preparing for Byte 12-15 : AddressingReset*/ + /* No need for host to resend addressing information */ + rndisResetCmplt->addressingReset = USB_LONG_TO_LITTLE_ENDIAN(0x00000000); + + *message = (uint8_t *)&(rndisResetCmplt->messageType); + USB_CDC_RNDIS_MUTEX_LOCK(handle->statusMutex); + handle->rndisHwState = NDIS_HARDWARE_STATUS_RESET; + handle->rndisDeviceState = RNDIS_UNINITIALIZED; + handle->rndisMediaConnectStatus = NDIS_MEDIA_STATE_UNKNOWN; + USB_CDC_RNDIS_MUTEX_UNLOCK(handle->statusMutex); + return kStatus_USB_Success; +} + +/*! + * @brief Indicate change in status of device. + * + * This function is called to indicate change in status of device. + * + * @param handle The pointer the RNDIS device. + * @param message The pointer to the pointer of the message buffer. + * @param len The pointer of the length of the buffer. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcRndisIndicateStatusCommand(usb_device_cdc_rndis_struct_t *handle, + uint8_t **message, + uint32_t *len) + +{ + return kStatus_USB_Success; +} + +/*! + * @brief Halt the RNDIS device. + * + * This function is called to halt the RNDIS device. + * i.e. to terminate the network connection. + * + * @param handle The pointer the RNDIS device. + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceCdcRndisHaltCommand(usb_device_cdc_rndis_struct_t *handle) +{ + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + usb_echo("RNDIS_Halt_Command\n"); + USB_CDC_RNDIS_MUTEX_LOCK(handle->statusMutex); + handle->rndisDeviceState = RNDIS_UNINITIALIZED; + handle->rndisMediaConnectStatus = NDIS_MEDIA_STATE_DISCONNECTED; + handle->rndisHwState = NDIS_HARDWARE_STATUS_NOT_READY; + USB_CDC_RNDIS_MUTEX_UNLOCK(handle->statusMutex); + return kStatus_USB_Success; +} +#endif /* USB_DEVICE_CONFIG_CDC_RNDIS */ diff --git a/usb/device/class/usb_device_cdc_rndis.h b/usb/device/class/usb_device_cdc_rndis.h new file mode 100644 index 0000000..a2c64b0 --- /dev/null +++ b/usb/device/class/usb_device_cdc_rndis.h @@ -0,0 +1,712 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _USB_DEVICE_CDC_RNDIS_H_ +#define _USB_DEVICE_CDC_RNDIS_H_ + +/*! + * @addtogroup cdc_rndis + * @{ + */ + +/******************************************************************************* +* Definitions +******************************************************************************/ +#define USB_DEVICE_CONFIG_CDC_RNDIS_MAX_INSTANCE (1U) /*!< The maximum number of USB CDC RNDIS device instance*/ + /*! + * @name RNDIS Control Message Type + * See MSDN for details. + * @{ + */ +#define RNDIS_PACKET_MSG (0x00000001U) +#define RNDIS_INITIALIZE_MSG (0x00000002U) +#define RNDIS_HALT_MSG (0x00000003U) +#define RNDIS_QUERY_MSG (0x00000004U) +#define RNDIS_SET_MSG (0x00000005U) +#define RNDIS_RESET_MSG (0x00000006U) +#define RNDIS_INDICATE_STATUS_MSG (0x00000007U) +#define RNDIS_KEEPALIVE_MSG (0x00000008U) +#define RNDIS_INITIALIZE_CMPLT (0x80000002U) +#define RNDIS_QUERY_CMPLT (0x80000004U) +#define RNDIS_SET_CMPLT (0x80000005U) +#define RNDIS_RESET_CMPLT (0x80000006U) +#define RNDIS_KEEPALIVE_CMPLT (0x80000008U) +/* @} */ + +/*! + * @name Object Identifiers used by NdisRequest Query/Set Information + * See MSDN for details. + * @{ + */ +/* General Objects */ +#define NDIS_OID_GEN_SUPPORTED_LIST (0x00010101U) +#define NDIS_OID_GEN_HARDWARE_STATUS (0x00010102U) +#define NDIS_OID_GEN_MEDIA_SUPPORTED (0x00010103U) +#define NDIS_OID_GEN_MEDIA_IN_USE (0x00010104U) +#define NDIS_OID_GEN_MAXIMUM_LOOKAHEAD (0x00010105U) +#define NDIS_OID_GEN_MAXIMUM_FRAME_SIZE (0x00010106U) +#define NDIS_OID_GEN_LINK_SPEED (0x00010107U) +#define NDIS_OID_GEN_TRANSMIT_BUFFER_SPACE (0x00010108U) +#define NDIS_OID_GEN_RECEIVE_BUFFER_SPACE (0x00010109U) +#define NDIS_OID_GEN_TRANSMIT_BLOCK_SIZE (0x0001010AU) +#define NDIS_OID_GEN_RECEIVE_BLOCK_SIZE (0x0001010BU) +#define NDIS_OID_GEN_VENDOR_ID (0x0001010CU) +#define NDIS_OID_GEN_VENDOR_DESCRIPTION (0x0001010DU) +#define NDIS_OID_GEN_CURRENT_PACKET_FILTER (0x0001010EU) +#define NDIS_OID_GEN_CURRENT_LOOKAHEAD (0x0001010FU) +#define NDIS_OID_GEN_DRIVER_VERSION (0x00010110U) +#define NDIS_OID_GEN_MAXIMUM_TOTAL_SIZE (0x00010111U) +#define NDIS_OID_GEN_PROTOCOL_OPTIONS (0x00010112U) +#define NDIS_OID_GEN_MAC_OPTIONS (0x00010113U) +#define NDIS_OID_GEN_MEDIA_CONNECT_STATUS (0x00010114U) +#define NDIS_OID_GEN_MAXIMUM_SEND_PACKETS (0x00010115U) +#define NDIS_OID_GEN_XMIT_OK (0x00020101U) +#define NDIS_OID_GEN_RCV_OK (0x00020102U) +#define NDIS_OID_GEN_XMIT_ERROR (0x00020103U) +#define NDIS_OID_GEN_RCV_ERROR (0x00020104U) +#define NDIS_OID_GEN_RCV_NO_BUFFER (0x00020105U) +#define NDIS_OID_GEN_DIRECTED_BYTES_XMIT (0x00020201U) +#define NDIS_OID_GEN_DIRECTED_FRAMES_XMIT (0x00020202U) +#define NDIS_OID_GEN_MULTICAST_BYTES_XMIT (0x00020203U) +#define NDIS_OID_GEN_MULTICAST_FRAMES_XMIT (0x00020204U) +#define NDIS_OID_GEN_BROADCAST_BYTES_XMIT (0x00020205U) +#define NDIS_OID_GEN_BROADCAST_FRAMES_XMIT (0x00020206U) +#define NDIS_OID_GEN_DIRECTED_BYTES_RCV (0x00020207U) +#define NDIS_OID_GEN_DIRECTED_FRAMES_RCV (0x00020208U) +#define NDIS_OID_GEN_MULTICAST_BYTES_RCV (0x00020209U) +#define NDIS_OID_GEN_MULTICAST_FRAMES_RCV (0x0002020AU) +#define NDIS_OID_GEN_BROADCAST_BYTES_RCV (0x0002020BU) +#define NDIS_OID_GEN_BROADCAST_FRAMES_RCV (0x0002020CU) +#define NDIS_OID_GEN_RCV_CRC_ERROR (0x0002020DU) +#define NDIS_OID_GEN_TRANSMIT_QUEUE_LENGTH (0x0002020EU) +#define NDIS_OID_GEN_GET_TIME_CAPS (0x0002020FU) +#define NDIS_OID_GEN_GET_NETCARD_TIME (0x00020210U) +/* 802.3 Objects (Ethernet) */ +#define NDIS_OID_802_3_PERMANENT_ADDRESS (0x01010101U) +#define NDIS_OID_802_3_CURRENT_ADDRESS (0x01010102U) +#define NDIS_OID_802_3_MULTICAST_LIST (0x01010103U) +#define NDIS_OID_802_3_MAXIMUM_LIST_SIZE (0x01010104U) +#define NDIS_OID_802_3_MAC_OPTIONS (0x01010105U) + +#define NDIS_802_3_MAC_OPTION_PRIORITY (0x00000001U) +#define NDIS_OID_802_3_RCV_ERROR_ALIGNMENT (0x01020101U) +#define NDIS_OID_802_3_XMIT_ONE_COLLISION (0x01020102U) +#define NDIS_OID_802_3_XMIT_MORE_COLLISIONS (0x01020103U) +#define NDIS_OID_802_3_XMIT_DEFERRED (0x01020201U) +#define NDIS_OID_802_3_XMIT_MAX_COLLISIONS (0x01020202U) +#define NDIS_OID_802_3_RCV_OVERRUN (0x01020203U) +#define NDIS_OID_802_3_XMIT_UNDERRUN (0x01020204U) +#define NDIS_OID_802_3_XMIT_HEARTBEAT_FAILURE (0x01020205U) +#define NDIS_OID_802_3_XMIT_TIMES_CRS_LOST (0x01020206U) +#define NDIS_OID_802_3_XMIT_LATE_COLLISIONS (0x01020207U) + +/* Optional OIDs */ +#define NDIS_OID_GEN_VENDOR_DRIVER_VERSION (0x00010116U) +#define NDIS_OID_GEN_SUPPORTED_GUIDS (0x00010117U) +#define NDIS_OID_GEN_NETWORK_LAYER_ADDRESSES (0x00010118U) /* Set only */ +#define NDIS_OID_GEN_TRANSPORT_HEADER_OFFSET (0x00010119U) /* Set only */ +#define NDIS_OID_GEN_MACHINE_NAME (0x0001021AU) +#define NDIS_OID_GEN_RNDIS_CONFIG_PARAMETER (0x0001021BU) /* Set only */ +#define NDIS_OID_GEN_VLAN_ID (0x0001021CU) +#define NDIS_OID_GEN_MEDIA_CAPABILITIES (0x00010201U) +#define NDIS_OID_GEN_PHYSICAL_MEDIUM (0x00010202U) +/* @} */ + +/*! + * @name NDIS Hardware status codes for OID_GEN_HARDWARE_STATUS + * See MSDN for details. + * @{ + */ +/*! Available and capable of sending and receiving data over the wire */ +#define NDIS_HARDWARE_STATUS_READY (0x00000000U) +/*! Initializing */ +#define NDIS_HARDWARE_STATUS_INITIALIZING (0x00000001U) +/*! Resetting */ +#define NDIS_HARDWARE_STATUS_RESET (0x00000002U) +/*! Closing */ +#define NDIS_HARDWARE_STATUS_CLOSING (0x00000003U) +/*! Not ready */ +#define NDIS_HARDWARE_STATUS_NOT_READY (0x00000004U) +/* @} */ + +/*! + * @name NDIS media types that the NIC can support + * See MSDN for details. + * @{ + */ +/*! Ethernet (802.3) is not supported for NDIS 6.0 drivers. + * Note NDIS 5.x Miniport drivers that conform to the IEEE® 802.11 interface must + * use this media type. For more information about the 802.11 interface, + * see 802.11 Wireless LAN Miniport Drivers. + */ +#define NDIS_MEDIUM802_3 (0x00000000U) +/*! Token Ring (802.5) is not supported for NDIS 6.0 drivers.*/ +#define NDIS_MEDIUM802_5 (0x00000001U) +/*! FDDI is not supported on Windows® Vista.*/ +#define NDIS_MEDIUM_FDDI (0x00000002U) +/*! WAN*/ +#define NDIS_MEDIUM_WAN (0x00000003U) +/*! LocalTalk*/ +#define NDIS_MEDIUM_LOCAL_TALK (0x00000004U) +/*! DEC/Intel/Xerox (DIX) Ethernet*/ +#define NDIS_MEDIUM_DIX (0x00000005U) +/*! ARCNET (raw) is not supported on Windows Vista.*/ +#define NDIS_MEDIUM_ARCNET_RAW (0x00000006U) +/*! ARCNET (878.2) is not supported on Windows Vista.*/ +#define NDIS_MEDIUM_ARCNET878_2 (0x00000007U) +/*! ATM is not supported for NDIS 6.0 drivers.*/ +#define NDIS_MEDIUM_ATM (0x00000008U) +/*! Native 802.11. This media type is used by Miniport drivers that conform to + * the Native 802.11 interface. For more information about this interface, see + * Native 802.11 Wireless LAN Miniport Drivers. + * Note: Native 802.11 interface is supported in NDIS 6.0 and later versions + */ +#define NDIS_MEDIUM_NATIVE802_11 (0x00000009U) +/*! Various types of NdisWirelessXxx media + * Note This media type is not available for use beginning with Windows Vista. + */ +#define NDIS_MEDIUM_WIRELESS_WAN (0x0000000AU) +/*! Infrared (IrDA)*/ +#define NDIS_MEDIUM_IRDA (0x0000000BU) +/*! Connection-oriented WAN */ +#define NDIS_MEDIUM_COWAN (0x0000000CU) +/*! IEEE 1394 (firewire) bus */ +#define NDIS_MEDIUM1394 (0x0000000DU) +/*! Broadcast PC network.*/ +#define NDIS_MEDIUM_BPC (0x0000000EU) +/*! InfiniBand network.*/ +#define NDIS_MEDIUM_INFINI_BAND (0x0000000FU) +/*! Tunnel network.*/ +#define NDIS_MEDIUM_TUNNEL (0x00000010U) +/*! NDIS loopback network. */ +#define NDIS_MEDIUM_LOOPBACK (0x00000011U) +/* @} */ + +/*! + * @name NDIS Packet Filter Bits for OID_GEN_CURRENT_PACKET_FILTER. + * See MSDN for details. + * @{ + */ +/*! Directed packets. Directed packets contain a destination address + * equal to the station address of the NIC. + */ +#define NDIS_PACKET_TYPE_DIRECTED (0x0001U) +/*! Multicast address packets sent to addresses in the multicast address list. + * A protocol driver can receive Ethernet (802.3) multicast packets or + * Token Ring (802.5) functional address packets by specifying the multicast or + * functional address packet type. Setting the multicast address list or + * functional address determines which multicast address + * groups the NIC driver enables. + */ +#define NDIS_PACKET_TYPE_MULTICAST (0x0002U) +/*! All multicast address packets, not just the ones enumerated in the + * multicast address list. + */ +#define NDIS_PACKET_TYPE_ALL_MULTICAST (0x0004U) +/*! Broadcast packets. */ +#define NDIS_PACKET_TYPE_BROADCAST (0x0008U) +/*! All source routing packets. If the protocol driver sets this bit, + * the NDIS library attempts to act as a source routing bridge. + */ +#define NDIS_PACKET_TYPE_SOURCE_ROUTING (0x0010U) +/*! Specifies all packets.*/ +#define NDIS_PACKET_TYPE_PROMISCUOUS (0x0020U) +/*! SMT packets that an FDDI NIC receives. */ +#define NDIS_PACKET_TYPE_SMT (0x0040U) +/*! All packets sent by installed protocols and all packets indicated by the NIC + * that is identified by a given NdisBindingHandle. + */ +#define NDIS_PACKET_TYPE_ALL_LOCAL (0x0080U) +/*! NIC driver frames that a Token Ring NIC receives. */ +#define NDIS_PACKET_TYPE_MAC_FRAME (0x8000U) +/*! Functional address packets sent to addresses included in the current + * functional address. + */ +#define NDIS_PACKET_TYPE_FUNCTIONAL (0x4000U) +/*! All functional address packets, not just the ones in the + * current functional address. + */ +#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL (0x2000U) +/*! Packets sent to the current group address. */ +#define NDIS_PACKET_TYPE_GROUP (0x1000U) +/* @} */ + +/*! + * @name RNDIS status values + * See MSDN for details. + * @{ + */ +/*! The requested operation completed successfully.*/ +#define RNDIS_STATUS_SUCCESS (0x00000000U) +/*! The underlying driver does not support the requested operation.*/ +#define RNDIS_STATUS_NOT_RECOGNIZED (0x00010001U) +/*! Unsupported request error (equivalent to STATUS_NOT_SUPPORTED). */ +#define RNDIS_STATUS_NOT_SUPPORTED (0xC00000BBU) +/*! The underlying driver attempted the requested operation, usually a set, + * on its NIC but it was aborted by the Netcard. For example, an attempt to set + * too many multicast addresses might cause the return of this value. + */ +#define RNDIS_STATUS_NOT_ACCEPTED (0x00010003U) +/*! This value usually is a non specific default, returned when none of the more + * specific NDIS_STATUS_XXX causes the underlying driver to fail the request. + */ +#define RNDIS_STATUS_FAILURE (0xC0000001U) +/*! The request can't be satisfied due to a resource shortage. + * Usually, this return indicates that an attempt to allocate memory was + * unsuccessful, but it does not necessarily indicate that the same request, + * submitted later, it is aborted for the same reason. + */ +#define RNDIS_STATUS_RESOURCES (0xC000009AU) +/*! The underlying driver failed the requested operation because a close is in progress.*/ +#define RNDIS_STATUS_CLOSING (0xC0010002U) +/*! The underlying driver failed the requested operation because indicating a close is in progress.*/ +#define RNDIS_STATUS_CLOSING_INDICATING (0xC001000EU) +/*! The underlying NIC driver cannot satisfy the request at this time because it + * is currently resetting the Netcard. + */ +#define RNDIS_STATUS_RESET_IN_PROGRESS (0xC001000DU) +/*! The value specified in the InformationBufferLength member of the + * NDIS_REQUEST-structured buffer at NdisRequest does not match the + * requirements for the given OID_XXX code. If the information buffer + * is too small, the BytesNeeded member contains the correct value for + * InformationBufferLength on return from NdisRequest. + */ +#define RNDIS_STATUS_INVALID_LENGTH (0xC0010014U) +/*! The information buffer is too small. */ +#define RNDIS_STATUS_BUFFER_TOO_SHORT (0xC0010016U) +/*! The data supplied at InformationBuffer in the given NDIS_REQUEST structure + * is invalid for the given OID_XXX code. + */ +#define RNDIS_STATUS_INVALID_DATA (0xC0010015U) +/*! The OID_XXX code specified in the OID member of the NDIS_REQUEST-structured + * buffer at NdisRequest is invalid or unsupported by the underlying driver. + */ +#define RNDIS_STATUS_INVALID_OID (0xC0010017U) +/*! Device is connected to network medium. */ +#define RNDIS_STATUS_MEDIA_CONNECT (0x4001000BU) +/*! Device is disconnected from network medium. */ +#define RNDIS_STATUS_MEDIA_DISCONNECT (0x4001000CU) +/* @} */ + +/*! + * @name RNDIS Response sizes + * Definitions of the size of response of various message types. + * @{ + */ +/*! Response size of INITIALIZE_MSG. */ +#define RNDIS_RESPONSE_INITIALIZE_MSG_SIZE (52U) +/*! Response size of QUERY_MSG. */ +#define RNDIS_RESPONSE_QUERY_MSG_SIZE (24U) +/*! Response size of SET_MSG. */ +#define RNDIS_RESPONSE_SET_MSG_SIZE (16U) +/*! Response size of RESET_MSG. */ +#define RNDIS_RESPONSE_RESET_MSG_SIZE (16U) +/*! Response size of KEEPALIVE_MSG. */ +#define RNDIS_RESPONSE_KEEPALIVE_MSG_SIZE (16U) +/* @} */ + +/*! The Miniport driver type is connectionless. */ +#define RNDIS_DF_CONNECTIONLESS (0x00000001U) +/*! The Miniport driver type is connection-oriented. */ +#define RNDIS_DF_CONNECTION_ORIENTED (0x00000002U) +/*! The number of RNDIS data messages that the device can handle in a single transfer. */ +#define RNDIS_SINGLE_PACKET_TRANSFER (0x00000001U) +/*! The byte alignment that the device expects for each RNDIS message that is part of a multimessage transfer. */ +#define RNDIS_PACKET_ALIGNMENT_FACTOR (0x00000003U) +/*! The number of OIDs the RNDIS device supported. */ +#define RNDIS_NUM_OIDS_SUPPORTED (25U) +/*! The vendor ID of the RNDIS device. Vendors without an IEEE-registered code should use the value 0xFFFFFF. */ +#define RNDIS_VENDOR_ID (0xFFFFFFU) +/*! A single byte that the vendor assigns to identify a particular NIC*/ +#define RNDIS_NIC_IDENTIFIER_VENDOR (0x01U) + +/*! + * @name RNDIS device connection status + * Definitions of the status value of NIC connection. + * @{ + */ +/*! The network connection has been lost. */ +#define NDIS_MEDIA_STATE_CONNECTED (0x00000000U) +/*! The network connection has been restored. */ +#define NDIS_MEDIA_STATE_DISCONNECTED (0x00000001U) +/*! The initial value of the connection status. */ +#define NDIS_MEDIA_STATE_UNKNOWN (0xFFFFFFFFU) +/* @} */ + +/*! DataLength : Data length of communication feature. */ +#define RNDIS_MAX_EXPECTED_COMMAND_SIZE (76U) + +/*! This is the maximum observed command size we get on control endpoint -- + * Memory for commands is allocated at initialization, instead of + * being dynamically allocated when command is received to avoid memory + * fragmentation. + */ +#define RNDIS_MAX_EXPECTED_RESPONSE_SIZE (RNDIS_RESPONSE_QUERY_MSG_SIZE + (RNDIS_NUM_OIDS_SUPPORTED << 2U)) + +/*! + * @name Reserved for connection oriented devices. Set value to zero. + * @{ + */ +#define RNDIS_AF_LIST_OFFSET (0x00000000U) +#define RNDIS_AF_LIST_SIZE (0x00000000U) +/* @} */ + +/*! Size of Ethernet address. */ +#define RNDIS_ETHER_ADDR_SIZE (6U) + +/*! Size of USB header for RNDIS packet. */ +#define RNDIS_USB_HEADER_SIZE (44U) +/*! Maximum size of multicast address list. */ +#define RNDIS_MULTICAST_LIST_SIZE (0U) + +/*! @brief Physical Medium Type definitions. Used with OID_GEN_PHYSICAL_MEDIUM. */ +typedef enum _ndis_physical_medium_enum +{ + NDIS_PHYSICAL_MEDIUM_UNSPECIFIED, + NDIS_PHYSICAL_MEDIUM_WIRELESS_LAN, + NDIS_PHYSICAL_MEDIUM_CABLE_MODEM, + NDIS_PHYSICAL_MEDIUM_PHONE_LINE, + NDIS_PHYSICAL_MEDIUM_POWER_LINE, + NDIS_PHYSICAL_MEDIUMDSL, /* includes ADSL and UADSL (G.Lite) */ + NDIS_PHYSICAL_MEDIUM_FIBRE_CHANNEL, + NDIS_PHYSICAL_MEDIUM1394, + NDIS_PHYSICAL_MEDIUM_WIRELESS_WAN, + NDIS_PHYSICAL_MEDIUM_NATIVE802_11, + NDIS_PHYSICAL_MEDIUM_BLUETOOTH, + NDIS_PHYSICAL_MEDIUM_MAX /* Not a real physical type, defined as an upper-bound. */ +} ndis_physical_medium_enum_t; + +/*! @brief Define message structure for REMOTE_NDIS_INITIALIZE_MSG. */ +typedef struct _rndis_init_msg_struct +{ + uint32_t messageType; + uint32_t messageLength; + uint32_t requestID; + uint32_t majorVersion; + uint32_t minorVersion; + uint32_t maxTransferSize; +} rndis_init_msg_struct_t; + +/*! @brief Define message structure for REMOTE_NDIS_INITIALIZE_CMPLT. */ +typedef struct _rndis_init_cmplt_struct +{ + uint32_t messageType; + uint32_t messageLength; + uint32_t requestID; + uint32_t status; + uint32_t majorVersion; + uint32_t minorVersion; + uint32_t deviceFlags; + uint32_t medium; + uint32_t maxPacketsPerTransfer; + uint32_t maxTransferSize; + uint32_t packetAlignmentFactor; + uint32_t afListOffset; + uint32_t afListSize; +} rndis_init_cmplt_struct_t; + +/*! @brief Define message structure for REMOTE_NDIS_HALT_MSG. */ +typedef struct _rndis_halt_msg_struct +{ + uint32_t messageType; + uint32_t messageLength; + uint32_t requestID; +} rndis_halt_msg_struct_t; + +/*! @brief Define message structure for REMOTE_NDIS_QUERY_MSG. */ +typedef struct _rndis_query_msg_struct +{ + uint32_t messageType; + uint32_t messageLength; + uint32_t requestID; + uint32_t oid; + uint32_t informationBufferLength; + uint32_t informationBufferOffset; + uint32_t deviceVcHandle; +} rndis_query_msg_struct_t; + +/*! @brief Define message structure for REMOTE_NDIS_QUERY_CMPLT. */ +typedef struct _rndis_query_cmplt_struct +{ + uint32_t messageType; + uint32_t messageLength; + uint32_t requestID; + uint32_t status; + uint32_t informationBufferLength; + uint32_t informationBufferOffset; +} rndis_query_cmplt_struct_t; + +/*! @brief Define message structure for REMOTE_NDIS_SET_MSG. */ +typedef struct _rndis_set_msg_struct +{ + uint32_t messageType; + uint32_t messageLength; + uint32_t requestID; + uint32_t oid; + uint32_t informationBufferLength; + uint32_t informationBufferOffset; + uint32_t deviceVcHandle; +} rndis_set_msg_struct_t; + +/*! @brief Define message structure for REMOTE_NDIS_SET_CMPLT. */ +typedef struct _rndis_set_cmplt_struct +{ + uint32_t messageType; + uint32_t messageLength; + uint32_t requestID; + uint32_t status; +} rndis_set_cmplt_struct_t; + +/*! @brief Define message structure for REMOTE_NDIS_RESET_MSG. */ +typedef struct _rndis_reset_msg_struct +{ + uint32_t messageType; + uint32_t messageLength; + uint32_t reserved; +} rndis_reset_msg_struct_t; + +/*! @brief Define message structure for REMOTE_NDIS_RESET_CMPLT. */ +typedef struct _rndis_reset_cmplt_struct +{ + uint32_t messageType; + uint32_t messageLength; + uint32_t status; + uint32_t addressingReset; +} rndis_reset_cmplt_struct_t; + +/*! @brief Define message structure for REMOTE_NDIS_INDICATE_STATUS_MSG. */ +typedef struct _rndis_indicate_status_msg_struct +{ + uint32_t messageType; + uint32_t messageLength; + uint32_t status; + uint32_t statusBufferLength; + uint32_t statusBufferOffset; +} rndis_indicate_status_msg_struct_t; + +/*! @brief Define message structure for REMOTE_NDIS_KEEPALIVE_MSG. */ +typedef struct _rndis_keepalive_msg_struct +{ + uint32_t messageType; + uint32_t messageLength; + uint32_t requestID; +} rndis_keepalive_msg_struct_t; + +/*! @brief Define message structure for REMOTE_NDIS_KEEPALIVE_CMPLT. */ +typedef struct _rndis_keepalive_cmplt_struct +{ + uint32_t messageType; + uint32_t messageLength; + uint32_t requestID; + uint32_t status; +} rndis_keepalive_cmplt_struct_t; + +/*! @brief Define message structure for RNDIS_PACKET_MSG. */ +typedef struct _rndis_packet_msg_struct +{ + uint32_t messageType; + uint32_t messageLength; + uint32_t dataOffset; + uint32_t dataLength; + uint32_t oobDataOffset; + uint32_t oobDataLength; + uint32_t numOOBDataElements; + uint32_t perPacketInfoOffset; + uint32_t perPacketInfoLength; + uint32_t vcHandle; + uint32_t reserved; +} rndis_packet_msg_struct_t; + +/*! @brief Define RNDIS device state. See MSDN for details. */ +typedef enum _rndis_state_enum +{ + /*! Following bus-level initialization, the device is said to be in the RNDIS-uninitialized state. + * If the device receives a REMOTE_NDIS_HALT_MSG, a bus-level disconnects, or a hard-reset + * at any time, it forces the device to the RNDIS-uninitialized state. + */ + RNDIS_UNINITIALIZED = 0, + /*! After the device receives a REMOTE_NDIS_INITIALIZE_MSG and responds with + * a REMOTE_NDIS_INITIALIZE_CMPLT with a status of RNDIS_STATUS_SUCCESS, the + * device enters the RNDIS-initialized state. + * If the device is in the RNDIS-data-initialized state when it receives a REMOTE_NDIS_SET_MSG + * specifying a zero filter value for OID_GEN_CURRENT_PACKET_FILTER, this event forces + * the device back to the RNDIS-initialized state. + */ + RNDIS_INITIALIZED, + /*! If the device receives a REMOTE_NDIS_SET_MSG that specifies a non-zero filter value + * for OID_GEN_CURRENT_PACKET_FILTER, the device enters the RNDIS-data-initialized state. + */ + RNDIS_DATA_INITIALIZED, +} rndis_state_enum_t; + +/*! @brief Define structure for CDC RNDIS device. */ +typedef struct _usb_device_cdc_rndis_struct +{ + class_handle_t cdcAcmHandle; /*!< USB CDC ACM class handle. */ + uint8_t *rndisCommand; /*!< The pointer to the buffer of the RNDIS request. */ + uint8_t *responseData; /*!< The pointer to the buffer of the RNDIS response. */ + uint32_t rndisHostMaxTxSize; /*!< The maximum transmit size in byte of the host. */ + uint32_t rndisDevMaxTxSize; /*!< The maximum transmit size in byte of the device. */ + uint32_t rndisHwState; /*!< The hardware state of the RNDIS device. */ + uint32_t rndisPacketFilter; /*!< The packet filter of the RNDIS device. */ + uint32_t rndisMediaConnectStatus; /*!< The media connection status of the RNDIS device. */ + uint32_t numFramesTxOk; /*!< The number of the frames sent successfully. */ + uint32_t numFramesRxOk; /*!< The number of the frames received successfully. */ + uint32_t numFramesTxError; /*!< The number of the frames sent failed. */ + uint32_t numFramesRxError; /*!< The number of the frames received failed. */ + uint32_t numRecvFramesMissed; /*!< The number of the frames missed to receive. */ + uint32_t numRecvFramesAlignmentError; /*!< The number of the frames received that has alignment error. */ + uint32_t numFramesTxOneCollision; /*!< The number of the frames sent that has one collision. */ + uint32_t numFramesTxManyCollision; /*!< The number of the frames sent that has many collision. */ + uint8_t rndisDeviceState; /*!< The RNDIS device state. */ + usb_osa_mutex_handle statusMutex; /*!< The mutex to guarantee the consistent access to the device state. */ + /*! The callback function provided by application for the RNDIS request. */ + usb_status_t (*rndisCallback)(class_handle_t handle, uint32_t event, void *param); +} usb_device_cdc_rndis_struct_t; + +/*! @brief Define structure for CDC RNDIS device. */ +typedef struct _usb_device_cdc_rndis_config_struct +{ + /*! The maximum transmit size in byte of the device. This value is configured by application. */ + uint32_t devMaxTxSize; + /*! The callback function provided by application for the RNDIS request. */ + usb_status_t (*rndisCallback)(class_handle_t handle, uint32_t event, void *param); +} usb_device_cdc_rndis_config_struct_t; + +/*! @brief Define parameters for CDC RNDIS request. */ +typedef struct _usb_device_cdc_rndis_request_param_struct +{ + uint8_t *buffer; /*!< The pointer to the buffer for RNDIS request. */ + uint32_t length; /*!< The length of the buffer for RNDIS request. */ +} usb_device_cdc_rndis_request_param_struct_t; + +/*! @brief Define RNDIS event. */ +typedef enum _rndis_event_enum +{ + kUSB_DeviceCdcEventAppGetLinkSpeed, /*!< This event indicates to get the link speed of the Ethernet. */ + kUSB_DeviceCdcEventAppGetSendPacketSize, /*!< This event indicates to get the USB send packet size. */ + kUSB_DeviceCdcEventAppGetRecvPacketSize, /*!< This event indicates to get the USB receive packet size. */ + kUSB_DeviceCdcEventAppGetMacAddress, /*!< This event indicates to get the mac address of the device. */ + kUSB_DeviceCdcEventAppGetLinkStatus, /*!< This event indicates to get the link status of the Ethernet. */ + kUSB_DeviceCdcEventAppGetMaxFrameSize /*!< This event indicates to get the Ethernet maximum frame size. */ +} rndis_event_enum_t; + +/******************************************************************************* +* API +******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name USB CDC ACM Class Driver + * @{ + */ +/*! + * @brief Initializes the USB CDC RNDIS device. + * + * This function sets the initial value for RNDIS device state, hardware state and media connection status, configures + * the maximum transmit size and the RNDIS request callback according to the user configuration structure. It also + * creates + * the mutex for accessing the device state. + * + * @param classHandle The class handle of the CDC ACM class. + * @param config The configure structure of the RNDIS device. + * @param handle This is a out parameter. It points to the address of the USB CDC RNDIS device handle. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Initialize the RNDIS device successfully. + * @retval kStatus_USB_Error Fails to allocate for the RNDIS device handle. + */ +extern usb_status_t USB_DeviceCdcRndisInit(class_handle_t classHandle, + usb_device_cdc_rndis_config_struct_t *config, + usb_device_cdc_rndis_struct_t **handle); + +/*! + * @brief Deinitializes the USB CDC RNDIS device. + * + * This function destroys the mutex of the device state and frees the RNDIS device handle. + * + * @param handle This is a pointer to the USB CDC RNDIS device handle. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success De-Initialize the RNDIS device successfully. + * @retval kStatus_USB_Error Fails to free the RNDIS device handle. + * @retval kStatus_USB_InvalidHandle The RNDIS device handle is invalid. + */ +extern usb_status_t USB_DeviceCdcRndisDeinit(usb_device_cdc_rndis_struct_t *handle); + +/*! + * @brief Responds to kUSB_DeviceCdcEventSendEncapsulatedCommand. + * + * This function checks the message length to see if it exceeds the maximum of the RNDIS request size and + * sets the device state or prepares notification for various message type accordingly. + * + * @param handle This is a pointer to the USB CDC RNDIS device handle. + * @param message This is a pointer to the address of the RNDIS request buffer. + * @param len This is a pointer to the variable of data size for the RNDIS request. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Responds to the host successfully. + * @retval kStatus_USB_Error The message length exceeds the maximum of the RNDIS request. + * @retval kStatus_USB_InvalidHandle The RNDIS device handle is invalid. + */ +extern usb_status_t USB_DeviceCdcRndisMessageSet(usb_device_cdc_rndis_struct_t *handle, + uint8_t **message, + uint32_t *len); + +/*! + * @brief Responds to kUSB_DeviceCdcEventGetEncapsulatedResponse. + * + * This function prepares the response for various message type which is stored in SendEncapsulatedCommand. + * + * @param handle This is a pointer to the USB CDC RNDIS device handle. + * @param message This is an out parameter. It is a pointer to the address of the RNDIS response buffer. + * @param len This is an out parameter. It is a pointer to the variable of data size for the RNDIS response. + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Prepares for the response to the host successfully. + * @retval kStatus_USB_InvalidRequest The message type is not supported. + * @retval kStatus_USB_InvalidHandle The RNDIS device handle is invalid. + */ +extern usb_status_t USB_DeviceCdcRndisMessageGet(usb_device_cdc_rndis_struct_t *handle, + uint8_t **message, + uint32_t *len); + +/*! +* @brief Soft reset the RNDIS device. +* +* This function is called to soft reset the RNDIS device. +* +* @param handle This is a pointer to the USB CDC RNDIS device handle. +* @param message This is an out parameter. It is a pointer to the address of the RNDIS response buffer. +* @param len This is an out parameter. It is a pointer to the variable of data size for the RNDIS response. +* @return A USB error code or kStatus_USB_Success. +* @retval kStatus_USB_Success Prepares for the response to the host successfully. +* @retval kStatus_USB_InvalidHandle The RNDIS device handle is invalid. +*/ +extern usb_status_t USB_DeviceCdcRndisResetCommand(usb_device_cdc_rndis_struct_t *handle, + uint8_t **message, + uint32_t *len); + +/*! +* @brief Halts the RNDIS device. +* +* This function is called to halt the RNDIS device. +* +* @param handle This is a pointer to the USB CDC RNDIS device handle. +* @return A USB error code or kStatus_USB_Success. +* @retval kStatus_USB_Success Halt the RNDIS device successfully. +* @retval kStatus_USB_InvalidHandle The RNDIS device handle is invalid. +*/ +extern usb_status_t USB_DeviceCdcRndisHaltCommand(usb_device_cdc_rndis_struct_t *handle); +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _USB_DEVICE_CDC_RNDIS_H_ */ diff --git a/usb/device/class/usb_device_class.c b/usb/device/class/usb_device_class.c new file mode 100644 index 0000000..9a7e797 --- /dev/null +++ b/usb/device/class/usb_device_class.c @@ -0,0 +1,552 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb_device_config.h" +#include "usb.h" + +#include "usb_device.h" +#include "usb_device_ch9.h" +#include "usb_device_class.h" + +#if ((defined(USB_DEVICE_CONFIG_NUM)) && (USB_DEVICE_CONFIG_NUM > 0U)) +/* Include the class drivers according to the usb_device_config.h. */ +#if ((defined(USB_DEVICE_CONFIG_HID)) && (USB_DEVICE_CONFIG_HID > 0U)) +#include "usb_device_hid.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_CDC_ACM)) && (USB_DEVICE_CONFIG_CDC_ACM > 0U)) +#include "usb_device_cdc_acm.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_MSC)) && (USB_DEVICE_CONFIG_MSC > 0U)) +#include "usb_device_msc.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_AUDIO)) && (USB_DEVICE_CONFIG_AUDIO > 0U)) +#include "usb_device_audio.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_PHDC)) && (USB_DEVICE_CONFIG_PHDC > 0U)) +#include "usb_device_phdc.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_VIDEO)) && (USB_DEVICE_CONFIG_VIDEO > 0U)) +#include "usb_device_video.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_PRINTER)) && (USB_DEVICE_CONFIG_PRINTER > 0U)) +#include "usb_device_printer.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_DFU)) && (USB_DEVICE_CONFIG_DFU > 0U)) +#include "usb_device_dfu.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_CCID)) && (USB_DEVICE_CONFIG_CCID > 0U)) +#include "usb_device_ccid.h" +#endif + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static usb_status_t USB_DeviceClassAllocateHandle(uint8_t controllerId, usb_device_common_class_struct_t **handle); +static usb_status_t USB_DeviceClassFreeHandle(uint8_t controllerId); +static usb_status_t USB_DeviceClassGetHandleByControllerId(uint8_t controllerId, + usb_device_common_class_struct_t **handle); +static usb_status_t USB_DeviceClassGetHandleByDeviceHandle(usb_device_handle deviceHandle, + usb_device_common_class_struct_t **handle); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* The device class driver list. */ +static const usb_device_class_map_t s_UsbDeviceClassInterfaceMap[] = { +#if ((defined(USB_DEVICE_CONFIG_HID)) && (USB_DEVICE_CONFIG_HID > 0U)) + {USB_DeviceHidInit, USB_DeviceHidDeinit, USB_DeviceHidEvent, kUSB_DeviceClassTypeHid}, +#endif + +#if ((defined(USB_DEVICE_CONFIG_CDC_ACM)) && (USB_DEVICE_CONFIG_CDC_ACM > 0U)) + {USB_DeviceCdcAcmInit, USB_DeviceCdcAcmDeinit, USB_DeviceCdcAcmEvent, kUSB_DeviceClassTypeCdc}, +#endif + +#if ((defined(USB_DEVICE_CONFIG_MSC)) && (USB_DEVICE_CONFIG_MSC > 0U)) + {USB_DeviceMscInit, USB_DeviceMscDeinit, USB_DeviceMscEvent, kUSB_DeviceClassTypeMsc}, +#endif + +#if ((defined USB_DEVICE_CONFIG_AUDIO) && (USB_DEVICE_CONFIG_AUDIO > 0U)) + {USB_DeviceAudioInit, USB_DeviceAudioDeinit, USB_DeviceAudioEvent, kUSB_DeviceClassTypeAudio}, +#endif + +#if ((defined USB_DEVICE_CONFIG_PHDC) && (USB_DEVICE_CONFIG_PHDC > 0U)) + {USB_DevicePhdcInit, USB_DevicePhdcDeinit, USB_DevicePhdcEvent, kUSB_DeviceClassTypePhdc}, +#endif + +#if ((defined USB_DEVICE_CONFIG_VIDEO) && (USB_DEVICE_CONFIG_VIDEO > 0U)) + {USB_DeviceVideoInit, USB_DeviceVideoDeinit, USB_DeviceVideoEvent, kUSB_DeviceClassTypeVideo}, +#endif + +#if ((defined USB_DEVICE_CONFIG_PRINTER) && (USB_DEVICE_CONFIG_PRINTER > 0U)) + {USB_DevicePrinterInit, USB_DevicePrinterDeinit, USB_DevicePrinterEvent, kUSB_DeviceClassTypePrinter}, +#endif + +#if ((defined USB_DEVICE_CONFIG_DFU) && (USB_DEVICE_CONFIG_DFU > 0U)) + {USB_DeviceDfuInit, USB_DeviceDfuDeinit, USB_DeviceDfuEvent, kUSB_DeviceClassTypeDfu}, +#endif + +#if ((defined USB_DEVICE_CONFIG_CCID) && (USB_DEVICE_CONFIG_CCID > 0U)) + {USB_DeviceCcidInit, USB_DeviceCcidDeinit, USB_DeviceCcidEvent, kUSB_DeviceClassTypeCcid}, +#endif + + {(usb_device_class_init_call_t)NULL, (usb_device_class_deinit_call_t)NULL, (usb_device_class_event_callback_t)NULL, + (usb_device_class_type_t)0}, +}; + +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_common_class_struct_t + s_UsbDeviceCommonClassStruct[USB_DEVICE_CONFIG_NUM]; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint8_t + s_UsbDeviceSetupBuffer[USB_DEVICE_CONFIG_NUM][USB_DATA_ALIGN_SIZE_MULTIPLE(USB_SETUP_PACKET_SIZE)]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Allocate a device common class handle. + * + * This function allocates a a device common class handle. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param handle It is out parameter, is used to return pointer of the device common class handle to the + * caller. + * + * @retval kStatus_USB_Success Get a device handle successfully. + * @retval kStatus_USB_Busy Cannot allocate a common class handle. + * @retval kStatus_USB_Error The common class has been initialized. + */ +static usb_status_t USB_DeviceClassAllocateHandle(uint8_t controllerId, usb_device_common_class_struct_t **handle) +{ + int32_t count; + USB_OSA_SR_ALLOC(); + + USB_OSA_ENTER_CRITICAL(); + /* Check the controller is initialized or not. */ + for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++) + { + if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) && + (controllerId == s_UsbDeviceCommonClassStruct[count].controllerId)) + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Error; + } + } + /* Get a free common class handle. */ + for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++) + { + if (NULL == s_UsbDeviceCommonClassStruct[count].handle) + { + s_UsbDeviceCommonClassStruct[count].controllerId = controllerId; + s_UsbDeviceCommonClassStruct[count].setupBuffer = s_UsbDeviceSetupBuffer[count]; + *handle = &s_UsbDeviceCommonClassStruct[count]; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + } + + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Busy; +} + +/*! + * @brief Free a device common class handle. + * + * This function frees a device common class handle. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The common class can not be found. + */ +static usb_status_t USB_DeviceClassFreeHandle(uint8_t controllerId) +{ + int32_t count = 0U; + USB_OSA_SR_ALLOC(); + + USB_OSA_ENTER_CRITICAL(); + for (; count < USB_DEVICE_CONFIG_NUM; count++) + { + if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) && + (controllerId == s_UsbDeviceCommonClassStruct[count].controllerId)) + { + s_UsbDeviceCommonClassStruct[count].handle = NULL; + s_UsbDeviceCommonClassStruct[count].configList = (usb_device_class_config_list_struct_t *)NULL; + s_UsbDeviceCommonClassStruct[count].controllerId = 0U; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + } + USB_OSA_EXIT_CRITICAL(); + + return kStatus_USB_InvalidParameter; +} + +/*! + * @brief Get the device common class handle according to the controller id. + * + * This function gets the device common class handle according to the controller id. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param handle It is out parameter, is used to return pointer of the device common class handle to the + * caller. + * + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The common class can not be found. + */ +static usb_status_t USB_DeviceClassGetHandleByControllerId(uint8_t controllerId, + usb_device_common_class_struct_t **handle) +{ + int32_t count = 0U; + USB_OSA_SR_ALLOC(); + + USB_OSA_ENTER_CRITICAL(); + for (; count < USB_DEVICE_CONFIG_NUM; count++) + { + if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) && + (controllerId == s_UsbDeviceCommonClassStruct[count].controllerId)) + { + *handle = &s_UsbDeviceCommonClassStruct[count]; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + } + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_InvalidParameter; +} + +/*! + * @brief Get the device common class handle according to the device handle. + * + * This function gets the device common class handle according to the device handle. + * + * @param deviceHandle The device handle, got from the USB_DeviceInit. + * @param handle It is out parameter, is used to return pointer of the device common class handle to the + * caller. + * + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The common class can not be found. + */ +static usb_status_t USB_DeviceClassGetHandleByDeviceHandle(usb_device_handle deviceHandle, + usb_device_common_class_struct_t **handle) +{ + int32_t count = 0U; + USB_OSA_SR_ALLOC(); + + USB_OSA_ENTER_CRITICAL(); + for (; count < USB_DEVICE_CONFIG_NUM; count++) + { + if (deviceHandle == s_UsbDeviceCommonClassStruct[count].handle) + { + *handle = &s_UsbDeviceCommonClassStruct[count]; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + } + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_InvalidParameter; +} + +/*! + * @brief Get the device handle according to the controller id. + * + * This function gets the device handle according to the controller id. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param handle It is out parameter, is used to return pointer of the device handle to the caller. + * + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The device handle not be found. + */ +usb_status_t USB_DeviceClassGetDeviceHandle(uint8_t controllerId, usb_device_handle *handle) +{ + int32_t count = 0U; + USB_OSA_SR_ALLOC(); + + USB_OSA_ENTER_CRITICAL(); + for (; count < USB_DEVICE_CONFIG_NUM; count++) + { + if ((NULL != s_UsbDeviceCommonClassStruct[count].handle) && + (controllerId == s_UsbDeviceCommonClassStruct[count].controllerId)) + { + *handle = s_UsbDeviceCommonClassStruct[count].handle; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + } + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_InvalidParameter; +} + +/*! + * @brief Handle the event passed to the class drivers. + * + * This function handles the event passed to the class drivers. + * + * @param handle The device handle, got from the USB_DeviceInit. + * @param event The event codes. Please refer to the enumeration usb_device_class_event_t. + * @param param The param type is determined by the event code. + * + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success A valid request has been handled. + * @retval kStatus_USB_InvalidParameter The device handle not be found. + * @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe will be stalled by the caller. + */ +usb_status_t USB_DeviceClassEvent(usb_device_handle handle, usb_device_class_event_t event, void *param) +{ + usb_device_common_class_struct_t *classHandle; + uint8_t mapIndex; + uint8_t classIndex; + usb_status_t errorReturn = kStatus_USB_Error; + usb_status_t error = kStatus_USB_Error; + + if (NULL == param) + { + return kStatus_USB_InvalidParameter; + } + + /* Get the common class handle according to the device handle. */ + errorReturn = USB_DeviceClassGetHandleByDeviceHandle(handle, &classHandle); + if (kStatus_USB_Success != errorReturn) + { + return kStatus_USB_InvalidParameter; + } + + for (classIndex = 0U; classIndex < classHandle->configList->count; classIndex++) + { + for (mapIndex = 0U; mapIndex < (sizeof(s_UsbDeviceClassInterfaceMap) / sizeof(usb_device_class_map_t)); + mapIndex++) + { + if (s_UsbDeviceClassInterfaceMap[mapIndex].type == + classHandle->configList->config[classIndex].classInfomation->type) + { + /* Call class event callback of supported class */ + errorReturn = s_UsbDeviceClassInterfaceMap[mapIndex].classEventCallback( + (void *)classHandle->configList->config[classIndex].classHandle, event, param); + /* Return the error code kStatus_USB_InvalidRequest immediately, when a class returns + * kStatus_USB_InvalidRequest. */ + if (kStatus_USB_InvalidRequest == errorReturn) + { + return kStatus_USB_InvalidRequest; + } + /* For composite device, it should return kStatus_USB_Success once a valid request has been handled */ + if (kStatus_USB_Success == errorReturn) + { + error = kStatus_USB_Success; + } + break; + } + } + } + + return error; +} + +/*! + * @brief Handle the common class callback. + * + * This function handles the common class callback. + * + * @param handle The device handle, got from the USB_DeviceInit. + * @param event The event codes. Please refer to the enumeration usb_device_event_t. + * @param param The param type is determined by the event code. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassCallback(usb_device_handle handle, uint32_t event, void *param) +{ + usb_device_common_class_struct_t *classHandle; + usb_status_t error = kStatus_USB_Error; + + /* Get the common class handle according to the device handle. */ + error = USB_DeviceClassGetHandleByDeviceHandle(handle, &classHandle); + if (kStatus_USB_Success != error) + { + return error; + } + + if (kUSB_DeviceEventBusReset == event) + { + /* Initialize the control pipes */ + USB_DeviceControlPipeInit(handle, classHandle); + + /* Notify the classes the USB bus reset signal detected. */ + USB_DeviceClassEvent(handle, kUSB_DeviceClassEventDeviceReset, classHandle); + } + + /* Call the application device callback function. deviceCallback is from the second parameter of + USB_DeviceClassInit */ + error = classHandle->configList->deviceCallback(handle, event, param); + return error; +} + +/*! + * @brief Initialize the common class and the supported classes. + * + * This function is used to initialize the common class and the supported classes. + * + * @param[in] controllerId The controller id of the USB IP. Please refer to the enumeration #usb_controller_index_t. + * @param[in] configList The class configurations. The pointer must point to the global variable. + * Please refer to the structure #usb_device_class_config_list_struct_t. + * @param[out] handle It is out parameter, is used to return pointer of the device handle to the caller. + * The value of parameter is a pointer points the device handle, and this design is used to + * make simple device align with composite device. For composite device, there are many + * kinds of class handle, but there is only one device handle. So the handle points to + * a device instead of a class. And the class handle can be got from the + * #usb_device_class_config_struct_t::classHandle after the function successfully. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassInit( + uint8_t controllerId, /*!< [IN] Controller ID */ + usb_device_class_config_list_struct_t *configList, /*!< [IN] Pointer to class configuration list */ + usb_device_handle *handle /*!< [OUT] Pointer to the device handle */ + ) +{ + usb_device_common_class_struct_t *classHandle; + usb_status_t error = kStatus_USB_Error; + uint8_t mapIndex; + uint8_t classIndex; + + if ((NULL == handle) || (NULL == configList) || ((usb_device_callback_t)NULL == configList->deviceCallback)) + { + return kStatus_USB_InvalidParameter; + } + + /* Allocate a common class driver handle. */ + error = USB_DeviceClassAllocateHandle(controllerId, &classHandle); + if (kStatus_USB_Success != error) + { + return error; + } + /* Save the configuration list */ + classHandle->configList = configList; + + /* Initialize the device stack. */ + error = USB_DeviceInit(controllerId, USB_DeviceClassCallback, &classHandle->handle); + + if (kStatus_USB_Success != error) + { + USB_DeviceDeinit(classHandle->handle); + USB_DeviceClassFreeHandle(controllerId); + return error; + } + + /* Initialize the all supported classes according to the configuration list. */ + for (classIndex = 0U; classIndex < classHandle->configList->count; classIndex++) + { + for (mapIndex = 0U; mapIndex < (sizeof(s_UsbDeviceClassInterfaceMap) / sizeof(usb_device_class_map_t)); + mapIndex++) + { + if (classHandle->configList->config[classIndex].classInfomation->type == + s_UsbDeviceClassInterfaceMap[mapIndex].type) + { + (void)s_UsbDeviceClassInterfaceMap[mapIndex].classInit( + controllerId, &classHandle->configList->config[classIndex], + &classHandle->configList->config[classIndex].classHandle); + } + } + } + + *handle = classHandle->handle; + return error; +} + +/*! + * @brief De-initialize the common class and the supported classes. + * + * This function is used to de-initialize the common class and the supported classes. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassDeinit(uint8_t controllerId /*!< [IN] Controller ID */ + ) +{ + usb_device_common_class_struct_t *classHandle; + usb_status_t error = kStatus_USB_Error; + uint8_t mapIndex; + uint8_t classIndex; + + /* Get the common class handle according to the controller id. */ + error = USB_DeviceClassGetHandleByControllerId(controllerId, &classHandle); + + if (kStatus_USB_Success != error) + { + return error; + } + + /* De-initialize the all supported classes according to the configuration list. */ + for (classIndex = 0U; classIndex < classHandle->configList->count; classIndex++) + { + for (mapIndex = 0U; mapIndex < (sizeof(s_UsbDeviceClassInterfaceMap) / sizeof(usb_device_class_map_t)); + mapIndex++) + { + if (classHandle->configList->config[classIndex].classInfomation->type == + s_UsbDeviceClassInterfaceMap[mapIndex].type) + { + (void)s_UsbDeviceClassInterfaceMap[mapIndex].classDeinit( + classHandle->configList->config[classIndex].classHandle); + } + } + } + + /* De-initialize the USB device stack. */ + error = USB_DeviceDeinit(classHandle->handle); + if (kStatus_USB_Success == error) + { + /* Free the common class handle. */ + (void)USB_DeviceClassFreeHandle(controllerId); + } + return error; +} + +/*! + * @brief Get the USB bus speed. + * + * This function is used to get the USB bus speed. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param speed It is an OUT parameter, return current speed of the controller. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassGetSpeed(uint8_t controllerId, /*!< [IN] Controller ID */ + uint8_t *speed /*!< [OUT] Current speed */ + ) +{ + usb_device_common_class_struct_t *classHandle; + usb_status_t error = kStatus_USB_Error; + + /* Get the common class handle according to the controller id. */ + error = USB_DeviceClassGetHandleByControllerId(controllerId, &classHandle); + + if (kStatus_USB_Success != error) + { + return error; + } + + /* Get the current speed. */ + error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusSpeed, speed); + + return error; +} +#endif /* USB_DEVICE_CONFIG_NUM */ diff --git a/usb/device/class/usb_device_class.h b/usb/device/class/usb_device_class.h new file mode 100644 index 0000000..5863474 --- /dev/null +++ b/usb/device/class/usb_device_class.h @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_CLASS_H__ +#define __USB_DEVICE_CLASS_H__ + +/*! + * @addtogroup usb_device_class_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Macro to define class handle */ +#define class_handle_t uint32_t + +/*! @brief Available class types. */ +typedef enum _usb_usb_device_class_type +{ + kUSB_DeviceClassTypeHid = 1U, + kUSB_DeviceClassTypeCdc, + kUSB_DeviceClassTypeMsc, + kUSB_DeviceClassTypeAudio, + kUSB_DeviceClassTypePhdc, + kUSB_DeviceClassTypeVideo, + kUSB_DeviceClassTypePrinter, + kUSB_DeviceClassTypeDfu, + kUSB_DeviceClassTypeCcid, +} usb_device_class_type_t; + +/*! @brief Available common class events. */ +typedef enum _usb_device_class_event +{ + kUSB_DeviceClassEventClassRequest = 1U, + kUSB_DeviceClassEventDeviceReset, + kUSB_DeviceClassEventSetConfiguration, + kUSB_DeviceClassEventSetInterface, + kUSB_DeviceClassEventSetEndpointHalt, + kUSB_DeviceClassEventClearEndpointHalt, +} usb_device_class_event_t; + +/*! + * @brief Obtains the endpoint data structure. + * + * Define the endpoint data structure. + * + */ +typedef struct _usb_device_endpoint_struct +{ + uint8_t endpointAddress; /*!< Endpoint address*/ + uint8_t transferType; /*!< Endpoint transfer type*/ + uint16_t maxPacketSize; /*!< Endpoint maximum packet size */ + uint8_t interval; /*!< Endpoint interval*/ +} usb_device_endpoint_struct_t; + +/*! +* @brief Obtains the endpoint group. +* +* Structure representing endpoints and the number of endpoints that the user wants. +* +*/ +typedef struct _usb_device_endpoint_list +{ + uint8_t count; /*!< How many endpoints in current interface*/ + usb_device_endpoint_struct_t *endpoint; /*!< Endpoint structure list*/ +} usb_device_endpoint_list_t; + +/*! + * @brief Obtains the interface list data structure. + * + * Structure representing an interface. + * + */ +typedef struct _usb_device_interface_struct +{ + uint8_t alternateSetting; /*!< Alternate setting number*/ + usb_device_endpoint_list_t endpointList; /*!< Endpoints of the interface*/ + void *classSpecific; /*!< Class specific structure handle*/ +} usb_device_interface_struct_t; + +/*! + * @brief Obtains the interface data structure. + * + * Structure representing interface. + * + */ +typedef struct _usb_device_interfaces_struct +{ + uint8_t classCode; /*!< Class code of the interface*/ + uint8_t subclassCode; /*!< Subclass code of the interface*/ + uint8_t protocolCode; /*!< Protocol code of the interface*/ + uint8_t interfaceNumber; /*!< Interface number*/ + usb_device_interface_struct_t *interface; /*!< Interface structure list*/ + uint8_t count; /*!< Number of interfaces in the current interface*/ +} usb_device_interfaces_struct_t; + +/*! + * @brief Obtains the interface group. + * + * Structure representing how many interfaces in one class type. + * + */ +typedef struct _usb_device_interface_list +{ + uint8_t count; /*!< Number of interfaces of the class*/ + usb_device_interfaces_struct_t *interfaces; /*!< All interfaces*/ +} usb_device_interface_list_t; + +/*! + * @brief Obtains the class data structure. + * + * Structure representing how many configurations in one class type. + * + */ +typedef struct _usb_device_class_struct +{ + usb_device_interface_list_t *interfaceList; /*!< Interfaces of the class*/ + usb_device_class_type_t type; /*!< Class type*/ + uint8_t configurations; /*!< Number of configurations of the class*/ +} usb_device_class_struct_t; + +/*callback function pointer structure for application to provide class parameters*/ +typedef usb_status_t (*usb_device_class_callback_t)(class_handle_t classHandle, + uint32_t callbackEvent, + void *eventParam); + +/*! + * @brief Obtains the device class information structure. + * + * Structure representing the device class information. This structure only can be stored in RAM space. + * + */ +typedef struct _usb_device_class_config_struct +{ + usb_device_class_callback_t classCallback; /*!< Class callback function to handle the device status-related event + for the specified type of class*/ + class_handle_t classHandle; /*!< The class handle of the class, filled by the common driver.*/ + usb_device_class_struct_t *classInfomation; /*!< Detailed information of the class*/ +} usb_device_class_config_struct_t; + +/*! + * @brief Obtains the device class configuration structure. + * + * Structure representing the device class configuration information. + * + */ +typedef struct _usb_device_class_config_list_struct +{ + usb_device_class_config_struct_t *config; /*!< Array of class configuration structures */ + usb_device_callback_t deviceCallback; /*!< Device callback function */ + uint8_t count; /*!< Number of class supported */ +} usb_device_class_config_list_struct_t; + +/*! + * @brief Obtains the control request structure. + * + * This structure is used to pass the control request information. + * The structure is used in following two cases. + * 1. Case one, the host wants to send data to the device in the control data stage: @n + * a. If a setup packet is received, the structure is used to pass the setup packet data and wants to get the + * buffer to receive data sent from the host. + * The field isSetup is 1. + * The length is the requested buffer length. + * The buffer is filled by the class or application by using the valid buffer address. + * The setup is the setup packet address. + * b. If the data received is sent by the host, the structure is used to pass the data buffer address and the + * data + * length sent by the host. + * In this way, the field isSetup is 0. + * The buffer is the address of the data sent from the host. + * The length is the received data length. + * The setup is the setup packet address. @n + * 2. Case two, the host wants to get data from the device in control data stage: @n + * If the setup packet is received, the structure is used to pass the setup packet data and wants to get the + * data buffer address to send data to the host. + * The field isSetup is 1. + * The length is the requested data length. + * The buffer is filled by the class or application by using the valid buffer address. + * The setup is the setup packet address. + * + */ +typedef struct _usb_device_control_request_struct +{ + usb_setup_struct_t *setup; /*!< The pointer of the setup packet data. */ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length or requested length. */ + uint8_t isSetup; /*!< Indicates whether a setup packet is received. */ +} usb_device_control_request_struct_t; + +/*! @brief Obtains the control get descriptor request common structure. */ +typedef struct _usb_device_get_descriptor_common_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ +} usb_device_get_descriptor_common_struct_t; + +/*! @brief Obtains the control get device descriptor request structure. */ +typedef struct _usb_device_get_device_descriptor_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ +} usb_device_get_device_descriptor_struct_t; + +/*! @brief Obtains the control get device qualifier descriptor request structure. */ +typedef struct _usb_device_get_device_qualifier_descriptor_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ +} usb_device_get_device_qualifier_descriptor_struct_t; + +/*! @brief Obtains the control get configuration descriptor request structure. */ +typedef struct _usb_device_get_configuration_descriptor_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ + uint8_t configuration; /*!< The configuration number. */ +} usb_device_get_configuration_descriptor_struct_t; + +/*! @brief Obtains the control get bos descriptor request structure. */ +typedef struct _usb_device_get_bos_descriptor_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ +} usb_device_get_bos_descriptor_struct_t; + +/*! @brief Obtains the control get string descriptor request structure. */ +typedef struct _usb_device_get_string_descriptor_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ + uint16_t languageId; /*!< Language ID. */ + uint8_t stringIndex; /*!< String index. */ +} usb_device_get_string_descriptor_struct_t; + +/*! @brief Obtains the control get HID descriptor request structure. */ +typedef struct _usb_device_get_hid_descriptor_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ + uint8_t interfaceNumber; /*!< The interface number. */ +} usb_device_get_hid_descriptor_struct_t; + +/*! @brief Obtains the control get HID report descriptor request structure. */ +typedef struct _usb_device_get_hid_report_descriptor_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ + uint8_t interfaceNumber; /*!< The interface number. */ +} usb_device_get_hid_report_descriptor_struct_t; + +/*! @brief Obtains the control get HID physical descriptor request structure. */ +typedef struct _usb_device_get_hid_physical_descriptor_struct +{ + uint8_t *buffer; /*!< Pass the buffer address. */ + uint32_t length; /*!< Pass the buffer length. */ + uint8_t index; /*!< Physical index */ + uint8_t interfaceNumber; /*!< The interface number. */ +} usb_device_get_hid_physical_descriptor_struct_t; + +/*! @brief Obtains the control get descriptor request common union. */ +typedef union _usb_device_get_descriptor_common_union +{ + usb_device_get_descriptor_common_struct_t commonDescriptor; /*!< Common structure. */ + usb_device_get_device_descriptor_struct_t deviceDescriptor; /*!< The structure to get device descriptor. */ + usb_device_get_device_qualifier_descriptor_struct_t + deviceQualifierDescriptor; /*!< The structure to get device qualifier descriptor. */ + usb_device_get_configuration_descriptor_struct_t + configurationDescriptor; /*!< The structure to get configuration descriptor. */ + usb_device_get_string_descriptor_struct_t stringDescriptor; /*!< The structure to get string descriptor. */ + usb_device_get_hid_descriptor_struct_t hidDescriptor; /*!< The structure to get HID descriptor. */ + usb_device_get_hid_report_descriptor_struct_t + hidReportDescriptor; /*!< The structure to get HID report descriptor. */ + usb_device_get_hid_physical_descriptor_struct_t + hidPhysicalDescriptor; /*!< The structure to get HID physical descriptor. */ +} usb_device_get_descriptor_common_union_t; + +/*! @brief Define function type for class device instance initialization */ +typedef usb_status_t (*usb_device_class_init_call_t)(uint8_t controllerId, + usb_device_class_config_struct_t *classConfig, + class_handle_t *classHandle); +/*! @brief Define function type for class device instance deinitialization, internal */ +typedef usb_status_t (*usb_device_class_deinit_call_t)(class_handle_t handle); +/*! @brief Define function type for class device instance Event change */ +typedef usb_status_t (*usb_device_class_event_callback_t)(void *classHandle, uint32_t event, void *param); + +/*! @brief Define class driver interface structure. */ +typedef struct _usb_device_class_map +{ + usb_device_class_init_call_t classInit; /*!< Class driver initialization- entry of the class driver */ + usb_device_class_deinit_call_t classDeinit; /*!< Class driver de-initialization*/ + usb_device_class_event_callback_t classEventCallback; /*!< Class driver event callback*/ + usb_device_class_type_t type; /*!< Class type*/ +} usb_device_class_map_t; + +/*! @brief Structure holding common class state information */ +typedef struct _usb_device_common_class_struct +{ + usb_device_handle handle; /*!< USB device handle*/ + usb_device_class_config_list_struct_t *configList; /*!< USB device configure list*/ + uint8_t *setupBuffer; /*!< Setup packet data buffer*/ + uint16_t standardTranscationBuffer; /*!< + * This variable is used in: + * get status request + * get configuration request + * get interface request + * set interface request + * get sync frame request + */ + uint8_t controllerId; /*!< Controller ID*/ +} usb_device_common_class_struct_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the common class and the supported classes. + * + * This function is used to initialize the common class and the supported classes. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t. + * @param[in] configList The class configurations. The pointer must point to the global variable. + * See the structure #usb_device_class_config_list_struct_t. + * @param[out] handle A parameter used to return pointer of the device handle to the caller. + * The value of the parameter is a pointer to the device handle. This design is used to + * make a simple device align with the composite device. For the composite device, there are + * many + * kinds of class handles. However, there is only one device handle. Therefore, the handle + * points to + * a device instead of a class. The class handle can be received from the + * #usb_device_class_config_struct_t::classHandle after the function successfully. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassInit(uint8_t controllerId, + usb_device_class_config_list_struct_t *configList, + usb_device_handle *handle); + +/*! + * @brief Deinitializes the common class and the supported classes. + * + * This function is used to deinitialize the common class and the supported classes. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassDeinit(uint8_t controllerId); + +/*! + * @brief Gets the USB bus speed. + * + * This function is used to get the USB bus speed. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t. + * @param[out] speed It is an OUT parameter, which returns the current speed of the controller. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassGetSpeed(uint8_t controllerId, uint8_t *speed); + +/*! + * @brief Handles the event passed to the class drivers. + * + * This function handles the event passed to the class drivers. + * + * @param[in] handle The device handle received from the #USB_DeviceInit. + * @param[in] event The event codes. See the enumeration #usb_device_class_event_t. + * @param[in,out] param The parameter type is determined by the event code. + * + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success A valid request has been handled. + * @retval kStatus_USB_InvalidParameter The device handle not be found. + * @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe is stalled by the caller. + */ +usb_status_t USB_DeviceClassEvent(usb_device_handle handle, usb_device_class_event_t event, void *param); + +/*! + * @brief Handles the common class callback. + * + * This function handles the common class callback. + * + * @param[in] handle The device handle received from the #USB_DeviceInit. + * @param[in] event The event codes. See the enumeration #usb_device_event_t. + * @param[in,out] param The parameter type is determined by the event code. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceClassCallback(usb_device_handle handle, uint32_t event, void *param); + +/*! + * @brief Gets the device handle according to the controller ID. + * + * This function gets the device handle according to the controller ID. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t. + * @param[out] handle An out parameter used to return the pointer of the device handle to the caller. + * + * @retval kStatus_USB_Success Get device handle successfully. + * @retval kStatus_USB_InvalidParameter The device handle can't be found. + */ +usb_status_t USB_DeviceClassGetDeviceHandle(uint8_t controllerId, usb_device_handle *handle); + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __USB_DEVICE_CLASS_H__ */ diff --git a/usb/device/class/usb_device_hid.c b/usb/device/class/usb_device_hid.c new file mode 100644 index 0000000..81547cb --- /dev/null +++ b/usb/device/class/usb_device_hid.c @@ -0,0 +1,745 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device.h" + +#include "usb_device_class.h" + +#if ((defined(USB_DEVICE_CONFIG_HID)) && (USB_DEVICE_CONFIG_HID > 0U)) +#include "usb_device_hid.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +static usb_status_t USB_DeviceHidAllocateHandle(usb_device_hid_struct_t **handle); +static usb_status_t USB_DeviceHidFreeHandle(usb_device_hid_struct_t *handle); +static usb_status_t USB_DeviceHidInterruptIn(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam); +static usb_status_t USB_DeviceHidInterruptOut(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam); +static usb_status_t USB_DeviceHidEndpointsInit(usb_device_hid_struct_t *hidHandle); +static usb_status_t USB_DeviceHidEndpointsDeinit(usb_device_hid_struct_t *hidHandle); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_hid_struct_t + s_UsbDeviceHidHandle[USB_DEVICE_CONFIG_HID]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Allocate a device hid class handle. + * + * This function allocates a device hid class handle. + * + * @param handle It is out parameter, is used to return pointer of the device hid class handle to the caller. + * + * @retval kStatus_USB_Success Get a device hid class handle successfully. + * @retval kStatus_USB_Busy Cannot allocate a device hid class handle. + */ +static usb_status_t USB_DeviceHidAllocateHandle(usb_device_hid_struct_t **handle) +{ + int32_t count; + for (count = 0U; count < USB_DEVICE_CONFIG_HID; count++) + { + if (NULL == s_UsbDeviceHidHandle[count].handle) + { + *handle = &s_UsbDeviceHidHandle[count]; + return kStatus_USB_Success; + } + } + + return kStatus_USB_Busy; +} + +/*! + * @brief Free a device hid class handle. + * + * This function frees a device hid class handle. + * + * @param handle The device hid class handle. + * + * @retval kStatus_USB_Success Free device hid class handle successfully. + */ +static usb_status_t USB_DeviceHidFreeHandle(usb_device_hid_struct_t *handle) +{ + handle->handle = NULL; + handle->configStruct = (usb_device_class_config_struct_t *)NULL; + handle->configuration = 0U; + handle->alternate = 0U; + return kStatus_USB_Success; +} + +/*! + * @brief Interrupt IN endpoint callback function. + * + * This callback function is used to notify uplayer the transfser result of a transfer. + * This callback pointer is passed when the interrupt IN pipe initialized. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The result of the interrupt IN pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the HID class handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceHidInterruptIn(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_hid_struct_t *hidHandle; + usb_status_t error = kStatus_USB_Error; + + /* Get the HID class handle */ + hidHandle = (usb_device_hid_struct_t *)callbackParam; + + if (!hidHandle) + { + return kStatus_USB_InvalidHandle; + } + hidHandle->interruptInPipeBusy = 0U; + if ((NULL != hidHandle->configStruct) && (hidHandle->configStruct->classCallback)) + { + /* Notify the application data sent by calling the hid class callback. classCallback is initialized + in classInit of s_UsbDeviceClassInterfaceMap,it is from the second parameter of classInit */ + error = + hidHandle->configStruct->classCallback((class_handle_t)hidHandle, kUSB_DeviceHidEventSendResponse, message); + } + + return error; +} + +/*! + * @brief Interrupt OUT endpoint callback function. + * + * This callback function is used to notify uplayer the transfser result of a transfer. + * This callback pointer is passed when the interrupt OUT pipe initialized. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The result of the interrupt OUT pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the HID class handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceHidInterruptOut(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_hid_struct_t *hidHandle; + usb_status_t error = kStatus_USB_Error; + + /* Get the HID class handle */ + hidHandle = (usb_device_hid_struct_t *)callbackParam; + + if (!hidHandle) + { + return kStatus_USB_InvalidHandle; + } + hidHandle->interruptOutPipeBusy = 0U; + if ((NULL != hidHandle->configStruct) && (hidHandle->configStruct->classCallback)) + { + /* Notify the application data sent by calling the hid class callback. classCallback is initialized + in classInit of s_UsbDeviceClassInterfaceMap,it is from the second parameter of classInit */ + error = + hidHandle->configStruct->classCallback((class_handle_t)hidHandle, kUSB_DeviceHidEventRecvResponse, message); + } + + return error; +} + +/*! + * @brief Initialize the endpoints of the hid class. + * + * This callback function is used to initialize the endpoints of the hid class. + * + * @param hidHandle The device hid class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceHidEndpointsInit(usb_device_hid_struct_t *hidHandle) +{ + usb_device_interface_list_t *interfaceList; + usb_device_interface_struct_t *interface = (usb_device_interface_struct_t *)NULL; + usb_status_t error = kStatus_USB_Error; + + /* Check the configuration is valid or not. */ + if (!hidHandle->configuration) + { + return error; + } + + if (hidHandle->configuration > hidHandle->configStruct->classInfomation->configurations) + { + return error; + } + + /* Get the interface list of the new configuration. */ + if (NULL == hidHandle->configStruct->classInfomation->interfaceList) + { + return error; + } + interfaceList = &hidHandle->configStruct->classInfomation->interfaceList[hidHandle->configuration - 1U]; + + /* Find interface by using the alternate setting of the interface. */ + for (int count = 0U; count < interfaceList->count; count++) + { + if (USB_DEVICE_CONFIG_HID_CLASS_CODE == interfaceList->interfaces[count].classCode) + { + for (int index = 0U; index < interfaceList->interfaces[count].count; index++) + { + if (interfaceList->interfaces[count].interface[index].alternateSetting == hidHandle->alternate) + { + interface = &interfaceList->interfaces[count].interface[index]; + break; + } + } + hidHandle->interfaceNumber = interfaceList->interfaces[count].interfaceNumber; + break; + } + } + if (!interface) + { + /* Return error if the interface is not found. */ + return error; + } + + /* Keep new interface handle. */ + hidHandle->interfaceHandle = interface; + + /* Initialize the endpoints of the new interface. */ + for (int count = 0U; count < interface->endpointList.count; count++) + { + usb_device_endpoint_init_struct_t epInitStruct; + usb_device_endpoint_callback_struct_t epCallback; + epInitStruct.zlt = 0U; + epInitStruct.interval = interface->endpointList.endpoint[count].interval; + epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress; + epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize; + epInitStruct.transferType = interface->endpointList.endpoint[count].transferType; + + if (USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) + { + epCallback.callbackFn = USB_DeviceHidInterruptIn; + hidHandle->interruptInPipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + hidHandle->interruptInPipeStall = 0U; + hidHandle->interruptInPipeDataLen = 0U; + } + else + { + epCallback.callbackFn = USB_DeviceHidInterruptOut; + hidHandle->interruptOutPipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + hidHandle->interruptOutPipeStall = 0U; + hidHandle->interruptOutPipeDataLen = 0U; + } + epCallback.callbackParam = hidHandle; + + error = USB_DeviceInitEndpoint(hidHandle->handle, &epInitStruct, &epCallback); + } + return error; +} + +/*! + * @brief De-initialize the endpoints of the hid class. + * + * This callback function is used to de-initialize the endpoints of the hid class. + * + * @param hidHandle The device hid class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceHidEndpointsDeinit(usb_device_hid_struct_t *hidHandle) +{ + usb_status_t error = kStatus_USB_Error; + + if (!hidHandle->interfaceHandle) + { + return error; + } + /* De-initialize all endpoints of the interface */ + for (int count = 0U; count < hidHandle->interfaceHandle->endpointList.count; count++) + { + error = USB_DeviceDeinitEndpoint(hidHandle->handle, + hidHandle->interfaceHandle->endpointList.endpoint[count].endpointAddress); + } + hidHandle->interfaceHandle = NULL; + return error; +} + +/*! + * @brief Handle the event passed to the hid class. + * + * This function handles the event passed to the hid class. + * + * @param handle The hid class handle, got from the usb_device_class_config_struct_t::classHandle. + * @param event The event codes. Please refer to the enumeration usb_device_class_event_t. + * @param param The param type is determined by the event code. + * + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The device handle not be found. + * @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe will be stalled by the caller. + */ +usb_status_t USB_DeviceHidEvent(void *handle, uint32_t event, void *param) +{ + usb_device_hid_struct_t *hidHandle; + usb_device_hid_report_struct_t report; + usb_status_t error = kStatus_USB_Error; + uint16_t interfaceAlternate; + uint8_t *temp8; + uint8_t alternate; + + if ((!param) || (!handle)) + { + return kStatus_USB_InvalidHandle; + } + + /* Get the hid class handle. */ + hidHandle = (usb_device_hid_struct_t *)handle; + + switch (event) + { + case kUSB_DeviceClassEventDeviceReset: + /* Bus reset, clear the configuration. */ + hidHandle->configuration = 0U; + hidHandle->interruptInPipeBusy = 0U; + hidHandle->interruptOutPipeBusy = 0U; + hidHandle->interfaceHandle = NULL; + break; + case kUSB_DeviceClassEventSetConfiguration: + /* Get the new configuration. */ + temp8 = ((uint8_t *)param); + if (!hidHandle->configStruct) + { + break; + } + if (*temp8 == hidHandle->configuration) + { + break; + } + + /* De-initialize the endpoints when current configuration is none zero. */ + if (hidHandle->configuration) + { + error = USB_DeviceHidEndpointsDeinit(hidHandle); + } + /* Save new configuration. */ + hidHandle->configuration = *temp8; + /* Clear the alternate setting value. */ + hidHandle->alternate = 0U; + + /* Initialize the endpoints of the new current configuration by using the alternate setting 0. */ + error = USB_DeviceHidEndpointsInit(hidHandle); + break; + case kUSB_DeviceClassEventSetInterface: + if (!hidHandle->configStruct) + { + break; + } + /* Get the new alternate setting of the interface */ + interfaceAlternate = *((uint16_t *)param); + /* Get the alternate setting value */ + alternate = (uint8_t)(interfaceAlternate & 0xFFU); + + /* Whether the interface belongs to the class. */ + if (hidHandle->interfaceNumber != ((uint8_t)(interfaceAlternate >> 8U))) + { + break; + } + /* Only handle new alternate setting. */ + if (alternate == hidHandle->alternate) + { + break; + } + /* De-initialize old endpoints */ + error = USB_DeviceHidEndpointsDeinit(hidHandle); + hidHandle->alternate = alternate; + /* Initialize new endpoints */ + error = USB_DeviceHidEndpointsInit(hidHandle); + break; + case kUSB_DeviceClassEventSetEndpointHalt: + if ((!hidHandle->configStruct) || (!hidHandle->interfaceHandle)) + { + break; + } + /* Get the endpoint address */ + temp8 = ((uint8_t *)param); + for (int count = 0U; count < hidHandle->interfaceHandle->endpointList.count; count++) + { + if (*temp8 == hidHandle->interfaceHandle->endpointList.endpoint[count].endpointAddress) + { + /* Only stall the endpoint belongs to the class */ + if (USB_IN == ((hidHandle->interfaceHandle->endpointList.endpoint[count].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) + { + hidHandle->interruptInPipeStall = 1U; + } + else + { + hidHandle->interruptOutPipeStall = 1U; + } + error = USB_DeviceStallEndpoint(hidHandle->handle, *temp8); + } + } + break; + case kUSB_DeviceClassEventClearEndpointHalt: + if ((!hidHandle->configStruct) || (!hidHandle->interfaceHandle)) + { + break; + } + /* Get the endpoint address */ + temp8 = ((uint8_t *)param); + for (int count = 0U; count < hidHandle->interfaceHandle->endpointList.count; count++) + { + if (*temp8 == hidHandle->interfaceHandle->endpointList.endpoint[count].endpointAddress) + { + /* Only un-stall the endpoint belongs to the class */ + error = USB_DeviceUnstallEndpoint(hidHandle->handle, *temp8); + if (USB_IN == (((*temp8) & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) + { + if (hidHandle->interruptInPipeStall) + { + hidHandle->interruptInPipeStall = 0U; + if ((uint8_t*)USB_UNINITIALIZED_VAL_32 != hidHandle->interruptInPipeDataBuffer) + { + error = USB_DeviceSendRequest(hidHandle->handle, (hidHandle->interfaceHandle->endpointList.endpoint[count].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK), + hidHandle->interruptInPipeDataBuffer, hidHandle->interruptInPipeDataLen); + if (kStatus_USB_Success != error) + { + usb_device_endpoint_callback_message_struct_t endpointCallbackMessage; + endpointCallbackMessage.buffer = hidHandle->interruptInPipeDataBuffer; + endpointCallbackMessage.length = hidHandle->interruptInPipeDataLen; + endpointCallbackMessage.isSetup = 0U; + USB_DeviceHidInterruptIn(hidHandle->handle,(void*)&endpointCallbackMessage, handle); + } + hidHandle->interruptInPipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + hidHandle->interruptInPipeDataLen = 0U; + } + } + } + else + { + if (hidHandle->interruptOutPipeStall) + { + hidHandle->interruptOutPipeStall = 0U; + if ((uint8_t*)USB_UNINITIALIZED_VAL_32 != hidHandle->interruptOutPipeDataBuffer) + { + error = USB_DeviceRecvRequest(hidHandle->handle, (hidHandle->interfaceHandle->endpointList.endpoint[count].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK), + hidHandle->interruptOutPipeDataBuffer, hidHandle->interruptOutPipeDataLen); + if (kStatus_USB_Success != error) + { + usb_device_endpoint_callback_message_struct_t endpointCallbackMessage; + endpointCallbackMessage.buffer = hidHandle->interruptOutPipeDataBuffer; + endpointCallbackMessage.length = hidHandle->interruptOutPipeDataLen; + endpointCallbackMessage.isSetup = 0U; + USB_DeviceHidInterruptOut(hidHandle->handle, (void*)&endpointCallbackMessage, handle); + } + hidHandle->interruptOutPipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32;; + hidHandle->interruptOutPipeDataLen = 0U; + } + } + } + } + } + break; + case kUSB_DeviceClassEventClassRequest: + if (param) + { + /* Handle the hid class specific request. */ + usb_device_control_request_struct_t *controlRequest = (usb_device_control_request_struct_t *)param; + + if ((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != + USB_REQUEST_TYPE_RECIPIENT_INTERFACE) + { + break; + } + + if ((controlRequest->setup->wIndex & 0xFFU) != hidHandle->interfaceNumber) + { + break; + } + + switch (controlRequest->setup->bRequest) + { + case USB_DEVICE_HID_REQUEST_GET_REPORT: + /* Get report request */ + report.reportType = (controlRequest->setup->wValue & 0xFF00U) >> 0x08U; + report.reportId = (controlRequest->setup->wValue & 0x00FFU); + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = hidHandle->configStruct->classCallback((class_handle_t)hidHandle, + kUSB_DeviceHidEventGetReport, &report); + controlRequest->buffer = report.reportBuffer; + controlRequest->length = report.reportLength; + break; + case USB_DEVICE_HID_REQUEST_GET_IDLE: + /* Get idle request, classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = hidHandle->configStruct->classCallback( + (class_handle_t)hidHandle, kUSB_DeviceHidEventGetIdle, &hidHandle->idleRate); + controlRequest->buffer = &hidHandle->idleRate; + break; + case USB_DEVICE_HID_REQUEST_GET_PROTOCOL: + /* Get protocol request, classCallback is initialized in classInit of + s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = hidHandle->configStruct->classCallback( + (class_handle_t)hidHandle, kUSB_DeviceHidEventGetIdle, &hidHandle->protocol); + controlRequest->buffer = &hidHandle->protocol; + break; + case USB_DEVICE_HID_REQUEST_SET_REPORT: + /* Set report request */ + report.reportType = (controlRequest->setup->wValue & 0xFF00U) >> 0x08U; + report.reportId = (controlRequest->setup->wValue & 0x00FFU); + if (controlRequest->isSetup) + { + report.reportLength = controlRequest->length; + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = hidHandle->configStruct->classCallback( + (class_handle_t)hidHandle, kUSB_DeviceHidEventRequestReportBuffer, &report); + controlRequest->buffer = report.reportBuffer; + controlRequest->length = report.reportLength; + } + else + { + report.reportBuffer = controlRequest->buffer; + report.reportLength = controlRequest->length; + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = hidHandle->configStruct->classCallback((class_handle_t)hidHandle, + kUSB_DeviceHidEventSetReport, &report); + } + break; + case USB_DEVICE_HID_REQUEST_SET_IDLE: + /* Set idle request */ + { + hidHandle->idleRate = (controlRequest->setup->wValue & 0xFF00U) >> 0x08U; + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = hidHandle->configStruct->classCallback( + (class_handle_t)hidHandle, kUSB_DeviceHidEventSetIdle, &hidHandle->idleRate); + } + break; + case USB_DEVICE_HID_REQUEST_SET_PROTOCOL: + /* Set protocol request */ + { + hidHandle->protocol = (controlRequest->setup->wValue & 0x00FFU); + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = hidHandle->configStruct->classCallback( + (class_handle_t)hidHandle, kUSB_DeviceHidEventSetProtocol, &hidHandle->protocol); + } + break; + default: + error = kStatus_USB_InvalidRequest; + break; + } + } + break; + default: + break; + } + return error; +} + +/*! + * @brief Initialize the hid class. + * + * This function is used to initialize the hid class. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param config The class configuration information. + * @param handle It is out parameter, is used to return pointer of the hid class handle to the caller. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceHidInit(uint8_t controllerId, usb_device_class_config_struct_t *config, class_handle_t *handle) +{ + usb_device_hid_struct_t *hidHandle; + usb_status_t error = kStatus_USB_Error; + + /* Allocate a hid class handle. */ + error = USB_DeviceHidAllocateHandle(&hidHandle); + + if (kStatus_USB_Success != error) + { + return error; + } + + /* Get the device handle according to the controller id. */ + error = USB_DeviceClassGetDeviceHandle(controllerId, &hidHandle->handle); + + if (kStatus_USB_Success != error) + { + return error; + } + + if (!hidHandle->handle) + { + return kStatus_USB_InvalidHandle; + } + /* Save the configuration of the class. */ + hidHandle->configStruct = config; + /* Clear the configuration value. */ + hidHandle->configuration = 0U; + hidHandle->alternate = 0xffU; + + *handle = (class_handle_t)hidHandle; + return error; +} + +/*! + * @brief De-initialize the device hid class. + * + * The function de-initializes the device hid class. + * + * @param handle The hid class handle got from usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceHidDeinit(class_handle_t handle) +{ + usb_device_hid_struct_t *hidHandle; + usb_status_t error = kStatus_USB_Error; + + hidHandle = (usb_device_hid_struct_t *)handle; + + if (!hidHandle) + { + return kStatus_USB_InvalidHandle; + } + /* De-initialzie the endpoints. */ + error = USB_DeviceHidEndpointsDeinit(hidHandle); + /* Free the hid class handle. */ + USB_DeviceHidFreeHandle(hidHandle); + return error; +} + +/*! + * @brief Send data through a specified endpoint. + * + * The function is used to send data through a specified endpoint. + * The function calls USB_DeviceSendRequest internally. + * + * @param handle The hid class handle got from usb_device_class_config_struct_t::classHandle. + * @param ep Endpoint index. + * @param buffer The memory address to hold the data need to be sent. + * @param length The data length need to be sent. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value just means if the sending request is successful or not; the transfer done is notified by + * USB_DeviceHidInterruptIn. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceHidSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length) +{ + usb_device_hid_struct_t *hidHandle; + usb_status_t error = kStatus_USB_Error; + + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + hidHandle = (usb_device_hid_struct_t *)handle; + + if (hidHandle->interruptInPipeBusy) + { + return kStatus_USB_Busy; + } + hidHandle->interruptInPipeBusy = 1U; + + if (hidHandle->interruptInPipeStall) + { + hidHandle->interruptInPipeDataBuffer = buffer; + hidHandle->interruptInPipeDataLen = length; + return kStatus_USB_Success; + } + error = USB_DeviceSendRequest(hidHandle->handle, ep, buffer, length); + if (kStatus_USB_Success != error) + { + hidHandle->interruptInPipeBusy = 0U; + } + return error; +} + +/*! + * @brief Receive data through a specified endpoint. + * + * The function is used to receive data through a specified endpoint. + * The function calls USB_DeviceRecvRequest internally. + * + * @param handle The hid class handle got from usb_device_class_config_struct_t::classHandle. + * @param ep Endpoint index. + * @param buffer The memory address to save the received data. + * @param length The data length want to be received. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value just means if the receiving request is successful or not; the transfer done is notified by + * USB_DeviceHidInterruptOut. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceHidRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length) +{ + usb_device_hid_struct_t *hidHandle; + usb_status_t error = kStatus_USB_Error; + + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + hidHandle = (usb_device_hid_struct_t *)handle; + + if (hidHandle->interruptOutPipeBusy) + { + return kStatus_USB_Busy; + } + hidHandle->interruptOutPipeBusy = 1U; + + if (hidHandle->interruptOutPipeStall) + { + hidHandle->interruptOutPipeDataBuffer = buffer; + hidHandle->interruptOutPipeDataLen = length; + return kStatus_USB_Success; + } + error = USB_DeviceRecvRequest(hidHandle->handle, ep, buffer, length); + if (kStatus_USB_Success != error) + { + hidHandle->interruptOutPipeBusy = 0U; + } + return error; +} + +#endif diff --git a/usb/device/class/usb_device_hid.h b/usb/device/class/usb_device_hid.h new file mode 100644 index 0000000..8aad940 --- /dev/null +++ b/usb/device/class/usb_device_hid.h @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_HID_H__ +#define __USB_DEVICE_HID_H__ + +/*! + * @addtogroup usb_device_hid_drv + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief The class code of the HID class */ +#define USB_DEVICE_CONFIG_HID_CLASS_CODE (0x03U) + +/*! @brief Request code to get report of HID class. */ +#define USB_DEVICE_HID_REQUEST_GET_REPORT (0x01U) +#define USB_DEVICE_HID_REQUEST_GET_REPORT_TYPE_INPUT (0x01U) +#define USB_DEVICE_HID_REQUEST_GET_REPORT_TYPE_OUPUT (0x02U) +#define USB_DEVICE_HID_REQUEST_GET_REPORT_TYPE_FEATURE (0x03U) +/*! @brief Request code to get idle of HID class. */ +#define USB_DEVICE_HID_REQUEST_GET_IDLE (0x02U) +/*! @brief Request code to get protocol of HID class. */ +#define USB_DEVICE_HID_REQUEST_GET_PROTOCOL (0x03U) +/*! @brief Request code to set report of HID class. */ +#define USB_DEVICE_HID_REQUEST_SET_REPORT (0x09U) +/*! @brief Request code to set idle of HID class. */ +#define USB_DEVICE_HID_REQUEST_SET_IDLE (0x0AU) +/*! @brief Request code to set protocol of HID class. */ +#define USB_DEVICE_HID_REQUEST_SET_PROTOCOL (0x0BU) + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) +/*! @brief The sequence initiation time for the dcd module. */ +#define USB_DEVICE_DCD_SEQ_INIT_TIME (1000U) +/*! @brief The time period to debounce on DP signal. */ +#define USB_DEVICE_DCD_DBNC_MSEC (10U) +/*! @brief The time period comparator enabled. */ +#define USB_DEVICE_DCD_VDPSRC_ON_MSEC (200U) +/*! @brief The amount of time that the module waits after primary detection before start to secondary detection. */ +#define USB_DEVICE_DCD_TIME_WAIT_AFTER_PRI_DETECTION (40U) +/*! @brief The amount of time the module enable the Vdm_src. */ +#define USB_DEVICE_DCD_TIME_DM_SRC_ON (10U) + +/*! @brief USB DCD charging port type */ +typedef enum _usb_device_dcd_port_type +{ + kUSB_DeviceDCDPortTypeNoPort = 0x0U, + kUSB_DeviceDCDPortTypeSDP, + kUSB_DeviceDCDPortTypeCDP, + kUSB_DeviceDCDPortTypeDCP, +} usb_device_dcd_port_type_t; + +/*! @brief USB DCD charging detect status */ +typedef enum _usb_device_dcd_dev_status +{ + kUSB_DeviceDCDDevStatusVBUSDetect = 0x0U, + kUSB_DeviceDCDDevStatusDataContactDetect, + kUSB_DeviceDCDDevStatusChargingPortDetect, + kUSB_DeviceDCDDevStatusTimeOut, + kUSB_DeviceDCDDevStatusUnknownType, + kUSB_DeviceDCDDevStatusDetectFinish, + kUSB_DeviceDCDDevStatusComplete, + kUSB_DeviceDCDDevStatusAttached, + kUSB_DeviceDCDDevStatusDetached, +} usb_device_dcd_dev_status_t; +#endif + +/*! @brief Available common EVENT types in HID class callback */ +typedef enum _usb_device_hid_event +{ + kUSB_DeviceHidEventSendResponse = 0x01U, /*!< Send data completed or cancelled etc*/ + kUSB_DeviceHidEventRecvResponse, /*!< Data received or cancelled etc*/ + kUSB_DeviceHidEventGetReport, /*!< Get report request */ + kUSB_DeviceHidEventGetIdle, /*!< Get idle request */ + kUSB_DeviceHidEventGetProtocol, /*!< Get protocol request */ + kUSB_DeviceHidEventSetReport, /*!< Set report request */ + kUSB_DeviceHidEventSetIdle, /*!< Set idle request */ + kUSB_DeviceHidEventSetProtocol, /*!< Set protocol request */ + kUSB_DeviceHidEventRequestReportBuffer, /*!< Get buffer to save the data of the set report request. */ +} usb_device_hid_event_t; + +/*! + * @brief The device HID GET/SET report structure. + * + * This structure is used to pass data when the event type is kUSB_DeviceHidEventGetReport, + * kUSB_DeviceHidEventSetReport, and kUSB_DeviceHidEventRequestReportBuffer. + * 1. kUSB_DeviceHidEventGetReport + * The structure is used to save the report buffer and report length got from the application. + * The reportBuffer is the report data buffer address filled by the application. + * The reportLength is the report length. + * The reportType is the requested report type. + * The reportId is the requested report ID. + * + * 2. kUSB_DeviceHidEventSetReport + * The structure is used to pass the report data received from the host to the application. + * The reportBuffer is buffer address of the report data received from the host. + * The reportLength is the report data length. + * The reportType is the requested report type. + * The reportId is the requested report ID. + * + * 3. kUSB_DeviceHidEventRequestReportBuffer + * The structure is used to get the buffer to save the report data sent by the host. + * The reportBuffer is buffer address to receive to report data. It is filled by the application. + * The reportLength is the requested report data buffer length. + * The reportType is the requested report type. + * The reportId is the requested report ID. + */ +typedef struct _usb_device_hid_report_struct +{ + uint8_t *reportBuffer; /*!< The report buffer address */ + uint32_t reportLength; /*!< The report data length */ + uint8_t reportType; /*!< The report type */ + uint8_t reportId; /*!< The report ID */ +} usb_device_hid_report_struct_t; + +/*! @brief The HID device class status structure */ +typedef struct _usb_device_hid_struct +{ + usb_device_handle handle; /*!< The device handle */ + usb_device_class_config_struct_t *configStruct; /*!< The configuration of the class. */ + usb_device_interface_struct_t *interfaceHandle; /*!< Current interface handle */ + uint8_t *interruptInPipeDataBuffer; /*!< IN pipe data buffer backup when stall */ + uint32_t interruptInPipeDataLen; /*!< IN pipe data length backup when stall */ + uint8_t *interruptOutPipeDataBuffer; /*!< OUT pipe data buffer backup when stall */ + uint32_t interruptOutPipeDataLen; /*!< OUT pipe data length backup when stall */ + uint8_t configuration; /*!< Current configuration */ + uint8_t interfaceNumber; /*!< The interface number of the class */ + uint8_t alternate; /*!< Current alternate setting of the interface */ + uint8_t idleRate; /*!< The idle rate of the HID device */ + uint8_t protocol; /*!< Current protocol */ + uint8_t interruptInPipeBusy; /*!< Interrupt IN pipe busy flag */ + uint8_t interruptOutPipeBusy; /*!< Interrupt OUT pipe busy flag */ + uint8_t interruptInPipeStall; /*!< Interrupt IN pipe stall flag */ + uint8_t interruptOutPipeStall; /*!< Interrupt OUT pipe stall flag */ +} usb_device_hid_struct_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the HID class. + * + * This function is used to initialize the HID class. This function only can be called by #USB_DeviceClassInit. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t. + * @param[in] config The class configuration information. + * @param[out] handle An parameter used to return pointer of the HID class handle to the caller. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DeviceHidInit(uint8_t controllerId, + usb_device_class_config_struct_t *config, + class_handle_t *handle); + +/*! + * @brief Deinitializes the device HID class. + * + * The function deinitializes the device HID class. This function only can be called by #USB_DeviceClassDeinit. + * + * @param[in] handle The HID class handle got from usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DeviceHidDeinit(class_handle_t handle); + +/*! + * @brief Handles the event passed to the HID class. + * + * This function handles the event passed to the HID class. This function only can be called by #USB_DeviceClassEvent. + * + * @param[in] handle The HID class handle received from the usb_device_class_config_struct_t::classHandle. + * @param[in] event The event codes. See the enumeration usb_device_class_event_t. + * @param[in,out] param The parameter type is determined by the event code. + * + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The device handle not be found. + * @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe is stalled by the caller. + */ +extern usb_status_t USB_DeviceHidEvent(void *handle, uint32_t event, void *param); + +/*! + * @name USB device HID class APIs + * @{ + */ + +/*! + * @brief Sends data through a specified endpoint. + * + * The function is used to send data through a specified endpoint. + * The function calls #USB_DeviceSendRequest internally. + * + * @param[in] handle The HID class handle received from usb_device_class_config_struct_t::classHandle. + * @param[in] ep Endpoint index. + * @param[in] buffer The memory address to hold the data need to be sent. + * @param[in] length The data length to be sent. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The function can only be called in the same context. + * + * @note The return value indicates whether the sending request is successful or not. The transfer done is notified by + * usb_device_hid_interrupt_in. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer can begin only when the previous transfer is done (a notification is received through the + * endpoint + * callback). + */ +extern usb_status_t USB_DeviceHidSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length); + +/*! + * @brief Receives data through a specified endpoint. + * + * The function is used to receive data through a specified endpoint. + * The function calls #USB_DeviceRecvRequest internally. + * + * @param[in] handle The HID class handle received from the usb_device_class_config_struct_t::classHandle. + * @param[in] ep Endpoint index. + * @param[in] buffer The memory address to save the received data. + * @param[in] length The data length to be received. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The function can only be called in the same context. + * + * @note The return value indicates whether the receiving request is successful or not. The transfer done is notified by + * usb_device_hid_interrupt_out. + * Currently, only one transfer request can be supported for a specific endpoint. + * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer can begin only when the previous transfer is done (a notification is received through the + * endpoint + * callback). + */ +extern usb_status_t USB_DeviceHidRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length); + +/*! @}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __USB_DEVICE_HID_H__ */ diff --git a/usb/device/class/usb_device_msc.c b/usb/device/class/usb_device_msc.c new file mode 100644 index 0000000..c79ce9e --- /dev/null +++ b/usb/device/class/usb_device_msc.c @@ -0,0 +1,1204 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device.h" + +#include "usb_device_class.h" + +#if ((defined(USB_DEVICE_CONFIG_MSC)) && (USB_DEVICE_CONFIG_MSC > 0U)) +#include "usb_device_msc.h" +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +usb_status_t USB_DeviceMscRecv(usb_device_msc_struct_t *mscHandle); +usb_status_t USB_DeviceMscSend(usb_device_msc_struct_t *mscHandle); +usb_status_t USB_DeviceMscEndpointsInit(usb_device_msc_struct_t *mscHandle); +usb_status_t USB_DeviceMscEndpointsDeinit(usb_device_msc_struct_t *mscHandle); + +extern usb_status_t USB_DeviceMscUfiThirteenCasesCheck(usb_device_msc_struct_t *mscHandle); +extern usb_status_t USB_DeviceMscUfiRequestSenseCommand(usb_device_msc_struct_t *mscHandle); +extern usb_status_t USB_DeviceMscUfiInquiryCommand(usb_device_msc_struct_t *mscHandle); +extern usb_status_t USB_DeviceMscUfiReadCommand(usb_device_msc_struct_t *mscHandle); +extern usb_status_t USB_DeviceMscUfiWriteCommand(usb_device_msc_struct_t *mscHandle); +extern usb_status_t USB_DeviceMscUfiTestUnitReadyCommand(usb_device_msc_struct_t *mscHandle); +extern usb_status_t USB_DeviceMscUfiVerifyCommand(usb_device_msc_struct_t *mscHandle); +extern usb_status_t USB_DeviceMscUfiModeSenseCommand(usb_device_msc_struct_t *mscHandle); +extern usb_status_t USB_DeviceMscUfiModeSelectCommand(usb_device_msc_struct_t *mscHandle); +extern usb_status_t USB_DeviceMscUfiReadCapacityCommand(usb_device_msc_struct_t *mscHandle); +extern usb_status_t USB_DeviceMscUfiReadFormatCapacityCommand(usb_device_msc_struct_t *mscHandle); +extern usb_status_t USB_DeviceMscUfiFormatUnitCommand(usb_device_msc_struct_t *mscHandle); +extern usb_status_t USB_DeviceMscUfiPreventAllowMediumCommand(usb_device_msc_struct_t *mscHandle); +extern usb_status_t USB_DeviceMscUfiSendDiagnosticCommand(usb_device_msc_struct_t *mscHandle); +extern usb_status_t USB_DeviceMscUfiStartStopUnitCommand(usb_device_msc_struct_t *mscHandle); +extern usb_status_t USB_DeviceMscUfiUnsupportCommand(usb_device_msc_struct_t *mscHandle); +/******************************************************************************* + * Variables + ******************************************************************************/ + +#if (USB_DEVICE_CONFIG_MSC == 1U) +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_msc_cbw_t s_MscCbw1; +#define MSCCBW_ARRAY ((usb_device_msc_cbw_t *[]){&s_MscCbw1}) +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_msc_csw_t s_MscCsw1; +#define MSCCSW_ARRAY ((usb_device_msc_csw_t *[]){&s_MscCsw1}) +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_request_sense_data_struct_t requestSense1; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_read_capacity_struct_t readCapacity1; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_read_capacity16_data_struct_t readCapacity161; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) uint8_t + formatCapacityData1[sizeof(usb_device_capacity_list_header_struct_t) + + sizeof(usb_device_current_max_capacity_descriptor_struct_t) + + sizeof(usb_device_formattable_capacity_descriptor_struct_t) * 3]; +#define MSCSENSE_ARRAY ((usb_device_request_sense_data_struct_t *[]){&requestSense1}) +#define MSCCPAP_ARRAY ((usb_device_read_capacity_struct_t *[]){&readCapacity1}) +#define MSCCAPA16_ARRAY ((usb_device_read_capacity16_data_struct_t *[]){&readCapacity161}) +#define MSCFORMAT_ARRAY ((uint8_t *[]){&formatCapacityData1[0]}) +#elif(USB_DEVICE_CONFIG_MSC == 2U) +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_msc_cbw_t s_MscCbw1; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_msc_cbw_t s_MscCbw2; +#define MSCCBW_ARRAY ((usb_device_msc_cbw_t *[]){&s_MscCbw1, &s_MscCbw2}) +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_msc_csw_t s_MscCsw1; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_msc_csw_t s_MscCsw2; +#define MSCCSW_ARRAY ((usb_device_msc_csw_t *[]){&s_MscCsw1, &s_MscCsw2}) +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_request_sense_data_struct_t requestSense1; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_read_capacity_struct_t readCapacity1; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_read_capacity16_data_struct_t readCapacity161; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) uint8_t + formatCapacityData1[sizeof(usb_device_capacity_list_header_struct_t) + + sizeof(usb_device_current_max_capacity_descriptor_struct_t) + + sizeof(usb_device_formattable_capacity_descriptor_struct_t) * 3]; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_request_sense_data_struct_t requestSense2; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_read_capacity_struct_t readCapacity2; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_read_capacity16_data_struct_t readCapacity162; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) uint8_t + formatCapacityData2[sizeof(usb_device_capacity_list_header_struct_t) + + sizeof(usb_device_current_max_capacity_descriptor_struct_t) + + sizeof(usb_device_formattable_capacity_descriptor_struct_t) * 3]; +#define MSCSENSE_ARRAY ((usb_device_request_sense_data_struct_t *[]){&requestSense1, &requestSense2}) +#define MSCCPAP_ARRAY ((usb_device_read_capacity_struct_t *[]){&readCapacity1, &readCapacity2}) +#define MSCCAPA16_ARRAY ((usb_device_read_capacity16_data_struct_t *[]){&readCapacity161, &readCapacity162}) +#define MSCFORMAT_ARRAY ((uint8_t *[]){&formatCapacityData1[0], &formatCapacityData2[0]}) +#elif(USB_DEVICE_CONFIG_MSC == 3U) +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_msc_cbw_t s_MscCbw1; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_msc_cbw_t s_MscCbw2; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_msc_cbw_t s_MscCbw3; +#define MSCCBW_ARRAY ((usb_device_msc_cbw_t *[]){&s_MscCbw1, &s_MscCbw2, &s_MscCbw3}) +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_msc_csw_t s_MscCsw1; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_msc_csw_t s_MscCsw2; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_msc_csw_t s_MscCsw3; +#define MSCCSW_ARRAY ((usb_device_msc_csw_t *[]){&s_MscCsw1, &s_MscCsw2, &s_MscCsw3}) +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_request_sense_data_struct_t requestSense1; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_read_capacity_struct_t readCapacity1; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_read_capacity16_data_struct_t readCapacity161; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) uint8_t + formatCapacityData1[sizeof(usb_device_capacity_list_header_struct_t) + + sizeof(usb_device_current_max_capacity_descriptor_struct_t) + + sizeof(usb_device_formattable_capacity_descriptor_struct_t) * 3]; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_request_sense_data_struct_t requestSense2; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_read_capacity_struct_t readCapacity2; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_read_capacity16_data_struct_t readCapacity162; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) uint8_t + formatCapacityData2[sizeof(usb_device_capacity_list_header_struct_t) + + sizeof(usb_device_current_max_capacity_descriptor_struct_t) + + sizeof(usb_device_formattable_capacity_descriptor_struct_t) * 3]; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_request_sense_data_struct_t requestSense3; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_read_capacity_struct_t readCapacity3; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_read_capacity16_data_struct_t readCapacity163; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) uint8_t + formatCapacityData3[sizeof(usb_device_capacity_list_header_struct_t) + + sizeof(usb_device_current_max_capacity_descriptor_struct_t) + + sizeof(usb_device_formattable_capacity_descriptor_struct_t) * 3]; +#define MSCSENSE_ARRAY ((usb_device_request_sense_data_struct_t *[]){&requestSense1, &requestSense2, &requestSense3}) +#define MSCCPAP_ARRAY ((usb_device_read_capacity_struct_t *[]){&readCapacity1, &readCapacity2, &readCapacity3}) +#define MSCCAPA16_ARRAY \ + ((usb_device_read_capacity16_data_struct_t *[]){&readCapacity161, &readCapacity162, &readCapacity163}) +#define MSCFORMAT_ARRAY ((uint8_t *[]){&formatCapacityData1[0], &formatCapacityData2[0], &formatCapacityData3[0]}) +#else +#error "the max support USB_DEVICE_CONFIG_MSC is 3" +#endif + +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_msc_struct_t g_msc_handle[USB_DEVICE_CONFIG_MSC]; +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Allocate a device msc class handle. + * + * This function allocates a device msc class handle. + * + * @param handle It is out parameter, is used to return pointer of the device msc class handle to the caller. + * + * @retval kStatus_USB_Success Get a device msc class handle successfully. + * @retval kStatus_USB_Busy Cannot allocate a device msc class handle. + */ + +static usb_status_t USB_DeviceMscAllocateHandle(usb_device_msc_struct_t **handle) +{ + uint32_t count; + for (count = 0; count < USB_DEVICE_CONFIG_MSC; count++) + { + if (NULL == g_msc_handle[count].handle) + { + g_msc_handle[count].mscCbw = (MSCCBW_ARRAY[count]); + g_msc_handle[count].mscCsw = (MSCCSW_ARRAY[count]); + g_msc_handle[count].mscUfi.requestSense = (MSCSENSE_ARRAY[count]); + g_msc_handle[count].mscUfi.readCapacity = (MSCCPAP_ARRAY[count]); + g_msc_handle[count].mscUfi.readCapacity16 = (MSCCAPA16_ARRAY[count]); + g_msc_handle[count].mscUfi.formatCapacityData = (MSCFORMAT_ARRAY[count]); + *handle = &g_msc_handle[count]; + return kStatus_USB_Success; + } + } + + return kStatus_USB_Busy; +} + +/*! + * @brief Free a device msc class handle. + * + * This function frees a device msc class handle. + * + * @param handle The device msc class handle. + * + * @retval kStatus_USB_Success Free device msc class handle successfully. + */ +static usb_status_t USB_DeviceMscFreeHandle(usb_device_msc_struct_t *handle) +{ + handle->handle = NULL; + handle->configurationStruct = (usb_device_class_config_struct_t *)NULL; + handle->configuration = 0; + handle->alternate = 0; + return kStatus_USB_Success; +} + +/*! + * @brief Process usb msc ufi command. + * + * This function analyse the cbw , get the command code. + * + * @param handle The device msc class handle. + * + * @retval kStatus_USB_Success Free device msc class handle successfully. + */ +usb_status_t USB_DeviceMscProcessUfiCommand(usb_device_msc_struct_t *mscHandle) +{ + usb_status_t error = kStatus_USB_Error; + usb_device_msc_ufi_struct_t *ufi = NULL; + + ufi = &mscHandle->mscUfi; + if (USB_DEVICE_MSC_REQUEST_SENSE_COMMAND != mscHandle->mscCbw->cbwcb[0]) + { + ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_NO_SENSE; + ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_NO_SENSE; + ufi->requestSense->additionalSenseQualifer = USB_DEVICE_MSC_UFI_NO_SENSE; + } + ufi->thirteenCase.hostExpectedDataLength = mscHandle->mscCbw->dataTransferLength; + ufi->thirteenCase.hostExpectedDirection = (uint8_t)(mscHandle->mscCbw->flags >> USB_DEVICE_MSC_CBW_DIRECTION_SHIFT); + /*The first byte of all ufi command blocks shall contain an Operation Code, refer to ufi spec*/ + switch (mscHandle->mscCbw->cbwcb[0]) + { + /* ufi command operation code*/ + case USB_DEVICE_MSC_INQUIRY_COMMAND: /*operation code : 0x12*/ + error = USB_DeviceMscUfiInquiryCommand(mscHandle); + break; + case USB_DEVICE_MSC_READ_10_COMMAND: /*operation code : 0x28 */ + case USB_DEVICE_MSC_READ_12_COMMAND: /*operation code : 0xA8 */ + error = USB_DeviceMscUfiReadCommand(mscHandle); + break; + case USB_DEVICE_MSC_REQUEST_SENSE_COMMAND: /*operation code : 0x03*/ + error = USB_DeviceMscUfiRequestSenseCommand(mscHandle); + break; + case USB_DEVICE_MSC_TEST_UNIT_READY_COMMAND: /*operation code : 0x00 */ + error = USB_DeviceMscUfiTestUnitReadyCommand(mscHandle); + break; + case USB_DEVICE_MSC_WRITE_10_COMMAND: /*operation code : 0x2A */ + case USB_DEVICE_MSC_WRITE_12_COMMAND: /*operation code : 0xAA */ + error = USB_DeviceMscUfiWriteCommand(mscHandle); + break; + case USB_DEVICE_MSC_PREVENT_ALLOW_MEDIUM_REM_COMMAND: /*operation code :0x1E */ + error = USB_DeviceMscUfiPreventAllowMediumCommand(mscHandle); + break; + case USB_DEVICE_MSC_FORMAT_UNIT_COMMAND: /*operation code : 0x04*/ + error = USB_DeviceMscUfiFormatUnitCommand(mscHandle); + break; + case USB_DEVICE_MSC_READ_CAPACITY_10_COMMAND: /*operation code : 0x25*/ + case USB_DEVICE_MSC_READ_CAPACITY_16_COMMAND: /*operation code : 0x9E*/ + error = USB_DeviceMscUfiReadCapacityCommand(mscHandle); + break; + case USB_DEVICE_MSC_MODE_SENSE_10_COMMAND: /* operation code :0x5A*/ + case USB_DEVICE_MSC_MODE_SENSE_6_COMMAND: /* operation code : 0x1A */ + error = USB_DeviceMscUfiModeSenseCommand(mscHandle); + break; + case USB_DEVICE_MSC_MODE_SELECT_10_COMMAND: /*operation code : 0x55 */ + case USB_DEVICE_MSC_MODE_SELECT_6_COMMAND: /*operation code : 0x15 */ + error = USB_DeviceMscUfiModeSelectCommand(mscHandle); + break; + case USB_DEVICE_MSC_READ_FORMAT_CAPACITIES_COMMAND: /*operation code : 0x23 */ + error = USB_DeviceMscUfiReadFormatCapacityCommand(mscHandle); + break; + case USB_DEVICE_MSC_SEND_DIAGNOSTIC_COMMAND: /*operation code : 0x1D*/ + error = USB_DeviceMscUfiSendDiagnosticCommand(mscHandle); + break; + case USB_DEVICE_MSC_VERIFY_COMMAND: /*operation code : 0x2F*/ + error = USB_DeviceMscUfiVerifyCommand(mscHandle); + break; + case USB_DEVICE_MSC_START_STOP_UNIT_COMMAND: /*operation code : 0x1B*/ + error = USB_DeviceMscUfiStartStopUnitCommand(mscHandle); + break; + default: + error = USB_DeviceMscUfiUnsupportCommand(mscHandle); + break; + } + if ((USB_DEVICE_MSC_UFI_NO_SENSE != ufi->requestSense->senseKey) && + (USB_DEVICE_MSC_COMMAND_PASSED == mscHandle->mscCsw->cswStatus) && + (USB_DEVICE_MSC_REQUEST_SENSE_COMMAND != mscHandle->mscCbw->cbwcb[0])) + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED; + } + return error; +} + +/*! + * @brief Bulk IN endpoint callback function. + * + * This callback function is used to notify upper layer the transfer result of a transfer. + * This callback pointer is passed when the Bulk IN pipe initialized. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The result of the Bulk IN pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the MSC class handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceMscBulkIn(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_msc_struct_t *mscHandle = (usb_device_msc_struct_t *)callbackParam; + usb_device_msc_csw_t *csw; + usb_status_t error = kStatus_USB_Error; + if (message->length == USB_UNINITIALIZED_VAL_32) + { + /*this code is called when stack cancel the transfer, app should release the buffer it use */ + if ((mscHandle->dataInFlag) && (mscHandle->configurationStruct->classCallback != NULL) && + ((USB_DEVICE_MSC_READ_10_COMMAND == mscHandle->mscCbw->cbwcb[0]) || + (USB_DEVICE_MSC_READ_12_COMMAND == mscHandle->mscCbw->cbwcb[0]))) + { + usb_device_lba_app_struct_t lbaData; + + lbaData.size = 0; + lbaData.buffer = message->buffer; + lbaData.offset = 0; + /*classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventReadResponse, + (void *)&lbaData); + } + if (mscHandle->inEndpointCswCancelFlag == 1) + { + mscHandle->inEndpointCswCancelFlag = 0; + /*cancel the transfer and wait for the calcel to be complete in bulk in callback*/ + /*send csw*/ + mscHandle->mscCsw->dataResidue = USB_LONG_TO_LITTLE_ENDIAN(mscHandle->mscCsw->dataResidue); + USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, (uint8_t *)mscHandle->mscCsw, + USB_DEVICE_MSC_CSW_LENGTH); + mscHandle->cswPrimeFlag = 1; + mscHandle->stallStatus = 0; + } + return error; + } + if (mscHandle->transferRemaining >= message->length) + { + mscHandle->transferRemaining -= message->length; + } + + if (mscHandle->needInStallFlag == 1) + { + mscHandle->needInStallFlag = 0; + mscHandle->inEndpointStallFlag = 1; + mscHandle->dataInFlag = 0; + USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkInEndpoint); + return error; + } + if ((!mscHandle->dataInFlag) && (message->length == USB_DEVICE_MSC_CSW_LENGTH)) + { + csw = (usb_device_msc_csw_t *)(message->buffer); + } + + if (mscHandle->dataInFlag) + { + if ((mscHandle->configurationStruct->classCallback != NULL)) + { + usb_device_lba_app_struct_t lbaData; + + lbaData.size = message->length; + lbaData.buffer = message->buffer; + lbaData.offset = mscHandle->currentOffset; + + if ((USB_DEVICE_MSC_READ_10_COMMAND == mscHandle->mscCbw->cbwcb[0]) || + (USB_DEVICE_MSC_READ_12_COMMAND == mscHandle->mscCbw->cbwcb[0])) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, + kUSB_DeviceMscEventReadResponse, (void *)&lbaData); + } + + if (mscHandle->transferRemaining) + { + mscHandle->currentOffset += (message->length / mscHandle->lengthOfEachLba); + error = USB_DeviceMscSend(mscHandle); + } + if (!mscHandle->transferRemaining) + { + mscHandle->dataInFlag = 0; + /*data transfer has been done, send the csw to host */ + mscHandle->cswPrimeFlag = 1; + mscHandle->mscCsw->dataResidue = USB_LONG_TO_LITTLE_ENDIAN(mscHandle->mscCsw->dataResidue); + USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, (uint8_t *)mscHandle->mscCsw, + USB_DEVICE_MSC_CSW_LENGTH); + } + } + } + else if ((message->length == USB_DEVICE_MSC_CSW_LENGTH) && (csw->signature == USB_DEVICE_MSC_DCSWSIGNATURE)) + { + mscHandle->cbwValidFlag = 1; + mscHandle->cswPrimeFlag = 0; + (void)USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, (uint8_t *)mscHandle->mscCbw, + USB_DEVICE_MSC_CBW_LENGTH); + mscHandle->cbwPrimeFlag = 1; + } + else + { + } + return error; +} + +/*! + * @brief Bulk OUT endpoint callback function. + * + * This callback function is used to notify upper layer the transfer result of a transfer. + * This callback pointer is passed when the Bulk OUT pipe initialized. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The result of the Bulk OUT pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the MSC class handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceMscBulkOut(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_msc_struct_t *mscHandle = (usb_device_msc_struct_t *)callbackParam; + usb_status_t error = kStatus_USB_Success; + if (message->length == USB_UNINITIALIZED_VAL_32) + { + /*this code is called when stack cancel the transfer, app should release the buffer it use*/ + if ((mscHandle->dataOutFlag) && (mscHandle->configurationStruct->classCallback != NULL) && + ((USB_DEVICE_MSC_WRITE_10_COMMAND == mscHandle->mscCbw->cbwcb[0]) || + (USB_DEVICE_MSC_WRITE_12_COMMAND == mscHandle->mscCbw->cbwcb[0]))) + { + usb_device_lba_app_struct_t lbaData; + + lbaData.size = 0; + lbaData.buffer = message->buffer; + lbaData.offset = 0; + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventWriteResponse, + (void *)&lbaData); + } + if ((mscHandle->cbwPrimeFlag == 0) && (mscHandle->inEndpointStallFlag == 0) && + (mscHandle->outEndpointStallFlag == 0)) + { + /*prime cbw*/ + USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, (uint8_t *)mscHandle->mscCbw, + USB_DEVICE_MSC_CBW_LENGTH); + mscHandle->cbwPrimeFlag = 1; + } + return error; + } + + if (mscHandle->transferRemaining >= message->length) + { + mscHandle->transferRemaining -= message->length; + } + + if ((USB_DEVICE_MSC_MODE_SELECT_10_COMMAND == mscHandle->mscCbw->cbwcb[0]) || + (USB_DEVICE_MSC_MODE_SELECT_6_COMMAND == mscHandle->mscCbw->cbwcb[0])) + { + if ((mscHandle->configurationStruct->classCallback != NULL)) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, + kUSB_DeviceMscEventModeSelectResponse, (void *)NULL); + } + } + if (mscHandle->needOutStallFlag == 1) + { + mscHandle->needOutStallFlag = 0; + mscHandle->outEndpointStallFlag = 1; + mscHandle->dataOutFlag = 0; + mscHandle->cbwPrimeFlag = 0; + USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkOutEndpoint); + return error; + } + + if (mscHandle->dataOutFlag) + { + usb_device_lba_app_struct_t lbaData; + + lbaData.size = message->length; + lbaData.buffer = message->buffer; + lbaData.offset = mscHandle->currentOffset; + + if ((mscHandle->configurationStruct->classCallback != NULL)) + { + if ((USB_DEVICE_MSC_WRITE_10_COMMAND == mscHandle->mscCbw->cbwcb[0]) || + (USB_DEVICE_MSC_WRITE_12_COMMAND == mscHandle->mscCbw->cbwcb[0])) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, + kUSB_DeviceMscEventWriteResponse, (void *)&lbaData); + } + + if (mscHandle->transferRemaining) + { + mscHandle->currentOffset += (message->length / mscHandle->lengthOfEachLba); + error = USB_DeviceMscRecv(mscHandle); + } + } + + if (!mscHandle->transferRemaining) + { + mscHandle->dataOutFlag = 0; + { + mscHandle->mscCsw->dataResidue = USB_LONG_TO_LITTLE_ENDIAN(mscHandle->mscCsw->dataResidue); + USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, (uint8_t *)mscHandle->mscCsw, + USB_DEVICE_MSC_CSW_LENGTH); + mscHandle->cswPrimeFlag = 1; + } + } + } + else if ((mscHandle->cbwValidFlag) && (message->length == USB_DEVICE_MSC_CBW_LENGTH) && + (mscHandle->mscCbw->signature == USB_DEVICE_MSC_DCBWSIGNATURE) && + (!((mscHandle->mscCbw->logicalUnitNumber & 0xF0) || (mscHandle->mscCbw->cbLength & 0xE0))) && + (mscHandle->mscCbw->logicalUnitNumber < (mscHandle->logicalUnitNumber + 1)) && + ((mscHandle->mscCbw->cbLength >= 0x01) && (mscHandle->mscCbw->cbLength <= 0x10))) + { + mscHandle->cbwPrimeFlag = 0; + mscHandle->transferRemaining = 0; + + mscHandle->mscCsw->signature = USB_DEVICE_MSC_DCSWSIGNATURE; + mscHandle->mscCsw->dataResidue = 0; + mscHandle->mscCsw->tag = mscHandle->mscCbw->tag; + + mscHandle->cbwValidFlag = 0; + + mscHandle->mscCbw->dataTransferLength = USB_LONG_FROM_LITTLE_ENDIAN(mscHandle->mscCbw->dataTransferLength); + + mscHandle->dataOutFlag = (uint8_t)(((!(mscHandle->mscCbw->flags & USB_DEVICE_MSC_CBW_DIRECTION_BIT)) && + (mscHandle->mscCbw->dataTransferLength)) ? + 1 : + 0); + + mscHandle->dataInFlag = (uint8_t)( + ((mscHandle->mscCbw->flags & USB_DEVICE_MSC_CBW_DIRECTION_BIT) && (mscHandle->mscCbw->dataTransferLength)) ? + 1 : + 0); + + if ((0 != mscHandle->dataInFlag) && (0 != mscHandle->inEndpointStallFlag)) + { + error = kStatus_USB_Error; + return error; + } + error = USB_DeviceMscProcessUfiCommand(mscHandle); + if (error == kStatus_USB_InvalidRequest) + { + if (mscHandle->dataOutFlag == 1) + { + if (mscHandle->outEndpointStallFlag == 0) + { + mscHandle->needOutStallFlag = 1; + } + mscHandle->dataOutFlag = 0; + } + else if (mscHandle->dataInFlag == 1) + { + if (mscHandle->inEndpointStallFlag == 0) + { + mscHandle->needInStallFlag = 1; + } + mscHandle->dataInFlag = 0; + } + else + { + } + mscHandle->stallStatus = (uint8_t)USB_DEVICE_MSC_STALL_IN_DATA; + } + + if (!((mscHandle->dataOutFlag) || ((mscHandle->dataInFlag) || (mscHandle->needInStallFlag)))) + { + mscHandle->mscCsw->dataResidue = USB_LONG_TO_LITTLE_ENDIAN(mscHandle->mscCsw->dataResidue); + USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, (uint8_t *)mscHandle->mscCsw, + USB_DEVICE_MSC_CSW_LENGTH); + mscHandle->cswPrimeFlag = 1; + } + } + else + { + USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkOutEndpoint); + USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkInEndpoint); + mscHandle->cbwPrimeFlag = 0; + mscHandle->cbwValidFlag = 0; + mscHandle->outEndpointStallFlag = 1; + mscHandle->inEndpointStallFlag = 1; + mscHandle->stallStatus = (uint8_t)USB_DEVICE_MSC_STALL_IN_CBW; + mscHandle->performResetRecover = 1; + } + return error; +} + +/*! + * @brief Initialize the endpoints of the msc class. + * + * This callback function is used to initialize the endpoints of the msc class. + * + * @param mscHandle The device msc class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceMscEndpointsInit(usb_device_msc_struct_t *mscHandle) +{ + usb_device_interface_list_t *interfaceList; + usb_device_interface_struct_t *interface = (usb_device_interface_struct_t *)NULL; + usb_status_t error = kStatus_USB_Error; + + /* Check the configuration is valid or not. */ + if ((0 == mscHandle->configuration) || + (mscHandle->configuration > mscHandle->configurationStruct->classInfomation->configurations)) + { + return error; + } + + /* Get the interface list of the new configuration. */ + /* Check the interface list is valid or not. */ + if (NULL == mscHandle->configurationStruct->classInfomation->interfaceList) + { + return error; + } + interfaceList = &mscHandle->configurationStruct->classInfomation->interfaceList[mscHandle->configuration - 1]; + + /* Find interface by using the alternate setting of the interface. */ + for (int count = 0; count < interfaceList->count; count++) + { + if (USB_DEVICE_CONFIG_MSC_CLASS_CODE == interfaceList->interfaces[count].classCode) + { + for (int index = 0; index < interfaceList->interfaces[count].count; index++) + { + if (interfaceList->interfaces[count].interface[index].alternateSetting == mscHandle->alternate) + { + interface = &interfaceList->interfaces[count].interface[index]; + break; + } + } + mscHandle->interfaceNumber = interfaceList->interfaces[count].interfaceNumber; + break; + } + } + if (!interface) + { + /* Return error if the interface is not found. */ + return error; + } + + /* Keep new interface handle. */ + mscHandle->interfaceHandle = interface; + /* Initialize the endpoints of the new interface. */ + for (int count = 0; count < interface->endpointList.count; count++) + { + usb_device_endpoint_init_struct_t epInitStruct; + usb_device_endpoint_callback_struct_t epCallback; + epInitStruct.zlt = 0; + epInitStruct.interval = interface->endpointList.endpoint[count].interval; + epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress; + epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize; + epInitStruct.transferType = interface->endpointList.endpoint[count].transferType; + + if (USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) + { + mscHandle->bulkInEndpoint = epInitStruct.endpointAddress; + epCallback.callbackFn = USB_DeviceMscBulkIn; + } + else + { + mscHandle->bulkOutEndpoint = epInitStruct.endpointAddress; + epCallback.callbackFn = USB_DeviceMscBulkOut; + } + epCallback.callbackParam = mscHandle; + + error = USB_DeviceInitEndpoint(mscHandle->handle, &epInitStruct, &epCallback); + } + + mscHandle->dataOutFlag = 0; + mscHandle->dataInFlag = 0; + mscHandle->outEndpointStallFlag = 0; + mscHandle->inEndpointStallFlag = 0; + mscHandle->needOutStallFlag = 0; + mscHandle->needInStallFlag = 0; + mscHandle->cbwValidFlag = 1; + mscHandle->transferRemaining = 0; + mscHandle->performResetRecover = 0; + mscHandle->performResetDoneFlag = 0; + mscHandle->stallStatus = 0; + mscHandle->inEndpointCswCancelFlag = 0; + return error; +} + +/*! + * @brief De-initialize the endpoints of the msc class. + * + * This callback function is used to de-initialize the endpoints of the msc class. + * + * @param mscHandle The device msc class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceMscEndpointsDeinit(usb_device_msc_struct_t *mscHandle) +{ + usb_status_t error = kStatus_USB_Error; + + if (!mscHandle->interfaceHandle) + { + return error; + } + /* De-initialize all endpoints of the interface */ + for (int count = 0; count < mscHandle->interfaceHandle->endpointList.count; count++) + { + error = USB_DeviceDeinitEndpoint(mscHandle->handle, + mscHandle->interfaceHandle->endpointList.endpoint[count].endpointAddress); + } + mscHandle->interfaceHandle = NULL; + return error; +} + +/*! + * @brief Initialize the msc class. + * + * This function is used to initialize the msc class. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param config The class configuration information. + * @param handle It is out parameter, is used to return pointer of the msc class handle to the caller. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceMscInit(uint8_t controllerId, usb_device_class_config_struct_t *config, class_handle_t *handle) +{ + usb_device_msc_struct_t *mscHandle; + usb_status_t error = kStatus_USB_Error; + uint32_t implementingDiskDrive = USB_DEVICE_CONFIG_MSC_IMPLEMENTING_DISK_DRIVE; + usb_device_lba_information_struct_t diskInformation; + usb_device_msc_ufi_struct_t *ufi = NULL; + + /* Allocate a msc class handle. */ + error = USB_DeviceMscAllocateHandle(&mscHandle); + + if (kStatus_USB_Success != error) + { + return error; + } + + /* Get the device handle according to the controller id. */ + error = USB_DeviceClassGetDeviceHandle(controllerId, &mscHandle->handle); + + if (kStatus_USB_Success != error) + { + USB_DeviceMscFreeHandle(mscHandle); + return error; + } + if (!mscHandle->handle) + { + USB_DeviceMscFreeHandle(mscHandle); + return kStatus_USB_InvalidHandle; + } + /* Save the configuration of the class. */ + mscHandle->configurationStruct = config; + /* Clear the configuration value. */ + mscHandle->configuration = 0; + mscHandle->alternate = 0xff; + + /* Get device information. classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = mscHandle->configurationStruct->classCallback( + (class_handle_t)mscHandle, kUSB_DeviceMscEventGetLbaInformation, (void *)&diskInformation); + + if (((diskInformation.lengthOfEachLba) && (diskInformation.totalLbaNumberSupports)) == 0) + { + error = kStatus_USB_Error; + USB_DeviceMscFreeHandle(mscHandle); + return error; + } + mscHandle->logicalUnitNumber = diskInformation.logicalUnitNumberSupported; + /*initialize the basic device information*/ + ufi = &mscHandle->mscUfi; + mscHandle->totalLogicalBlockNumber = diskInformation.totalLbaNumberSupports; + mscHandle->lengthOfEachLba = diskInformation.lengthOfEachLba; + mscHandle->logicalUnitNumber = diskInformation.logicalUnitNumberSupported - 1; + mscHandle->bulkInBufferSize = diskInformation.bulkInBufferSize; + mscHandle->bulkOutBufferSize = diskInformation.bulkOutBufferSize; + mscHandle->implementingDiskDrive = implementingDiskDrive; + + ufi->requestSense->validErrorCode = USB_DEVICE_MSC_UFI_REQ_SENSE_VALID_ERROR_CODE; + ufi->requestSense->additionalSenseLength = USB_DEVICE_MSC_UFI_REQ_SENSE_ADDITIONAL_SENSE_LEN; + ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_NO_SENSE; + ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_NO_SENSE; + ufi->requestSense->additionalSenseQualifer = USB_DEVICE_MSC_UFI_NO_SENSE; + + ufi->readCapacity->lastLogicalBlockAddress = USB_LONG_TO_BIG_ENDIAN(mscHandle->totalLogicalBlockNumber - 1); + ufi->readCapacity->blockSize = USB_LONG_TO_BIG_ENDIAN((uint32_t)mscHandle->lengthOfEachLba); + ufi->readCapacity16->lastLogicalBlockAddress1 = USB_LONG_TO_BIG_ENDIAN(mscHandle->totalLogicalBlockNumber - 1); + ufi->readCapacity16->blockSize = USB_LONG_TO_BIG_ENDIAN((uint32_t)mscHandle->lengthOfEachLba); + + mscHandle->cbwPrimeFlag = 0; + mscHandle->cswPrimeFlag = 0; + + *handle = (class_handle_t)mscHandle; + return error; +} + +/*! + * @brief De-initialize the device msc class. + * + * The function de-initializes the device msc class. + * + * @param handle The msc class handle got from usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceMscDeinit(class_handle_t handle) +{ + usb_device_msc_struct_t *mscHandle; + usb_status_t error = kStatus_USB_Error; + + mscHandle = (usb_device_msc_struct_t *)handle; + + if (!mscHandle) + { + return kStatus_USB_InvalidHandle; + } + error = USB_DeviceMscEndpointsDeinit(mscHandle); + USB_DeviceMscFreeHandle(mscHandle); + return error; +} + +/*! + * @brief Handle the event passed to the msc class. + * + * This function handles the event passed to the msc class. + * + * @param handle The msc class handle, got from the usb_device_class_config_struct_t::classHandle. + * @param event The event codes. Please refer to the enumeration usb_device_class_event_t. + * @param param The param type is determined by the event code. + * + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The device handle not be found. + * @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe will be stalled by the caller. + */ +usb_status_t USB_DeviceMscEvent(void *handle, uint32_t event, void *param) +{ + usb_status_t error = kStatus_USB_Error; + usb_device_msc_struct_t *mscHandle; + + uint16_t interfaceAlternate; + uint8_t *temp8; + uint8_t alternate; + + if ((!param) || (!handle)) + { + return kStatus_USB_InvalidHandle; + } + + /* Get the msc class handle. */ + mscHandle = (usb_device_msc_struct_t *)handle; + switch (event) + { + case kUSB_DeviceClassEventDeviceReset: + /* Bus reset, clear the configuration. */ + mscHandle->configuration = 0; + break; + case kUSB_DeviceClassEventSetConfiguration: + /* Get the new configuration. */ + temp8 = ((uint8_t *)param); + if (!mscHandle->configurationStruct) + { + break; + } + if (*temp8 == mscHandle->configuration) + { + break; + } + + if (mscHandle->configuration) + { + /* De-initialize the endpoints when current configuration is none zero. */ + error = USB_DeviceMscEndpointsDeinit(mscHandle); + } + /* Save new configuration. */ + mscHandle->configuration = *temp8; + /* Clear the alternate setting value. */ + mscHandle->alternate = 0; + /* Initialize the endpoints of the new current configuration by using the alternate setting 0. */ + error = USB_DeviceMscEndpointsInit(mscHandle); + if (kStatus_USB_Success == error) + { + USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, (uint8_t *)mscHandle->mscCbw, + USB_DEVICE_MSC_CBW_LENGTH); + mscHandle->cbwPrimeFlag = 1; + } + break; + case kUSB_DeviceClassEventSetInterface: + + if (!mscHandle->configurationStruct) + { + break; + } + /* Get the new alternate setting of the interface */ + interfaceAlternate = *((uint16_t *)param); + /* Get the alternate setting value */ + alternate = (uint8_t)(interfaceAlternate & 0xFF); + + /* Whether the interface belongs to the class. */ + if (mscHandle->interfaceNumber != ((uint8_t)(interfaceAlternate >> 8))) + { + break; + } + /* Only handle new alternate setting. */ + if (alternate == mscHandle->alternate) + { + break; + } + error = USB_DeviceMscEndpointsDeinit(mscHandle); + /* Initialize new endpoints */ + error = USB_DeviceMscEndpointsInit(mscHandle); + if (kStatus_USB_Success == error) + { + USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, (uint8_t *)mscHandle->mscCbw, + USB_DEVICE_MSC_CBW_LENGTH); + mscHandle->cbwPrimeFlag = 1; + } + mscHandle->alternate = alternate; + + break; + case kUSB_DeviceClassEventSetEndpointHalt: + if ((!mscHandle->configurationStruct) || (!mscHandle->interfaceHandle)) + { + break; + } + /* Get the endpoint address */ + temp8 = ((uint8_t *)param); + + if ((mscHandle->inEndpointStallFlag == 0) && (*temp8 == mscHandle->bulkInEndpoint)) + { + /* Only stall the endpoint belongs to the class */ + mscHandle->inEndpointStallFlag = 1; + mscHandle->cswPrimeFlag = 0; + error = USB_DeviceStallEndpoint(mscHandle->handle, *temp8); + + } + if ((mscHandle->outEndpointStallFlag == 0) && (*temp8 == mscHandle->bulkOutEndpoint)) + { + mscHandle->outEndpointStallFlag = 1; + mscHandle->cbwPrimeFlag = 0; + error = USB_DeviceStallEndpoint(mscHandle->handle, *temp8); + + } + + break; + case kUSB_DeviceClassEventClearEndpointHalt: + if ((!mscHandle->configurationStruct) || (!mscHandle->interfaceHandle) || + (mscHandle->performResetRecover == 1)) + { + break; + } + /* Get the endpoint address */ + temp8 = ((uint8_t *)param); + /* Only un-stall the endpoint belongs to the class , If the endpoint is in stall status ,then + * un-stall it*/ + if ((mscHandle->inEndpointStallFlag == 1) && (*temp8 == mscHandle->bulkInEndpoint)) + { + mscHandle->inEndpointStallFlag = 0; + mscHandle->cswPrimeFlag = 0; + error = USB_DeviceUnstallEndpoint(mscHandle->handle, *temp8); + + } + if ((mscHandle->outEndpointStallFlag == 1) && (*temp8 == mscHandle->bulkOutEndpoint)) + { + mscHandle->outEndpointStallFlag = 0; + mscHandle->cbwPrimeFlag = 0; + error = USB_DeviceUnstallEndpoint(mscHandle->handle, *temp8); + + } + if (((mscHandle->stallStatus == USB_DEVICE_MSC_STALL_IN_CSW) || + (mscHandle->stallStatus == USB_DEVICE_MSC_STALL_IN_DATA)) && + (mscHandle->performResetDoneFlag != 1)) + { + if (mscHandle->cswPrimeFlag == 1) + { + /*cancel the transfer , after the cancel to be complete, and then prime csw in bulk in callback, */ + mscHandle->inEndpointCswCancelFlag = 1; + USB_DeviceCancel(mscHandle->handle, mscHandle->bulkInEndpoint); + } + else + { + /*send csw*/ + mscHandle->mscCsw->dataResidue = USB_LONG_TO_LITTLE_ENDIAN(mscHandle->mscCsw->dataResidue); + USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, (uint8_t *)mscHandle->mscCsw, + USB_DEVICE_MSC_CSW_LENGTH); + mscHandle->cswPrimeFlag = 1; + } + mscHandle->stallStatus = 0; + } + if ((mscHandle->performResetDoneFlag == 1) && (mscHandle->inEndpointStallFlag == 0) && + (mscHandle->outEndpointStallFlag == 0)) + { + mscHandle->performResetDoneFlag = 0; + if (mscHandle->cbwPrimeFlag == 1) + { + mscHandle->cbwPrimeFlag = 0; + USB_DeviceCancel(mscHandle->handle, mscHandle->bulkOutEndpoint); + } + else + { + /*prime cbw for new transfer*/ + USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, (uint8_t *)mscHandle->mscCbw, + USB_DEVICE_MSC_CBW_LENGTH); + mscHandle->cbwPrimeFlag = 1; + } + mscHandle->stallStatus = 0; + } + break; + case kUSB_DeviceClassEventClassRequest: + if (param) + { + /* Handle the msc class specific request. */ + usb_device_control_request_struct_t *control_request = (usb_device_control_request_struct_t *)param; + + if ((control_request->setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != + USB_REQUEST_TYPE_RECIPIENT_INTERFACE) + { + break; + } + + switch (control_request->setup->bRequest) + { + case USB_DEVICE_MSC_GET_MAX_LUN: + /*Get Max LUN */ + if ((control_request->setup->wIndex == mscHandle->interfaceNumber) && + (!control_request->setup->wValue) && (control_request->setup->wLength == 0x0001) && + ((control_request->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == + USB_REQUEST_TYPE_DIR_IN)) + { + control_request->buffer = &mscHandle->logicalUnitNumber; + control_request->length = (uint32_t)control_request->setup->wLength; + } + else + { + error = kStatus_USB_InvalidRequest; + } + + break; + case USB_DEVICE_MSC_BULK_ONLY_MASS_STORAGE_RESET: + /*Bulk-Only Mass Storage Reset (class-specific request)*/ + if ((control_request->setup->wIndex == mscHandle->interfaceNumber) && + (!control_request->setup->wValue) && (!control_request->setup->wLength) && + ((control_request->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == + USB_REQUEST_TYPE_DIR_OUT)) + { + /*Need to go to stall process, because reset recovery contains reset command and clare + * feature command*/ + mscHandle->outEndpointStallFlag = 1; + mscHandle->inEndpointStallFlag = 1; + + mscHandle->cbwValidFlag = 1; + mscHandle->performResetRecover = 0; + mscHandle->performResetDoneFlag = 1; + } + else + { + error = kStatus_USB_InvalidRequest; + } + + break; + default: + break; + } + } + break; + default: + break; + } + + return error; +} + +/*! + * @brief Send data through a specified endpoint. + * + * The function is used to send data through a specified endpoint. + * The function calls USB_DeviceSendRequest internally. + * + * @param handle The msc class handle got from usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value just means if the sending request is successful or not; the transfer done is notified by + * USB_DeviceMscBulkIn. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceMscSend(usb_device_msc_struct_t *mscHandle) +{ + usb_status_t error = kStatus_USB_Success; + usb_device_lba_app_struct_t lba; + + lba.offset = mscHandle->currentOffset; + /*bulkInBufferSize is the application buffer size, USB_DEVICE_MSC_MAX_SEND_TRANSFER_LENGTH is the max transfer + length by the hardware, + lba.size is the data pending for transfer ,select the minimum size to transfer ,the remaining will be transfer + next time*/ + lba.size = (mscHandle->bulkInBufferSize > USB_DEVICE_MSC_MAX_SEND_TRANSFER_LENGTH) ? + USB_DEVICE_MSC_MAX_SEND_TRANSFER_LENGTH : + mscHandle->bulkInBufferSize; + lba.size = + (mscHandle->transferRemaining > lba.size) ? lba.size : mscHandle->transferRemaining; /* which one is smaller */ + + lba.buffer = NULL; + /*classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit*/ + mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventReadRequest, &lba); + + if (mscHandle->currentOffset < mscHandle->totalLogicalBlockNumber) + { + error = USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, lba.buffer, lba.size); + } + else + { + mscHandle->needInStallFlag = 0; + mscHandle->inEndpointStallFlag = 1; + mscHandle->dataInFlag = 0; + mscHandle->stallStatus = (uint8_t)USB_DEVICE_MSC_STALL_IN_DATA; + USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkInEndpoint); + } + return error; +} + +/*! + * @brief Receive data through a specified endpoint. + * + * The function is used to receive data through a specified endpoint. + * The function calls USB_DeviceRecvRequest internally. + * + * @param handle The msc class handle got from usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value just means if the receiving request is successful or not; the transfer done is notified by + * USB_DeviceMscBulkOut. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceMscRecv(usb_device_msc_struct_t *mscHandle) +{ + usb_status_t error = kStatus_USB_Success; + usb_device_lba_app_struct_t lba; + + lba.offset = mscHandle->currentOffset; + /*bulkOutBufferSize is the application buffer size, USB_DEVICE_MSC_MAX_RECV_TRANSFER_LENGTH is the max transfer + length by the hardware, + lba.size is the data pending for transfer ,select the minimum size to transfer ,the remaining will be transfer + next time*/ + lba.size = (mscHandle->bulkOutBufferSize > USB_DEVICE_MSC_MAX_RECV_TRANSFER_LENGTH) ? + USB_DEVICE_MSC_MAX_RECV_TRANSFER_LENGTH : + mscHandle->bulkOutBufferSize; + lba.size = + (mscHandle->transferRemaining > lba.size) ? lba.size : mscHandle->transferRemaining; /* whichever is smaller */ + + lba.buffer = NULL; + /*classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit*/ + mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventWriteRequest, &lba); + + if (mscHandle->currentOffset < mscHandle->totalLogicalBlockNumber) + { + error = USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, lba.buffer, lba.size); + } + else + { + mscHandle->needOutStallFlag = 0; + mscHandle->outEndpointStallFlag = 1; + mscHandle->dataOutFlag = 0; + mscHandle->stallStatus = (uint8_t)USB_DEVICE_MSC_STALL_IN_DATA; + USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkOutEndpoint); + } + return error; +} + +/*! + * @brief Recv Send data through a specified endpoint. + * + * The function is used when ufi process read/write command . + * The function calls USB_DeviceMscRecv or usb_device_send_recv as the direction internally. + * + * @param handle The msc class handle got from usb_device_class_config_struct_t::classHandle. + * @param direction Data direction: 0 = Data-Out from host to the device, 1 = Data-In from the device to the host. + * @param buffer The memory address to hold the data need to be sent. + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value just means if the sending or receiving request is successful or not. + */ +usb_status_t USB_DeviceMscLbaTransfer(usb_device_msc_struct_t *mscHandle, + uint8_t direction, + usb_lba_transfer_information_struct_t *lba_info_ptr) +{ + usb_status_t error = kStatus_USB_Success; + + mscHandle->transferRemaining = lba_info_ptr->transferNumber * mscHandle->lengthOfEachLba; + mscHandle->currentOffset = lba_info_ptr->startingLogicalBlockAddress; + + if (direction == USB_IN) + { + error = USB_DeviceMscSend(mscHandle); + } + else + { + error = USB_DeviceMscRecv(mscHandle); + } + return error; +} +#endif diff --git a/usb/device/class/usb_device_msc.h b/usb/device/class/usb_device_msc.h new file mode 100644 index 0000000..0084ea1 --- /dev/null +++ b/usb/device/class/usb_device_msc.h @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_MSC_H__ +#define __USB_DEVICE_MSC_H__ + +#include "usb_device_msc_ufi.h" +/*! + * @addtogroup usb_msc + * @{ + */ +/*! @brief prevent media removal flag */ +#define USB_DEVICE_CONFIG_MSC_SUPPORT_DISK_LOCKING_MECHANISM (0U) +#define USB_DEVICE_CONFIG_MSC_IMPLEMENTING_DISK_DRIVE (0U) +/*! @brief The class code of the MSC class */ +#define USB_DEVICE_CONFIG_MSC_CLASS_CODE (0x08U) + +/*! @brief Bulk-Only Mass Storage Reset (class-specific request) */ +#define USB_DEVICE_MSC_BULK_ONLY_MASS_STORAGE_RESET (0xFFU) +/*! @brief Get Maximum LUN (class-specific request) */ +#define USB_DEVICE_MSC_GET_MAX_LUN (0xFEU) + +/*! @brief CBW dCBWSignature*/ +#define USB_DEVICE_MSC_DCBWSIGNATURE USB_LONG_TO_BIG_ENDIAN(0x55534243U) +/*! @brief CSW dCSSWSignature*/ +#define USB_DEVICE_MSC_DCSWSIGNATURE USB_LONG_TO_BIG_ENDIAN(0x55534253U) +/*! @brief CSW bmCBWFlags bit7 */ +#define USB_DEVICE_MSC_CBW_DIRECTION_BIT (0x80U) +#define USB_DEVICE_MSC_CBW_DIRECTION_SHIFT (7U) +/*! @brief CBW command length*/ +#define USB_DEVICE_MSC_CBW_LENGTH (31U) +/*! @brief CSW command length*/ +#define USB_DEVICE_MSC_CSW_LENGTH (13U) +/*! @brief Command Block Status Values*/ +#define USB_DEVICE_MSC_COMMAND_PASSED (0x00U) +#define USB_DEVICE_MSC_COMMAND_FAILED (0x01U) +#define USB_DEVICE_MSC_PHASE_ERROR (0x02U) +/*! @brief UFI Commands code*/ +#define USB_DEVICE_MSC_INQUIRY_COMMAND (0x12U) +#define USB_DEVICE_MSC_READ_10_COMMAND (0x28U) +#define USB_DEVICE_MSC_READ_12_COMMAND (0xA8U) +#define USB_DEVICE_MSC_REQUEST_SENSE_COMMAND (0x03U) +#define USB_DEVICE_MSC_TEST_UNIT_READY_COMMAND (0x00U) +#define USB_DEVICE_MSC_WRITE_10_COMMAND (0x2AU) +#define USB_DEVICE_MSC_WRITE_12_COMMAND (0xAAU) +#define USB_DEVICE_MSC_PREVENT_ALLOW_MEDIUM_REM_COMMAND (0x1EU) +#define USB_DEVICE_MSC_FORMAT_UNIT_COMMAND (0x04U) +#define USB_DEVICE_MSC_READ_CAPACITY_10_COMMAND (0x25U) +#define USB_DEVICE_MSC_READ_CAPACITY_16_COMMAND (0x9EU) +#define USB_DEVICE_MSC_READ_FORMAT_CAPACITIES_COMMAND (0x23U) +#define USB_DEVICE_MSC_MODE_SENSE_10_COMMAND (0x5AU) +#define USB_DEVICE_MSC_MODE_SENSE_6_COMMAND (0x1AU) +#define USB_DEVICE_MSC_MODE_SELECT_10_COMMAND (0x55U) +#define USB_DEVICE_MSC_MODE_SELECT_6_COMMAND (0x15U) +#define USB_DEVICE_MSC_SEND_DIAGNOSTIC_COMMAND (0x1DU) +#define USB_DEVICE_MSC_VERIFY_COMMAND (0x2FU) +#define USB_DEVICE_MSC_START_STOP_UNIT_COMMAND (0x1BU) + +/*Max transfer length */ +#define USB_DEVICE_MSC_MAX_RECV_TRANSFER_LENGTH (65536U) +#define USB_DEVICE_MSC_MAX_SEND_TRANSFER_LENGTH (65536U) + +/*! @brief Command Block Wrapper(CBW) */ +typedef struct _usb_device_msc_cbw +{ + uint32_t signature; /*!< Byte 0-3 dCBWSignature*/ + uint32_t tag; /*!< Byte 4-7 dCBWTag*/ + uint32_t dataTransferLength; /*!< Byte 8-11 dCBWDataTransferLength*/ + uint8_t flags; /*!< Byte 12 bmCBWFlags*/ + uint8_t logicalUnitNumber; /*!< Byte 13 bCBWLUN*/ + uint8_t cbLength; /*!< Byte 14 bCBWCBLength*/ + uint8_t cbwcb[16]; /*!< Byte 15-30 CBWCB, CBWCB is used to store UFI command*/ +} usb_device_msc_cbw_t; +/*! @brief Command Status Wrapper(CSW) */ +typedef struct _usb_device_msc_csw +{ + uint32_t signature; /*!< Byte 0-3 dCSWSignature*/ + uint32_t tag; /*!< Byte 4-7 dCSWTag*/ + uint32_t dataResidue; /*!< Byte 8-11 dCSWDataResidue*/ + uint8_t cswStatus; /*!< Byte 12 bCSWStatus*/ +} usb_device_msc_csw_t; +/*! @brief Read/write information */ +typedef struct _usb_lba_transfer_information_struct +{ + uint32_t startingLogicalBlockAddress; /*!< The logical block at which the read/write operation shall begin*/ + uint32_t transferNumber; /*!< The number of contiguous logical blocks of data that shall be transferred*/ +} usb_lba_transfer_information_struct_t; +/*! @brief device information */ +typedef struct _usb_device_lba_information_struct +{ + uint32_t totalLbaNumberSupports; /*!< Total blocks number supported*/ + uint32_t lengthOfEachLba; /*!< Length of each block*/ + uint32_t bulkInBufferSize; /*!< Bulk in buffer size*/ + uint32_t bulkOutBufferSize; /*!< Bulk out buffer size*/ + uint8_t logicalUnitNumberSupported; /*!< Number of LUN*/ +} usb_device_lba_information_struct_t; + +/*! @brief Data transfer information */ +typedef struct _usb_device_lba_app_struct +{ + uint32_t offset; /*!< Offset of the block need to access*/ + uint32_t size; /*!< Size of the transferred data*/ + uint8_t *buffer; /*!< Buffer address of the transferred data*/ +} usb_device_lba_app_struct_t; +/*! @brief command and Data transfer information for UFI command*/ +typedef struct _usb_device_ufi_app_struct +{ + uint8_t *cbwcb; /*!< current ufi command block strored in the CBW*/ + uint32_t size; /*!< Size of the transferred data if commmand has data flow*/ + uint8_t *buffer; /*!< Buffer address of the transferred data if commmand has data flow*/ + usb_device_request_sense_data_struct_t *requestSense; /*!< sense data for the current command*/ +} usb_device_ufi_app_struct_t; +/*! @brief The thirteen possible use cases of host expectations and device intent in the absence of +overriding error conditions. */ +typedef struct _usb_device_msc_thirteen_case_struct +{ + uint32_t hostExpectedDataLength; /*!< The number of bytes of data that the host expects to transfer */ + uint32_t deviceExpectedDataLength; /*!< The number of bytes of data that the device expects to transfer */ + uint8_t *buffer; /*!< Data buffer*/ + usb_lba_transfer_information_struct_t lbaInformation; /*!< Read/write information*/ + uint8_t lbaSendRecvSelect; /*!< Whether the command is read or write command*/ + uint8_t hostExpectedDirection; /*!< Host expected data direction*/ + uint8_t deviceExpectedDirection; /*!< Device expected data direction*/ +} usb_device_msc_thirteen_case_struct_t; +/*! @brief stall flag */ +typedef enum +{ + USB_DEVICE_MSC_STALL_IN_CBW = 1U, /*!< Stall in CBW*/ + USB_DEVICE_MSC_STALL_IN_DATA, /*!< Stall in data transfer*/ + USB_DEVICE_MSC_STALL_IN_CSW, /*!< Stall in CSW*/ +} usb_device_msc_stall_type; +/*! @brief Available common EVENT types in MSC class callback */ +typedef enum +{ + kUSB_DeviceMscEventReadResponse = 0x01U, /*!< host has already read the whole data from device or device send is cancelled etc*/ + kUSB_DeviceMscEventWriteResponse, /*!< devcie has already received the data from host or device receive is cancelled etc. */ + kUSB_DeviceMscEventWriteRequest, /*!< Host want to write data to device through write command, devcie need prepare + one buffer to store the data from host*/ + kUSB_DeviceMscEventReadRequest, /*!< Host want to read data from device through read command, device need prepare + one buffer containing data pending for transfer*/ + kUSB_DeviceMscEventGetLbaInformation, /*!< Get device information */ + kUSB_DeviceMscEventFormatComplete, /*!< Format complete */ + kUSB_DeviceMscEventTestUnitReady, /*!< Test Unit Ready command*/ + kUSB_DeviceMscEventInquiry, /*!< Inquiry Command command*/ + kUSB_DeviceMscEventModeSense, /*!< mode sense command*/ + kUSB_DeviceMscEventModeSelect, /*!< mode select command, prepare data buffer and buffer length to store data for + mode select*/ + kUSB_DeviceMscEventModeSelectResponse, /*!< got data of mode select command*/ + kUSB_DeviceMscEventRemovalRequest, /*!< Prevent_allow_medium_command */ + kUSB_DeviceMscEventSendDiagnostic, /*!< Send Diagnostic command */ + kUSB_DeviceMscEventStopEjectMedia, /*!< Start_stop_unit_command */ + +} USB_DeviceMscEvent_t; +/*! @brief The MSC device UFI command status structure */ +typedef struct _usb_device_msc_ufi_struct +{ + usb_device_request_sense_data_struct_t *requestSense; /*!< Request Sense Standard Data*/ + usb_device_msc_thirteen_case_struct_t thirteenCase; /*!< Thirteen possible cases*/ + usb_device_read_capacity_struct_t *readCapacity; /*!< READ CAPACITY Data*/ + usb_device_read_capacity16_data_struct_t *readCapacity16; /*!< READ CAPACITY Data*/ + usb_device_mode_parameters_header_struct_t ModeParametersHeader; /*!< Mode Parameter Header*/ + uint8_t formattedDisk; /*!< *Formatted or unformatted media*/ + uint8_t *formatCapacityData; + /*!< Capacity List*/ +} usb_device_msc_ufi_struct_t; +/*! @brief The MSC device structure */ +typedef struct _usb_device_msc_struct +{ + usb_device_handle handle; /*!< The device handle */ + usb_device_class_config_struct_t *configurationStruct; /*!< The configuration of the class*/ + usb_device_interface_struct_t *interfaceHandle; /*!< Current interface handle */ + uint32_t transferRemaining; /*!< Transfer remaining data */ + uint32_t currentOffset; /*!< Current address offset */ + uint32_t totalLogicalBlockNumber; /*!< Total logical block number of device */ + uint32_t lengthOfEachLba; /*!< Length of logical block */ + uint32_t implementingDiskDrive; /*!< Disk drive*/ + uint32_t bulkInBufferSize; /*!< Bulk in buffer size*/ + uint32_t bulkOutBufferSize; /*!< Bulk out buffer size*/ + + usb_device_msc_cbw_t *mscCbw; /*!< CBW structure */ + usb_device_msc_csw_t *mscCsw; /*!< CSW structure */ + + usb_device_msc_ufi_struct_t mscUfi; /*!< UFI command information structure*/ + + uint8_t dataOutFlag; /*!< CBW indicating bulk out transfer, clear this flag when data transfer done*/ + uint8_t dataInFlag; /*!< CBW indicating bulk in transfer, clear this flag when data transfer done*/ + uint8_t inEndpointStallFlag; /*!< In endpoint stall flag*/ + uint8_t outEndpointStallFlag; /*!< Out endpoint stall flag*/ + uint8_t cbwValidFlag; /*!< The CBW was received after the device had sent a CSW or after a reset ,or else it is + invalid*/ + uint8_t performResetRecover; /*!< Device need reset command from host*/ + uint8_t performResetDoneFlag; /*!< Device has perform reset command */ + uint8_t needInStallFlag; /*!< In endpoint should be stalled*/ + uint8_t needOutStallFlag; /*!< Out endpoint should be stalled*/ + uint8_t cbwPrimeFlag; /*!< CBW prime flag, prime means device MSC has been ready to receive CBW, the bulk out + endpoint has got the prepared buffer*/ + uint8_t cswPrimeFlag; /*!< CSW prime flag, prime means device MSC has been ready to receive CSW, the bulk in + endpoint has got the prepared buffer*/ + uint8_t stallStatus; /*!< Stall status*/ + + uint8_t logicalUnitNumber; /*!< Supported logical units number of device. See bulk only specification 3.2 Get + Maximum LUN + (class-specific request)*/ + uint8_t bulkInEndpoint; /*!< Bulk in endpoint number*/ + uint8_t bulkOutEndpoint; /*!< Bulk out endpoint number*/ + uint8_t alternate; /*!< Current alternate setting of the interface */ + uint8_t configuration; /*!< Current configuration */ + uint8_t interfaceNumber; /*!< The interface number of the class */ + uint8_t inEndpointCswCancelFlag; /*!< the state when calcel function happens, and need send the csw after cancel*/ +} usb_device_msc_struct_t; +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * @name USB device MSC class APIs + * @{ + */ +/*! +* @brief Initializes the MSC class. +* +* This function is used to initialize the MSC class. +* +* @param controllerId The controller ID of the USB IP. See the enumeration usb_controller_index_t. +* @param config The class configuration information. +* @param handle A parameter used to return pointer of the MSC class handle to the caller. +* +* @return A USB error code or kStatus_USB_Success. +*/ +extern usb_status_t USB_DeviceMscInit(uint8_t controllerId, + usb_device_class_config_struct_t *config, + class_handle_t *handle); +/*! + * @brief Deinitializes the device MSC class. + * + * The function deinitializes the device MSC class. + * + * @param handle The MSC class handle received from usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DeviceMscDeinit(class_handle_t handle); + +/*! @}*/ + +extern usb_status_t USB_DeviceMscEvent(void *handle, uint32_t event, void *param); +extern usb_status_t USB_DeviceMscLbaTransfer(usb_device_msc_struct_t *mscHandle, + uint8_t direction, + usb_lba_transfer_information_struct_t *lba_info_ptr); + + + +#ifdef __cplusplus +} +#endif + +/*! @}*/ + +#endif diff --git a/usb/device/class/usb_device_msc_ufi.c b/usb/device/class/usb_device_msc_ufi.c new file mode 100644 index 0000000..fa28fb8 --- /dev/null +++ b/usb/device/class/usb_device_msc_ufi.c @@ -0,0 +1,915 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device.h" + +#include "usb_device_class.h" + +#if USB_DEVICE_CONFIG_MSC +#include "usb_device_msc_ufi.h" +#include "usb_device_msc.h" +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/******************************************************************************* + * Variables + ******************************************************************************/ +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Thirteen possible case check. + * + * This function handle the thirteen possible cases of host expectations and device intent in the absence of + *overriding error conditions. + * + * @param handle The device msc class handle. + * + *@return A USB error code or kStatus_USB_Success. more information about return value ,refer to + *USB_DeviceMscLbaTransfer and USB_DeviceRecvRequest + */ + +usb_status_t USB_DeviceMscUfiThirteenCasesCheck(usb_device_msc_struct_t *mscHandle) +{ + usb_status_t error = kStatus_USB_Success; + usb_device_msc_ufi_struct_t *ufi; + usb_device_msc_thirteen_case_struct_t *mscCheckEvent; + + mscCheckEvent = (usb_device_msc_thirteen_case_struct_t *)&mscHandle->mscUfi.thirteenCase; + ufi = &mscHandle->mscUfi; + /* The following code describe the thirteen possible cases of host + expectations and device intent in absence of overriding error conditions ,refer to bulk-only spec chapter 6.7 + The Thirteen Cases*/ + if (mscCheckEvent->hostExpectedDataLength == 0) + { + /*Host expects no data transfers*/ + mscHandle->mscCsw->dataResidue = 0; + if (mscCheckEvent->deviceExpectedDataLength == 0) + { /*case 1, Device intends to transfer no data*/ + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED; + } + else + { /*case 2 ,Device intends to send data to the host; */ + /*case 3, Device intends to receive data from the host*/ + /*set csw status to 02h*/ + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_PHASE_ERROR; + } + } + else if (mscCheckEvent->hostExpectedDirection) + { + /*Host expects to receive data from the device*/ + if (mscCheckEvent->deviceExpectedDataLength == 0) + { + /*case 4, Device intends to transfer no data*/ + mscHandle->mscCsw->dataResidue = + mscCheckEvent->hostExpectedDataLength - mscCheckEvent->deviceExpectedDataLength; + error = USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, mscCheckEvent->buffer, + mscCheckEvent->deviceExpectedDataLength); + + if (kStatus_USB_Success == error) + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED; + } + else + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED; + ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_MEDIUM_ERROR; + ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_UNRECOVERED_READ_ERROR; + } + error = kStatus_USB_InvalidRequest; + } + else if (mscCheckEvent->deviceExpectedDirection) + { + if (mscCheckEvent->hostExpectedDataLength > mscCheckEvent->deviceExpectedDataLength) + { + /*case 5, device intends to send less data than the host indicated*/ + mscHandle->mscCsw->dataResidue = + mscCheckEvent->hostExpectedDataLength - mscCheckEvent->deviceExpectedDataLength; + + if (ufi->thirteenCase.lbaSendRecvSelect == 1) + { + error = USB_DeviceMscLbaTransfer(mscHandle, USB_IN, &mscCheckEvent->lbaInformation); + } + else + { + error = USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, mscCheckEvent->buffer, + mscCheckEvent->deviceExpectedDataLength); + } + + if (kStatus_USB_Success == error) + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED; + } + else + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED; + ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_MEDIUM_ERROR; + ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_UNRECOVERED_READ_ERROR; + } + error = kStatus_USB_InvalidRequest; + } + else if (mscCheckEvent->hostExpectedDataLength == mscCheckEvent->deviceExpectedDataLength) + { /*case 6*,device intends to send dCBWDataTransferLength excepted by the host*/ + mscHandle->mscCsw->dataResidue = 0; + if (ufi->thirteenCase.lbaSendRecvSelect == 1) + { + error = USB_DeviceMscLbaTransfer(mscHandle, USB_IN, &mscCheckEvent->lbaInformation); + } + else + { + error = USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, mscCheckEvent->buffer, + mscCheckEvent->deviceExpectedDataLength); + } + + if (kStatus_USB_Success == error) + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED; + } + else + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED; + ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_MEDIUM_ERROR; + ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_UNRECOVERED_READ_ERROR; + } + } + else + { /*case 7, device intends to send more data than the host indicated*/ + mscHandle->mscCsw->dataResidue = 0; + + if (ufi->thirteenCase.lbaSendRecvSelect == 1) + { + mscCheckEvent->lbaInformation.transferNumber = + mscCheckEvent->hostExpectedDataLength / mscHandle->lengthOfEachLba; + mscHandle->mscCsw->dataResidue = + mscCheckEvent->hostExpectedDataLength - + mscCheckEvent->lbaInformation.transferNumber * mscHandle->lengthOfEachLba; + error = USB_DeviceMscLbaTransfer(mscHandle, USB_IN, &mscCheckEvent->lbaInformation); + } + else + { + error = USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, mscCheckEvent->buffer, + mscCheckEvent->hostExpectedDataLength); + } + + if (kStatus_USB_Success == error) + { + if (ufi->thirteenCase.lbaSendRecvSelect == 1) + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_PHASE_ERROR; + } + else + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED; + } + } + else + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED; + ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_MEDIUM_ERROR; + ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_UNRECOVERED_READ_ERROR; + } + } + } + else + { + /*case 8, device intends to receive data from the host*/ + mscHandle->mscCsw->dataResidue = mscCheckEvent->hostExpectedDataLength; + error = USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, mscCheckEvent->buffer, 0); + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_PHASE_ERROR; + error = kStatus_USB_InvalidRequest; + } + } + else + { + /*Host expects to send data to the device*/ + if (0 == mscCheckEvent->deviceExpectedDataLength) + { /*case 9,Device intends to transfer no data*/ + USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkOutEndpoint); + mscHandle->mscCsw->dataResidue = mscCheckEvent->hostExpectedDataLength; + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED; + mscHandle->outEndpointStallFlag = 1; + error = kStatus_USB_InvalidRequest; + } + else if (mscCheckEvent->deviceExpectedDirection) + { /*case 10,Device intends to send data to the host*/ + USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkOutEndpoint); + mscHandle->mscCsw->dataResidue = mscCheckEvent->hostExpectedDataLength; + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_PHASE_ERROR; + mscHandle->outEndpointStallFlag = 1; + error = kStatus_USB_InvalidRequest; + } + else + { + if (mscCheckEvent->hostExpectedDataLength > mscCheckEvent->deviceExpectedDataLength) + { /*case 11, device intends to process less than the amount of data that the host indicated*/ + mscHandle->mscCsw->dataResidue = + mscCheckEvent->hostExpectedDataLength - mscCheckEvent->deviceExpectedDataLength; + + if (ufi->thirteenCase.lbaSendRecvSelect == 1) + { + error = USB_DeviceMscLbaTransfer(mscHandle, USB_OUT, &mscCheckEvent->lbaInformation); + } + else + { + error = USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, mscCheckEvent->buffer, + mscCheckEvent->deviceExpectedDataLength); + } + + if (kStatus_USB_Success == error) + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED; + } + else + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED; + ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_MEDIUM_ERROR; + ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_WRITE_FAULT; + } + error = kStatus_USB_InvalidRequest; + } + else if (mscCheckEvent->hostExpectedDataLength == mscCheckEvent->deviceExpectedDataLength) + { /*case 12,device intends to process equal to the amount of data that the host indicated*/ + mscHandle->mscCsw->dataResidue = 0; + if (ufi->thirteenCase.lbaSendRecvSelect == 1) + { + error = USB_DeviceMscLbaTransfer(mscHandle, USB_OUT, &mscCheckEvent->lbaInformation); + } + else + { + error = USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, mscCheckEvent->buffer, + mscCheckEvent->deviceExpectedDataLength); + } + if (kStatus_USB_Success == error) + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED; + } + else + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED; + ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_MEDIUM_ERROR; + ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_WRITE_FAULT; + } + } + else + { /*case 13,device intends to process more data than the host indicated*/ + mscHandle->mscCsw->dataResidue = 0; + if (ufi->thirteenCase.lbaSendRecvSelect == 1) + { + mscCheckEvent->lbaInformation.transferNumber = + mscCheckEvent->hostExpectedDataLength / mscHandle->lengthOfEachLba; + mscHandle->mscCsw->dataResidue = + mscCheckEvent->hostExpectedDataLength - + mscCheckEvent->lbaInformation.transferNumber * mscHandle->lengthOfEachLba; + error = USB_DeviceMscLbaTransfer(mscHandle, USB_OUT, &mscCheckEvent->lbaInformation); + } + else + { + error = USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, mscCheckEvent->buffer, + mscCheckEvent->hostExpectedDataLength); + } + + if (kStatus_USB_Success == error) + { + if (ufi->thirteenCase.lbaSendRecvSelect == 1) + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_PHASE_ERROR; + } + else + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED; + } + } + else + { + ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_MEDIUM_ERROR; + ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_WRITE_FAULT; + } + } + } + } + return error; +} + +/*! + * @brief request sense command. + * + * The REQUEST SENSE command instructs the UFI device to transfer sense data to the host for the specified logical + *unit. + * + * @param handle The device msc class handle. + * + *@return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceMscUfiRequestSenseCommand(usb_device_msc_struct_t *mscHandle) +{ + usb_device_msc_ufi_struct_t *ufi = NULL; + usb_status_t error; + + ufi = &mscHandle->mscUfi; + ufi->thirteenCase.deviceExpectedDataLength = USB_DEVICE_MSC_UFI_REQ_SENSE_DATA_LENGTH; + ufi->thirteenCase.deviceExpectedDirection = USB_IN; + ufi->thirteenCase.buffer = (uint8_t *)ufi->requestSense; + ufi->thirteenCase.lbaSendRecvSelect = 0; + error = USB_DeviceMscUfiThirteenCasesCheck(mscHandle); + + return error; +} + +/*! + * @brief inquiry command. + * + * The INQUIRY command requests that information regarding parameters of the UFI device itself be sent to the host. + * + * @param handle The device msc class handle. + * + *@return A USB error code or kStatus_USB_Success. +*/ +usb_status_t USB_DeviceMscUfiInquiryCommand(usb_device_msc_struct_t *mscHandle) +{ + usb_device_msc_ufi_struct_t *ufi = NULL; + usb_status_t error; + usb_device_ufi_app_struct_t temp; + + ufi = &mscHandle->mscUfi; + temp.requestSense = ufi->requestSense; + temp.cbwcb = &mscHandle->mscCbw->cbwcb[0]; + temp.size = 0U; + temp.buffer = NULL; + + if (mscHandle->configurationStruct->classCallback != NULL) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventInquiry, + (void *)&temp); + } + ufi->thirteenCase.deviceExpectedDataLength = temp.size; + ufi->thirteenCase.deviceExpectedDirection = USB_IN; + ufi->thirteenCase.buffer = temp.buffer; + ufi->thirteenCase.lbaSendRecvSelect = 0; + + error = USB_DeviceMscUfiThirteenCasesCheck(mscHandle); + return error; +} + +/*! + * @brief read command. + * + * The READ(10),READ(12) command requests that the UFI device transfer data to the host. + * + * @param handle The device msc class handle. + * + *@return A USB error code or kStatus_USB_Success. +*/ +usb_status_t USB_DeviceMscUfiReadCommand(usb_device_msc_struct_t *mscHandle) +{ + usb_device_msc_ufi_struct_t *ufi = NULL; + usb_status_t error; + uint32_t logicalBlockAddress = 0; + uint32_t lbaTransferLength = 0; + + ufi = &mscHandle->mscUfi; + + logicalBlockAddress = ((uint32_t)mscHandle->mscCbw->cbwcb[2] << 24); + logicalBlockAddress |= ((uint32_t)mscHandle->mscCbw->cbwcb[3] << 16); + logicalBlockAddress |= ((uint32_t)mscHandle->mscCbw->cbwcb[4] << 8); + logicalBlockAddress |= ((uint32_t)mscHandle->mscCbw->cbwcb[5]); + + if (mscHandle->mscCbw->cbwcb[0] == USB_DEVICE_MSC_READ_10_COMMAND) + { + lbaTransferLength = (uint16_t)((uint16_t)mscHandle->mscCbw->cbwcb[7] << 8); + lbaTransferLength |= (uint16_t)mscHandle->mscCbw->cbwcb[8]; + } + else if (mscHandle->mscCbw->cbwcb[0] == USB_DEVICE_MSC_READ_12_COMMAND) + { + lbaTransferLength = ((uint32_t)mscHandle->mscCbw->cbwcb[6] << 24); + lbaTransferLength |= ((uint32_t)mscHandle->mscCbw->cbwcb[7] << 16); + lbaTransferLength |= ((uint32_t)mscHandle->mscCbw->cbwcb[8] << 8); + lbaTransferLength |= ((uint32_t)mscHandle->mscCbw->cbwcb[9]); + } + else + { + } + + ufi->thirteenCase.deviceExpectedDirection = USB_IN; + ufi->thirteenCase.deviceExpectedDataLength = mscHandle->lengthOfEachLba * lbaTransferLength; + ufi->thirteenCase.buffer = NULL; + + ufi->thirteenCase.lbaSendRecvSelect = 1; + ufi->thirteenCase.lbaInformation.startingLogicalBlockAddress = logicalBlockAddress; + ufi->thirteenCase.lbaInformation.transferNumber = lbaTransferLength; + + error = USB_DeviceMscUfiThirteenCasesCheck(mscHandle); + return error; +} + +/*! + * @brief write command. + * + * The WRITE(10),WRITE(12) command requests that the UFI device write the data transferred by the host to the medium. + * + * @param handle The device msc class handle. + * + *@return A USB error code or kStatus_USB_Success. +*/ +usb_status_t USB_DeviceMscUfiWriteCommand(usb_device_msc_struct_t *mscHandle) +{ + usb_device_msc_ufi_struct_t *ufi = NULL; + usb_status_t error; + uint32_t logicalBlockAddress = 0; + uint32_t lbaTransferLength = 0; + + ufi = &mscHandle->mscUfi; + + logicalBlockAddress = ((uint32_t)mscHandle->mscCbw->cbwcb[2] << 24); + logicalBlockAddress |= ((uint32_t)mscHandle->mscCbw->cbwcb[3] << 16); + logicalBlockAddress |= ((uint32_t)mscHandle->mscCbw->cbwcb[4] << 8); + logicalBlockAddress |= ((uint32_t)mscHandle->mscCbw->cbwcb[5]); + + if (mscHandle->mscCbw->cbwcb[0] == USB_DEVICE_MSC_WRITE_10_COMMAND) + { + lbaTransferLength = (uint16_t)((uint16_t)mscHandle->mscCbw->cbwcb[7] << 8); + lbaTransferLength |= (uint16_t)mscHandle->mscCbw->cbwcb[8]; + } + else if (mscHandle->mscCbw->cbwcb[0] == USB_DEVICE_MSC_WRITE_12_COMMAND) + { + lbaTransferLength = ((uint32_t)mscHandle->mscCbw->cbwcb[6] << 24); + lbaTransferLength |= ((uint32_t)mscHandle->mscCbw->cbwcb[7] << 16); + lbaTransferLength |= ((uint32_t)mscHandle->mscCbw->cbwcb[8] << 8); + lbaTransferLength |= ((uint32_t)mscHandle->mscCbw->cbwcb[9]); + } + else + { + } + ufi->thirteenCase.deviceExpectedDirection = USB_OUT; + ufi->thirteenCase.deviceExpectedDataLength = mscHandle->lengthOfEachLba * lbaTransferLength; + ufi->thirteenCase.buffer = NULL; + + ufi->thirteenCase.lbaSendRecvSelect = 1; + ufi->thirteenCase.lbaInformation.startingLogicalBlockAddress = logicalBlockAddress; + ufi->thirteenCase.lbaInformation.transferNumber = lbaTransferLength; + + error = USB_DeviceMscUfiThirteenCasesCheck(mscHandle); + return error; +} + +/*! + * @brief test unit ready command. + * + * The TEST UNIT READY command provides a means to check if the UFI device is ready. + * + * @param handle The device msc class handle. + * + *@return A USB error code or kStatus_USB_Success. +*/ +usb_status_t USB_DeviceMscUfiTestUnitReadyCommand(usb_device_msc_struct_t *mscHandle) +{ + usb_device_msc_ufi_struct_t *ufi = NULL; + usb_status_t error; + usb_device_ufi_app_struct_t temp; + + ufi = &mscHandle->mscUfi; + temp.requestSense = ufi->requestSense; + temp.cbwcb = &mscHandle->mscCbw->cbwcb[0]; + + ufi->thirteenCase.deviceExpectedDataLength = 0; + ufi->thirteenCase.deviceExpectedDirection = USB_IN; + ufi->thirteenCase.buffer = NULL; + ufi->thirteenCase.lbaSendRecvSelect = 0; + + error = USB_DeviceMscUfiThirteenCasesCheck(mscHandle); + + if (mscHandle->configurationStruct->classCallback != NULL) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventTestUnitReady, + (void *)&temp); + } + return error; +} + +/*! + * @brief verify command. + * + * The VERIFY command requests that the UFI device verify the data on the medium. + * + * @param handle The device msc class handle. + * + *@return A USB error code or kStatus_USB_Success. +*/ +usb_status_t USB_DeviceMscUfiVerifyCommand(usb_device_msc_struct_t *mscHandle) +{ + usb_device_msc_ufi_struct_t *ufi = NULL; + usb_status_t error; + + ufi = &mscHandle->mscUfi; + + ufi->thirteenCase.deviceExpectedDataLength = 0; + ufi->thirteenCase.deviceExpectedDirection = USB_IN; + ufi->thirteenCase.buffer = NULL; + ufi->thirteenCase.lbaSendRecvSelect = 0; + + error = USB_DeviceMscUfiThirteenCasesCheck(mscHandle); + return error; +} + +/*! + * @brief mode sense command. + * + * The MODE SENSE command allows the UFI device to report medium or device parameters to the host. + * + * @param handle The device msc class handle. + * + *@return A USB error code or kStatus_USB_Success. +*/ +usb_status_t USB_DeviceMscUfiModeSenseCommand(usb_device_msc_struct_t *mscHandle) +{ + usb_device_msc_ufi_struct_t *ufi = NULL; + usb_status_t error; + + usb_device_ufi_app_struct_t temp; + + ufi = &mscHandle->mscUfi; + temp.requestSense = ufi->requestSense; + temp.cbwcb = &mscHandle->mscCbw->cbwcb[0]; + temp.size = 0U; + temp.buffer = NULL; + + if (mscHandle->configurationStruct->classCallback != NULL) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventModeSense, + (void *)&temp); + } + ufi->thirteenCase.deviceExpectedDataLength = temp.size; + ufi->thirteenCase.deviceExpectedDirection = USB_IN; + ufi->thirteenCase.buffer = temp.buffer; + ufi->thirteenCase.lbaSendRecvSelect = 0; + + error = USB_DeviceMscUfiThirteenCasesCheck(mscHandle); + return error; +} + +/*! + * @brief mode select command. + * + * The MODE SELECT command allows the host to specify medium or device parameters to the UFI device. + * + * @param handle The device msc class handle. + * + *@return A USB error code or kStatus_USB_Success. +*/ +usb_status_t USB_DeviceMscUfiModeSelectCommand(usb_device_msc_struct_t *mscHandle) +{ + usb_device_msc_ufi_struct_t *ufi = NULL; + usb_status_t error = kStatus_USB_TransferFailed; + + usb_device_ufi_app_struct_t temp; + + ufi = &mscHandle->mscUfi; + temp.requestSense = ufi->requestSense; + temp.cbwcb = &mscHandle->mscCbw->cbwcb[0]; + temp.buffer = NULL; + temp.size = 0; + if (mscHandle->configurationStruct->classCallback != NULL) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventModeSelect, + (void *)&temp); + } + + ufi->thirteenCase.deviceExpectedDataLength = temp.size; + ufi->thirteenCase.deviceExpectedDirection = USB_OUT; + ufi->thirteenCase.buffer = temp.buffer; + ufi->thirteenCase.lbaSendRecvSelect = 0; + + error = USB_DeviceMscUfiThirteenCasesCheck(mscHandle); + + if (mscHandle->mscCbw->cbwcb[1] & 0x01) + { + ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_ILLEGAL_REQUEST; + ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_INVALID_FIELD_IN_COMMAND_PKT; + } + return error; +} + +/*! + * @brief read capacity command. + * + * The READ CAPACITIY command allows the host to request capacities of the currently installed medium. + * + * @param handle The device msc class handle. + * + *@return A USB error code or kStatus_USB_Success. +*/ +usb_status_t USB_DeviceMscUfiReadCapacityCommand(usb_device_msc_struct_t *mscHandle) +{ + usb_device_msc_ufi_struct_t *ufi = NULL; + usb_status_t error = kStatus_USB_TransferFailed; + + ufi = &mscHandle->mscUfi; + + if (mscHandle->mscCbw->cbwcb[0] == USB_DEVICE_MSC_READ_CAPACITY_10_COMMAND) + { + ufi->thirteenCase.deviceExpectedDataLength = USB_DEVICE_MSC_UFI_READ_CAPACITY_DATA_LENGTH; + ufi->thirteenCase.buffer = (uint8_t *)(ufi->readCapacity); + } + else + { + ufi->thirteenCase.deviceExpectedDataLength = USB_DEVICE_MSC_UFI_READ_CAPACITY16_DATA_LENGTH; + ufi->thirteenCase.buffer = (uint8_t *)(ufi->readCapacity16); + } + ufi->thirteenCase.deviceExpectedDirection = USB_IN; + ufi->thirteenCase.lbaSendRecvSelect = 0; + + error = USB_DeviceMscUfiThirteenCasesCheck(mscHandle); + return error; +} + +/*! + * @brief read format capacity command. + * + * The READ FORMAT CAPACITIES command allows the host to request a list of the possible capacities that +* can be formatted on the currently installed medium. + * + * @param handle The device msc class handle. + * + *@return A USB error code or kStatus_USB_Success. +*/ +usb_status_t USB_DeviceMscUfiReadFormatCapacityCommand(usb_device_msc_struct_t *mscHandle) +{ + usb_device_msc_ufi_struct_t *ufi = NULL; + usb_status_t error = kStatus_USB_TransferFailed; + usb_device_current_max_capacity_descriptor_struct_t current_max_head; + usb_device_formattable_capacity_descriptor_struct_t formattable_capacity_head; + usb_device_capacity_list_header_struct_t capacityListHead = {{0x00, 0x00, 0x00}, 0x00}; + uint32_t response_size; + uint16_t allocation_length; + uint8_t num_formattable_cap_desc; + uint8_t descriptor_code; + uint8_t count = 0; + uint8_t i = 0; + uint8_t j = 0; + uint8_t *ptr; + + ufi = &mscHandle->mscUfi; + allocation_length = (uint16_t)((uint8_t)(mscHandle->mscCbw->cbwcb[7] << 8) | mscHandle->mscCbw->cbwcb[8]); + /*reference ufi command spec table-33 Descriptor Code definition*/ + num_formattable_cap_desc = (uint8_t)(ufi->formattedDisk ? (mscHandle->implementingDiskDrive ? 0x02 : 0x03) : 0x00); + + formattable_capacity_head.blockNumber = USB_LONG_TO_BIG_ENDIAN(mscHandle->totalLogicalBlockNumber); + formattable_capacity_head.blockLength = USB_LONG_TO_BIG_ENDIAN(mscHandle->lengthOfEachLba); + + descriptor_code = + (uint8_t)(ufi->formattedDisk ? USB_DEVICE_MSC_UFI_FORMATTED_MEDIA : USB_DEVICE_MSC_UFI_UNFORMATTED_MEDIA); + capacityListHead.capacityListLength = num_formattable_cap_desc * 8; + current_max_head.blockNumber = USB_LONG_TO_BIG_ENDIAN(mscHandle->totalLogicalBlockNumber); + current_max_head.descriptorCodeBlockLength = + USB_LONG_TO_BIG_ENDIAN(((uint8_t)(descriptor_code << 24) | mscHandle->lengthOfEachLba)); + + response_size = sizeof(usb_device_capacity_list_header_struct_t) + + sizeof(usb_device_current_max_capacity_descriptor_struct_t) + + sizeof(usb_device_formattable_capacity_descriptor_struct_t) * num_formattable_cap_desc; + + if (response_size > allocation_length) + { + response_size = allocation_length; + } + if (sizeof(ufi->formatCapacityData) < response_size) + { +#if (defined(_USB_DEBUG) && _USB_DEBUG) + usb_echo("format_capacity_response_data buff size less than need\n"); +#endif + } + + ptr = (uint8_t *)&capacityListHead; + for (count = 0; count < sizeof(capacityListHead); count++) + { + ufi->formatCapacityData[count] = ptr[i++]; + } + ptr = (uint8_t *)¤t_max_head; + i = 0; + for (; i < sizeof(current_max_head); count++) + { + ufi->formatCapacityData[count] = ptr[i++]; + } + + if (ufi->formattedDisk) + { + for (i = 0; i < num_formattable_cap_desc; i++) + { + ptr = (uint8_t *)&formattable_capacity_head; + + for (; count < sizeof(formattable_capacity_head); count++) + { + ufi->formatCapacityData[count] = ptr[j++]; + } + } + } + + ufi->thirteenCase.deviceExpectedDataLength = response_size; + ufi->thirteenCase.deviceExpectedDirection = USB_IN; + ufi->thirteenCase.buffer = (uint8_t *)ufi->formatCapacityData; + ufi->thirteenCase.lbaSendRecvSelect = 0; + + error = USB_DeviceMscUfiThirteenCasesCheck(mscHandle); + + return error; +} + +/*! + * @brief format unit command. + * + * The Host sends the FORMAT UNIT command to physically format one track of a diskette according to the selected + *options. + * + * @param handle The device msc class handle. + * + *@return A USB error code or kStatus_USB_Success. +*/ +usb_status_t USB_DeviceMscUfiFormatUnitCommand(usb_device_msc_struct_t *mscHandle) +{ + usb_device_msc_ufi_struct_t *ufi = NULL; + usb_status_t error; + + ufi = &mscHandle->mscUfi; + + ufi->thirteenCase.deviceExpectedDataLength = 0; + ufi->thirteenCase.deviceExpectedDirection = USB_IN; + ufi->thirteenCase.buffer = NULL; + ufi->thirteenCase.lbaSendRecvSelect = 0; + + error = USB_DeviceMscUfiThirteenCasesCheck(mscHandle); + + if (mscHandle->mscCsw->cswStatus != USB_DEVICE_MSC_PHASE_ERROR) + { + if ((mscHandle->mscCbw->cbwcb[1] & 0x1f) == 0x17) + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED; + } + else + { + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED; + ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_ILLEGAL_REQUEST; + ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_INVALID_FIELD_IN_COMMAND_PKT; + } + } + return error; +} + +/*! + * @brief prevent allow medium command. + * + * This command tells the UFI device to enable or disable the removal of the medium in the logical unit. + * + * @param handle The device msc class handle. + * + *@return A USB error code or kStatus_USB_Success. +*/ +usb_status_t USB_DeviceMscUfiPreventAllowMediumCommand(usb_device_msc_struct_t *mscHandle) +{ + usb_device_msc_ufi_struct_t *ufi = NULL; + usb_status_t error; + usb_device_ufi_app_struct_t temp; + + ufi = &mscHandle->mscUfi; + temp.requestSense = ufi->requestSense; + temp.cbwcb = &mscHandle->mscCbw->cbwcb[0]; + + ufi->thirteenCase.deviceExpectedDataLength = 0; + ufi->thirteenCase.deviceExpectedDirection = USB_IN; + ufi->thirteenCase.buffer = NULL; + ufi->thirteenCase.lbaSendRecvSelect = 0; + + error = USB_DeviceMscUfiThirteenCasesCheck(mscHandle); + + if (mscHandle->configurationStruct->classCallback != NULL) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventRemovalRequest, + (void *)&temp); + } + + return error; +} + +/*! + * @brief send diagnostic command. + * + * The SEND DIAGNOSTIC command requests the UFI device to do a reset or perform a self-test. + * + * @param handle The device msc class handle. + * + *@return A USB error code or kStatus_USB_Success. +*/ +usb_status_t USB_DeviceMscUfiSendDiagnosticCommand(usb_device_msc_struct_t *mscHandle) +{ + usb_device_msc_ufi_struct_t *ufi = NULL; + usb_status_t error; + usb_device_ufi_app_struct_t temp; + + ufi = &mscHandle->mscUfi; + temp.requestSense = ufi->requestSense; + temp.cbwcb = &mscHandle->mscCbw->cbwcb[0]; + + ufi->thirteenCase.deviceExpectedDataLength = 0; + ufi->thirteenCase.deviceExpectedDirection = USB_IN; + ufi->thirteenCase.buffer = NULL; + ufi->thirteenCase.lbaSendRecvSelect = 0; + + error = USB_DeviceMscUfiThirteenCasesCheck(mscHandle); + if (mscHandle->configurationStruct->classCallback != NULL) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventSendDiagnostic, + (void *)&temp); + } + return error; +} + +/*! + * @brief start stop unit command. + * + * The START-STOP UNIT command instructs the UFI device to enable or disable media access operations. + * + * @param handle The device msc class handle. + * + *@return A USB error code or kStatus_USB_Success. +*/ +usb_status_t USB_DeviceMscUfiStartStopUnitCommand(usb_device_msc_struct_t *mscHandle) +{ + usb_device_msc_ufi_struct_t *ufi = NULL; + usb_status_t error; + usb_device_ufi_app_struct_t temp; + + ufi = &mscHandle->mscUfi; + temp.requestSense = ufi->requestSense; + temp.cbwcb = &mscHandle->mscCbw->cbwcb[0]; + + ufi->thirteenCase.deviceExpectedDataLength = 0; + ufi->thirteenCase.deviceExpectedDirection = USB_IN; + ufi->thirteenCase.buffer = NULL; + ufi->thirteenCase.lbaSendRecvSelect = 0; + + error = USB_DeviceMscUfiThirteenCasesCheck(mscHandle); + + if (mscHandle->mscCsw->cswStatus != USB_DEVICE_MSC_PHASE_ERROR) + { + if (mscHandle->configurationStruct->classCallback != NULL) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventStopEjectMedia, + (void *)&temp); + } + } + + return error; +} + +/*! + * @brief un-support command. + * + * Handle unsupported command . + * + * @param handle The device msc class handle. + * + *@return A USB error code or kStatus_USB_Success. +*/ +usb_status_t USB_DeviceMscUfiUnsupportCommand(usb_device_msc_struct_t *mscHandle) +{ + usb_device_msc_ufi_struct_t *ufi = NULL; + usb_status_t error; + ufi = &mscHandle->mscUfi; + + mscHandle->mscCsw->dataResidue = 0; + mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED; + + ufi->thirteenCase.deviceExpectedDataLength = 0; + ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_ILLEGAL_REQUEST; + ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_INVALID_COMMAND_OPCODE; + ufi->requestSense->additionalSenseQualifer = USB_DEVICE_MSC_UFI_NO_SENSE; + + error = USB_DeviceMscUfiThirteenCasesCheck(mscHandle); + + return error; +} + +#endif diff --git a/usb/device/class/usb_device_msc_ufi.h b/usb/device/class/usb_device_msc_ufi.h new file mode 100644 index 0000000..656b6cd --- /dev/null +++ b/usb/device/class/usb_device_msc_ufi.h @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _USB_MSC_UFI_H +#define _USB_MSC_UFI_H 1 +/*! + * @addtogroup msc_ufi + * @{ + */ +/*Sense Key of REQUEST SENSE command, refer to UFI specification chapter 5*/ +/*! @brief Indicates that there is no specific sense key information to be reported*/ +#define USB_DEVICE_MSC_UFI_NO_SENSE 0x00U +/*! @brief Indicates that the last command completed successfully with some recovery action performed by the UFI + * device*/ +#define USB_DEVICE_MSC_UFI_RECOVERED_ERROR 0x01U +/*! @brief Indicates that the UFI device cannot be accessed*/ +#define USB_DEVICE_MSC_UFI_NOT_READY 0x02U +/*! @brief Indicates that the command terminated with a non-recovered +error condition that was probably caused by a flaw in the medium or an error in the +recorded data*/ +#define USB_DEVICE_MSC_UFI_MEDIUM_ERROR 0x03U +/*! @brief Indicates that the UFI device detected a non-recoverable hardware failure while performing the command or + * during a self test*/ +#define USB_DEVICE_MSC_UFI_HARDWARE_ERROR 0x04U +/*! @brief Indicates that there was an illegal parameter in the Command +Packet or in the additional parameters supplied as data for some commands*/ +#define USB_DEVICE_MSC_UFI_ILLEGAL_REQUEST 0x05U +/*! @brief Indicates that the removable medium may have been changed or the UFI device has been reset*/ +#define USB_DEVICE_MSC_UFI_UNIT_ATTENTION 0x06U +/*! @brief Indicates that a command that writes the medium was attempted on a block that is protected from this + * operation*/ +#define USB_DEVICE_MSC_UFI_DATA_PROTECT 0x07U +/*! @brief Indicates that a write-once device or a sequential-access device +encountered blank medium or format-defined end-of-data indication while reading or +a write-once device encountered a non-blank medium while writing*/ +#define USB_DEVICE_MSC_UFI_BLANK_CHECK 0x08U +/*! @brief This sense key is available for reporting vendor-specific conditions*/ +#define USB_DEVICE_MSC_UFI_VENDOR_SPECIFIC_ERROR 0x09U +/*! @brief Indicates that the UFI device has aborted the command +The host may be able to recover by trying the command again*/ +#define USB_DEVICE_MSC_UFI_ABORTED_COMMAND 0x0BU +/*! @brief Indicates that a buffered peripheral device has reached the +end-of-partition and data may remain in the buffer that has not been written to the medium*/ +#define USB_DEVICE_MSC_UFI_VOLUME_OVERFLOW 0x0DU +/*! @brief Indicates that the source data did not match the data read from the medium*/ +#define USB_DEVICE_MSC_UFI_MISCOMPARE 0x0EU + +/*! @brief Invalid command operation code*/ +#define USB_DEVICE_MSC_UFI_INVALID_COMMAND_OPCODE 0x20U +/*! @brief Write fault*/ +#define USB_DEVICE_MSC_UFI_WRITE_FAULT 0x03U +/*! @brief Not recovered read error*/ +#define USB_DEVICE_MSC_UFI_UNRECOVERED_READ_ERROR 0x11U +/*! @brief Unknown error*/ +#define USB_DEVICE_MSC_UFI_UNKNOWN_ERROR 0xFFU +/*! @brief Invalid field in command packet*/ +#define USB_DEVICE_MSC_UFI_INVALID_FIELD_IN_COMMAND_PKT 0x24U +/*! @brief Invalid logical block address out of range*/ +#define USB_DEVICE_MSC_UFI_LBA_OUT_OF_RANGE 0x21U + +/*! @brief Valid error code, 70h indicate current errors*/ +#define USB_DEVICE_MSC_UFI_REQ_SENSE_VALID_ERROR_CODE 0x70U +/*! @brief The UFI device sets the value of this field to ten, to indicate that ten more bytes of sense data follow this + * field*/ +#define USB_DEVICE_MSC_UFI_REQ_SENSE_ADDITIONAL_SENSE_LEN 0x0AU + +/*! @brief Prevent media removal flag*/ +#define USB_DEVICE_MSC_UFI_PREVENT_ALLOW_REMOVAL_MASK 0x01U +/*! @brief LoEj Start flag */ +#define USB_DEVICE_MSC_UFI_LOAD_EJECT_START_MASK 0x03U + +/*! @brief Formatted Media - Current media capacity */ +#define USB_DEVICE_MSC_UFI_FORMATTED_MEDIA 0x02U +/*! @brief Unformatted Media - Maximum formatting capacity for this cartridge*/ +#define USB_DEVICE_MSC_UFI_UNFORMATTED_MEDIA 0x01U +/*! @brief No Cartridge in Drive - Maximum formating capacity for any cartridge*/ +#define USB_DEVICE_MSC_UFI_NO_CARTRIDGE_IN_DRIVE 0x03U + +/*! @brief INQUIRY Data length of INQUIRY Command*/ +#define USB_DEVICE_MSC_UFI_INQUIRY_ALLOCATION_LENGTH 0x24U +/*! @brief Request Sense Data length of REQUEST SENSE Command*/ +#define USB_DEVICE_MSC_UFI_REQ_SENSE_DATA_LENGTH 18U +/*! @brief READ CAPACITY Data length of READ CAPACITY Command*/ +#define USB_DEVICE_MSC_UFI_READ_CAPACITY_DATA_LENGTH 0x08U +/*! @brief READ CAPACITY Data length of READ CAPACITY Command*/ +#define USB_DEVICE_MSC_UFI_READ_CAPACITY16_DATA_LENGTH 0x0CU + +/*! @brief Reserved*/ +#define USB_DEVICE_MSC_UFI_PERIPHERAL_QUALIFIER 0U +/*! @brief Peripheral Device Type shift*/ +#define USB_DEVICE_MSC_UFI_PERIPHERAL_QUALIFIER_SHIFT 5U +/*! @brief Version value*/ +#define USB_DEVICE_MSC_UFI_VERSIONS 4U +/*! @brief Peripheral Device Type value of INQUIRY Data*/ +#define USB_DEVICE_MSC_UFI_PERIPHERAL_DEVICE_TYPE 0x00U +/*! @brief Removable Media Bit value, this shall be set to one to indicate removable media*/ +#define USB_DEVICE_MSC_UFI_REMOVABLE_MEDIUM_BIT 1U +/*! @brief Removable Media Bit shift*/ +#define USB_DEVICE_MSC_UFI_REMOVABLE_MEDIUM_BIT_SHIFT 7U +/*! @brief Additional Length*/ +#define USB_DEVICE_MSC_UFI_ADDITIONAL_LENGTH 0x20U + +/*! @brief UFI inquiry command structure*/ +typedef struct _usb_device_inquiry_command_struct +{ + uint8_t operationCode; /*!< Operation Code*/ + uint8_t logicalUnitNumber; /*!< Specifies the logical unit (0~7) for which Inquiry data should be returned*/ + uint8_t pageCode; /*!< Page Code*/ + uint8_t reserved; /*!< Reserved*/ + uint8_t allocationLength; /*!< Specifies the maximum number of bytes of inquiry data to be returned*/ + uint8_t reserved1[7]; /*!< Reserved*/ +} usb_device_inquiry_command_struct_t; + +/*! @brief UFI request sense command structure*/ +typedef struct _usb_device_request_sense_command_struct +{ + uint8_t operationCode; /*!< Operation Code*/ + uint8_t logicalUnitNumber; /*!< Logical Unit Number*/ + uint8_t reserved[2]; /*!< reserved*/ + uint8_t allocationLength; /*!< Allocation Length*/ + uint8_t reserved1[7]; /*!< reserved*/ +} usb_device_request_sense_command_struct_t; + +/*! @brief UFI read format capacities command structure*/ +typedef struct _usb_device_read_format_capacities_command_struct +{ + uint8_t operationCode; /*!< Operation Code*/ + uint8_t logicalUnitNumber; /*!< Logical Unit Number*/ + uint8_t reserved[5]; /*!< reserved*/ + uint16_t allocationLength; /*!< Allocation Length*/ + uint8_t reserved1[3]; /*!< reserved*/ +} usb_device_read_format_capacities_command_struct_t; + +/*! @brief UFI read capacities command structure*/ +typedef struct _usb_device_read_capacities_command_struct +{ + uint8_t operationCode; /*!< Operation Code*/ + uint8_t logicalUnitNumber; /*!< Logical Unit Number*/ + uint32_t lba; /*!< Logical Block Address*/ + uint8_t reserved[2]; /*!< Reserved*/ + uint8_t pmi; /*!< This bit should be set to zero for UFI*/ + uint8_t reserved1[3]; /*!< Reserved*/ +} usb_device_read_capacities_command_struct_t; + +/*! @brief UFI read write 10 structure*/ +typedef struct _usb_device_read_write_10_command_struct +{ + uint8_t operationCode; /*!< Operation Code*/ + uint8_t lunDpoFuaReladr; /*!< Logical Unit Number DPO FUA RelAdr*/ + uint32_t lba; /*!< Logical Block Address*/ + uint8_t reserved; /*!< Reserved*/ + uint8_t transferLengthMsb; /*!< Transfer Length (MSB)*/ + uint8_t transferLengthLsb; /*!< Transfer Length (LSB)*/ + uint8_t reserved1[3]; /*!< Reserved*/ +} usb_device_read_write_10_command_struct_t; + +/*! @brief UFI inquiry data format structure*/ +typedef struct _usb_device_inquiry_data_fromat_struct +{ + uint8_t peripheralDeviceType; /*!< Peripheral Device Type*/ + uint8_t rmb; /*!< Removable Media Bit*/ + uint8_t versions; /*!< ISO Version, ECMA Version, ANSI Version*/ + uint8_t responseDataFormat; /*!< Response Data Format*/ + uint8_t additionalLength; /*!< The Additional Length field shall specify the length in bytes of the parameters*/ + uint8_t reserved[3]; /*!< reserved*/ + uint8_t vendorInformatin[8]; /*!< Vendor Identification*/ + uint8_t productId[16]; /*!< Product Identification*/ + uint8_t productVersionLevel[4]; /*!< Product Revision Level*/ +} usb_device_inquiry_data_fromat_struct_t; + +/*! @brief UFI request sense data structure*/ +typedef struct _usb_device_request_sense_data_struct +{ + uint8_t validErrorCode; /*!< Error Code*/ + uint8_t reserved; /*!< reserved*/ + uint8_t senseKey; /*!< Sense Key*/ + uint8_t information[4]; /*!< Information*/ + uint8_t additionalSenseLength; /*!< Additional Sense Length*/ + uint8_t reserved1[4]; /*!< reserved*/ + uint8_t additionalSenseCode; /*!< Additional Sense Code*/ + uint8_t additionalSenseQualifer; /*!< Additional Sense Code Qualifier*/ + uint8_t reserved2[4]; /*!< reserved*/ +} usb_device_request_sense_data_struct_t; + +/*! @brief UFI read capacity data structure*/ +typedef struct _usb_device_read_capacity_struct +{ + uint32_t lastLogicalBlockAddress; /*!< Last Logical Block Address*/ + uint32_t blockSize; /*!< Block Length In Bytes*/ +} usb_device_read_capacity_struct_t; + +/*! @brief UFI read capacity data structure*/ +typedef struct _usb_device_read_capacity16_data_struct +{ + uint32_t lastLogicalBlockAddress0; /*!< Last Logical Block Address*/ + uint32_t lastLogicalBlockAddress1; /*!< Last Logical Block Address*/ + uint32_t blockSize; /*!< Block Length In Bytes*/ +} usb_device_read_capacity16_data_struct_t; + +/*! @brief UFI capacity list header structure*/ +typedef struct _usb_device_capacity_list_header_struct +{ + uint8_t reserverd[3]; /*!< reserved*/ + uint8_t capacityListLength; /*!< Capacity List Length*/ +} usb_device_capacity_list_header_struct_t; + +/*! @brief UFI current maximum capacity structure*/ +typedef struct _usb_device_current_max_capacity_descriptor_struct +{ + uint32_t blockNumber; /*!< Number of Blocks*/ + uint32_t descriptorCodeBlockLength; /*!< Byte 4 Descriptor Code , byte 5-7 Block Length*/ +} usb_device_current_max_capacity_descriptor_struct_t; + +/*! @brief UFI formatting capacity structure*/ +typedef struct _usb_device_formattable_capacity_descriptor_struct +{ + uint32_t blockNumber; /*!< Number of Blocks*/ + uint32_t blockLength; /*!< Block Length*/ +} usb_device_formattable_capacity_descriptor_struct_t; + +/*! @brief UFI mode parameters header structure*/ +typedef struct _usb_device_mode_parameters_header_struct +{ + uint16_t modeDataLength; /*!< Mode Data Length*/ + uint8_t mediumTypeCode; /*!< The Medium Type Code field specifies the inserted medium type*/ + uint8_t wpDpfua; /*!< WP and DPOFUA bit*/ + uint8_t reserved[4]; /*!< Reserved*/ +} usb_device_mode_parameters_header_struct_t; + +/*! @brief UFI Capacity List structure*/ +typedef struct _usb_device_format_capacity_response_data_struct +{ + uint8_t capacityListHead[sizeof(usb_device_capacity_list_header_struct_t)]; /*! 0U)) +#include "usb_device_phdc.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! @brief local function prototypes */ +static usb_status_t USB_DevicePhdcAllocateHandle(usb_device_phdc_struct_t **handle); +static usb_status_t USB_DevicePhdcFreeHandle(usb_device_phdc_struct_t *handle); +static usb_status_t USB_DevicePhdcBulkInCallback(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam); +static usb_status_t USB_DevicePhdcBulkOutCallback(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam); +static usb_status_t USB_DevicePhdcInterruptInCallback(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam); +static usb_status_t USB_DevicePhdcEndpointsInit(usb_device_phdc_struct_t *phdcHandle); +static usb_status_t USB_DevicePhdcEndpointsDeinit(usb_device_phdc_struct_t *phdcHandle); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief the PHDC device instance */ +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_phdc_struct_t g_phdcHandle[USB_DEVICE_CONFIG_PHDC]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Allocate a device PHDC class handle. + * + * This function allocates a device PHDC class handle. + * + * @param handle It is out parameter, is used to return pointer of the device PHDC class handle to the caller. + * + * @retval kStatus_USB_Success Get a device PHDC class handle successfully. + * @retval kStatus_USB_Busy Cannot allocate a device PHDC class handle. + */ +static usb_status_t USB_DevicePhdcAllocateHandle(usb_device_phdc_struct_t **handle) +{ + int32_t count; + for (count = 0; count < USB_DEVICE_CONFIG_PHDC; count++) + { + if (NULL == g_phdcHandle[count].handle) + { + *handle = &g_phdcHandle[count]; + return kStatus_USB_Success; + } + } + return kStatus_USB_Busy; +} + +/*! + * @brief Free a device PHDC class handle. + * + * This function frees a device PHDC class handle. + * + * @param handle The device PHDC class handle. + * + * @retval kStatus_USB_Success Free device PHDC class handle successfully. + */ +static usb_status_t USB_DevicePhdcFreeHandle(usb_device_phdc_struct_t *handle) +{ + handle->handle = NULL; + handle->configStruct = (usb_device_class_config_struct_t *)NULL; + handle->configuration = 0U; + handle->alternate = 0U; + return kStatus_USB_Success; +} + +/*! + * @brief bulk IN endpoint callback function. + * + * This callback function is used to notify upper layer the transfer result of a transfer. + * This callback pointer is passed when the bulk IN pipe initialized. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The result of the bulk IN pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. + * In the class, the value is the PHDC class handle. + * + * @retval kStatus_USB_Success The transfer is successful. + * @retval kStatus_USB_InvalidHandle The device handle not be found. + */ +static usb_status_t USB_DevicePhdcBulkInCallback(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_phdc_struct_t *phdcHandle; + usb_status_t error = kStatus_USB_Error; + + phdcHandle = (usb_device_phdc_struct_t *)callbackParam; + + if (!phdcHandle) + { + return kStatus_USB_InvalidHandle; + } + phdcHandle->bulkIn.isBusy = 0U; + if ((NULL != phdcHandle->configStruct) && (phdcHandle->configStruct->classCallback)) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = phdcHandle->configStruct->classCallback((class_handle_t)phdcHandle, + kUSB_DevicePhdcEventBulkInSendComplete, message); + } + + return error; +} + +/*! + * @brief bulk OUT endpoint callback function. + * + * This callback function is used to notify upper layer the transfer result of a transfer. + * This callback pointer is passed when the bulk OUT pipe initialized. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The result of the bulk OUT pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. + * In the class, the value is the PHDC class handle. + * + * @retval kStatus_USB_Success The transfer is successful. + * @retval kStatus_USB_InvalidHandle The device handle not be found. + */ +static usb_status_t USB_DevicePhdcBulkOutCallback(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_phdc_struct_t *phdcHandle; + usb_status_t error = kStatus_USB_Error; + + phdcHandle = (usb_device_phdc_struct_t *)callbackParam; + + if (!phdcHandle) + { + return kStatus_USB_InvalidHandle; + } + phdcHandle->bulkOut.isBusy = 0U; + if ((NULL != phdcHandle->configStruct) && (phdcHandle->configStruct->classCallback)) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = phdcHandle->configStruct->classCallback((class_handle_t)phdcHandle, kUSB_DevicePhdcEventDataReceived, + message); + } + + return error; +} + +/*! + * @brief Interrupt IN endpoint callback function. + * + * This callback function is used to notify upper layer the transfer result of a transfer. + * This callback pointer is passed when the interrupt IN pipe initialized. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The result of the interrupt IN pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. + * In the class, the value is the PHDC class handle. + * + * @retval kStatus_USB_Success The transfer is successful. + * @retval kStatus_USB_InvalidHandle The device handle not be found. + */ +static usb_status_t USB_DevicePhdcInterruptInCallback(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_phdc_struct_t *phdcHandle; + usb_status_t error = kStatus_USB_Error; + + phdcHandle = (usb_device_phdc_struct_t *)callbackParam; + + if (!phdcHandle) + { + return kStatus_USB_InvalidHandle; + } + phdcHandle->interruptIn.isBusy = 0U; + if ((NULL != phdcHandle->configStruct) && (phdcHandle->configStruct->classCallback)) + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = phdcHandle->configStruct->classCallback((class_handle_t)phdcHandle, + kUSB_DevicePhdcEventInterruptInSendComplete, message); + } + return error; +} + +/*! + * @brief Initialize the endpoints of the PHDC class. + * + * This callback function is used to initialize the endpoints of the PHDC class. + * + * @param phdcHandle The device PHDC class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @retval kStatus_USB_Success The PHDC endpoint is initialized successful. + * @retval kStatus_USB_Error The interfaces not be found. + */ +static usb_status_t USB_DevicePhdcEndpointsInit(usb_device_phdc_struct_t *phdcHandle) +{ + usb_device_interface_list_t *interfaceList; + usb_device_interface_struct_t *interface = (usb_device_interface_struct_t *)NULL; + usb_status_t error = kStatus_USB_Error; + if (!phdcHandle) + { + return error; + } + if (phdcHandle->configuration > phdcHandle->configStruct->classInfomation->configurations) + { + return error; + } + /* gets the interface list */ + interfaceList = &phdcHandle->configStruct->classInfomation->interfaceList[phdcHandle->configuration - 1]; + for (int count = 0; count < interfaceList->count; count++) + { + if (USB_DEVICE_CONFIG_PHDC_CLASS_CODE == interfaceList->interfaces[count].classCode) + { + for (int index = 0; index < interfaceList->interfaces[count].count; index++) + { + if (interfaceList->interfaces[count].interface[index].alternateSetting == phdcHandle->alternate) + { + interface = &interfaceList->interfaces[count].interface[index]; + break; + } + } + phdcHandle->interfaceNumber = interfaceList->interfaces[count].interfaceNumber; + break; + } + } + if (!interface) + { + return error; + } + phdcHandle->interfaceHandle = interface; + for (int count = 0; count < interface->endpointList.count; count++) + { + usb_device_endpoint_init_struct_t epInitStruct; + usb_device_endpoint_callback_struct_t epCallback; + epInitStruct.zlt = 0U; + epInitStruct.interval = interface->endpointList.endpoint[count].interval; + epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress; + epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize; + epInitStruct.transferType = interface->endpointList.endpoint[count].transferType; + if (USB_ENDPOINT_INTERRUPT == epInitStruct.transferType) + { + epCallback.callbackFn = USB_DevicePhdcInterruptInCallback; + phdcHandle->interruptIn.ep = (epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK); + phdcHandle->interruptIn.pipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + phdcHandle->interruptIn.pipeStall = 0U; + phdcHandle->interruptIn.pipeDataLen = 0U; + } + else if (USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) + { + epCallback.callbackFn = USB_DevicePhdcBulkInCallback; + phdcHandle->bulkIn.ep = (epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK); + phdcHandle->bulkIn.pipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + phdcHandle->bulkIn.pipeStall = 0U; + phdcHandle->bulkIn.pipeDataLen = 0U; + } + else + { + epCallback.callbackFn = USB_DevicePhdcBulkOutCallback; + phdcHandle->bulkOut.ep = (epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK); + phdcHandle->bulkOut.pipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + phdcHandle->bulkOut.pipeStall = 0U; + phdcHandle->bulkOut.pipeDataLen = 0U; + } + epCallback.callbackParam = phdcHandle; + + error = USB_DeviceInitEndpoint(phdcHandle->handle, &epInitStruct, &epCallback); + } + return error; +} + +/*! + * @brief De-initialize the endpoints of the PHDC class. + * + * This callback function is used to de-initialize the endpoints of the PHC class. + * + * @param phdcHandle The device PHDC class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @retval kStatus_USB_Success The PHDC endpoint is de-initialized successful. + * @retval kStatus_USB_Error The interface handle not be found. + */ +static usb_status_t USB_DevicePhdcEndpointsDeinit(usb_device_phdc_struct_t *phdcHandle) +{ + usb_status_t error = kStatus_USB_Error; + + if (!phdcHandle->interfaceHandle) + { + return error; + } + for (int count = 0; count < phdcHandle->interfaceHandle->endpointList.count; count++) + { + error = USB_DeviceDeinitEndpoint(phdcHandle->handle, + phdcHandle->interfaceHandle->endpointList.endpoint[count].endpointAddress); + } + return error; +} + +/*! + * @brief Handle the event passed to the PHDC class. + * + * This function handles the event passed to the PHDC class. + * + * @param[in] handle The PHDC class handle, got from the usb_device_class_config_struct_t::classHandle. + * @param[in] event The event codes. Please refer to the enumeration usb_device_class_event_t. + * @param[in,out] param The param type is determined by the event code. + * + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The device handle not be found. + * @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe will be stalled by the caller. + */ +usb_status_t USB_DevicePhdcEvent(void *handle, uint32_t event, void *param) +{ + usb_device_phdc_struct_t *phdcHandle; + usb_status_t error = kStatus_USB_Error; + uint16_t interfaceAlternate; + uint8_t *temp8; + uint8_t alternate; + + if ((!param) || (!handle)) + { + return kStatus_USB_InvalidHandle; + } + + phdcHandle = (usb_device_phdc_struct_t *)handle; + + switch (event) + { + case kUSB_DeviceClassEventDeviceReset: + phdcHandle->configuration = 0U; + phdcHandle->bulkIn.isBusy = 0U; + phdcHandle->bulkOut.isBusy = 0U; + phdcHandle->interruptIn.isBusy = 0U; + break; + case kUSB_DeviceClassEventSetConfiguration: + temp8 = ((uint8_t *)param); + if (!phdcHandle->configStruct) + { + break; + } + if (*temp8 == phdcHandle->configuration) + { + break; + } + + if (phdcHandle->configuration) + { + error = USB_DevicePhdcEndpointsDeinit(phdcHandle); + } + phdcHandle->configuration = *temp8; + phdcHandle->alternate = 0U; + error = USB_DevicePhdcEndpointsInit(phdcHandle); + break; + case kUSB_DeviceClassEventSetInterface: + if (!phdcHandle->configStruct) + { + break; + } + + interfaceAlternate = *((uint16_t *)param); + alternate = (uint8_t)(interfaceAlternate & 0xFF); + + if (phdcHandle->interfaceNumber != ((uint8_t)(interfaceAlternate >> 8))) + { + break; + } + if (alternate == phdcHandle->alternate) + { + break; + } + error = USB_DevicePhdcEndpointsDeinit(phdcHandle); + phdcHandle->alternate = alternate; + error = USB_DevicePhdcEndpointsInit(phdcHandle); + break; + case kUSB_DeviceClassEventSetEndpointHalt: + if ((!phdcHandle->configStruct) || (!phdcHandle->interfaceHandle)) + { + break; + } + temp8 = ((uint8_t *)param); + for (int count = 0; count < phdcHandle->interfaceHandle->endpointList.count; count++) + { + if (*temp8 == phdcHandle->interfaceHandle->endpointList.endpoint[count].endpointAddress) + { + /* Only stall the endpoint belongs to the class */ + if (USB_ENDPOINT_INTERRUPT == phdcHandle->interfaceHandle->endpointList.endpoint[count].transferType) + { + phdcHandle->interruptIn.pipeStall = 1U; + } + else if (USB_IN == ((phdcHandle->interfaceHandle->endpointList.endpoint[count].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) + { + phdcHandle->bulkIn.pipeStall = 1U; + } + else + { + phdcHandle->bulkOut.pipeStall = 1U; + } + error = USB_DeviceStallEndpoint(phdcHandle->handle, *temp8); + } + } + break; + case kUSB_DeviceClassEventClearEndpointHalt: + if ((!phdcHandle->configStruct) || (!phdcHandle->interfaceHandle)) + { + break; + } + temp8 = ((uint8_t *)param); + for (int count = 0; count < phdcHandle->interfaceHandle->endpointList.count; count++) + { + if (*temp8 == phdcHandle->interfaceHandle->endpointList.endpoint[count].endpointAddress) + { + error = USB_DeviceUnstallEndpoint(phdcHandle->handle, *temp8); + if (USB_ENDPOINT_INTERRUPT == phdcHandle->interfaceHandle->endpointList.endpoint[count].transferType) + { + if (phdcHandle->interruptIn.pipeStall) + { + phdcHandle->interruptIn.pipeStall = 0U; + if ((uint8_t*)USB_UNINITIALIZED_VAL_32 != phdcHandle->interruptIn.pipeDataBuffer) + { + error = USB_DeviceSendRequest(phdcHandle->handle, (phdcHandle->interruptIn.ep), + phdcHandle->interruptIn.pipeDataBuffer, phdcHandle->interruptIn.pipeDataLen); + if (kStatus_USB_Success != error) + { + usb_device_endpoint_callback_message_struct_t endpointCallbackMessage; + endpointCallbackMessage.buffer = phdcHandle->interruptIn.pipeDataBuffer; + endpointCallbackMessage.length = phdcHandle->interruptIn.pipeDataLen; + endpointCallbackMessage.isSetup = 0U; + USB_DevicePhdcInterruptInCallback(phdcHandle->handle,(void*)&endpointCallbackMessage, handle); + } + phdcHandle->interruptIn.pipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + phdcHandle->interruptIn.pipeDataLen = 0U; + } + } + } + else if (USB_IN == ((phdcHandle->interfaceHandle->endpointList.endpoint[count].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) + { + if (phdcHandle->bulkIn.pipeStall) + { + phdcHandle->bulkIn.pipeStall = 0U; + if ((uint8_t*)USB_UNINITIALIZED_VAL_32 != phdcHandle->bulkIn.pipeDataBuffer) + { + error = USB_DeviceSendRequest(phdcHandle->handle, (phdcHandle->bulkIn.ep), + phdcHandle->bulkIn.pipeDataBuffer, phdcHandle->bulkIn.pipeDataLen); + if (kStatus_USB_Success != error) + { + usb_device_endpoint_callback_message_struct_t endpointCallbackMessage; + endpointCallbackMessage.buffer = phdcHandle->bulkIn.pipeDataBuffer; + endpointCallbackMessage.length = phdcHandle->bulkIn.pipeDataLen; + endpointCallbackMessage.isSetup = 0U; + USB_DevicePhdcBulkInCallback(phdcHandle->handle,(void*)&endpointCallbackMessage, handle); + } + phdcHandle->bulkIn.pipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + phdcHandle->bulkIn.pipeDataLen = 0U; + } + } + } + else + { + if (phdcHandle->bulkOut.pipeStall) + { + phdcHandle->bulkOut.pipeStall = 0U; + if ((uint8_t*)USB_UNINITIALIZED_VAL_32 != phdcHandle->bulkOut.pipeDataBuffer) + { + error = USB_DeviceRecvRequest(phdcHandle->handle, (phdcHandle->bulkOut.ep), + phdcHandle->bulkOut.pipeDataBuffer, phdcHandle->bulkOut.pipeDataLen); + if (kStatus_USB_Success != error) + { + usb_device_endpoint_callback_message_struct_t endpointCallbackMessage; + endpointCallbackMessage.buffer = phdcHandle->bulkOut.pipeDataBuffer; + endpointCallbackMessage.length = phdcHandle->bulkOut.pipeDataLen; + endpointCallbackMessage.isSetup = 0U; + USB_DevicePhdcBulkOutCallback(phdcHandle->handle, (void*)&endpointCallbackMessage, handle); + } + phdcHandle->bulkOut.pipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + phdcHandle->bulkOut.pipeDataLen = 0U; + } + } + + } + } + } + break; + case kUSB_DeviceClassEventClassRequest: + if (param) + { + usb_device_control_request_struct_t *controlRequest = (usb_device_control_request_struct_t *)param; + + if ((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != + USB_REQUEST_TYPE_RECIPIENT_INTERFACE) + { + break; + } + + if ((controlRequest->setup->wIndex & 0xFF) != phdcHandle->interfaceNumber) + { + break; + } + + switch (controlRequest->setup->bRequest) + { + case USB_DEVICE_PHDC_REQUEST_SET_FEATURE: + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = phdcHandle->configStruct->classCallback( + (class_handle_t)phdcHandle, kUSB_DevicePhdcEventSetFeature, &controlRequest->setup->wValue); + } + break; + case USB_DEVICE_PHDC_REQUEST_CLEAR_FEATURE: + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = phdcHandle->configStruct->classCallback((class_handle_t)phdcHandle, + kUSB_DevicePhdcEventClearFeature, + &controlRequest->setup->wValue); + } + break; + case USB_DEVICE_PHDC_REQUEST_GET_STATUS: + { + /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = phdcHandle->configStruct->classCallback((class_handle_t)phdcHandle, + kUSB_DevicePhdcEventGetStatus, controlRequest); + } + break; + default: + error = kStatus_USB_InvalidRequest; + break; + } + } + break; + default: + error = kStatus_USB_InvalidRequest; + break; + } + return error; +} + +/*! + * @brief Initialize the PHDC class. + * + * This function is used to initialize the PHDC class. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param config The class configuration information. + * @param handle It is output parameter, is used to return pointer of the PHDC class handle to the caller. + * + * @retval kStatus_USB_Success The PHDC class is initialized successfully. + * @retval kStatus_USB_Busy No PHDC device handle available for allocation. + * @retval kStatus_USB_InvalidHandle The PHDC device handle allocation failure. + * @retval kStatus_USB_InvalidParameter The USB device handle allocation failure. + */ +usb_status_t USB_DevicePhdcInit(uint8_t controllerId, usb_device_class_config_struct_t *config, class_handle_t *handle) +{ + usb_device_phdc_struct_t *phdcHandle; + usb_status_t error = kStatus_USB_Error; + + error = USB_DevicePhdcAllocateHandle(&phdcHandle); + + if (kStatus_USB_Success != error) + { + return error; + } + + error = USB_DeviceClassGetDeviceHandle(controllerId, &phdcHandle->handle); + + if (kStatus_USB_Success != error) + { + return error; + } + + if (!phdcHandle->handle) + { + return kStatus_USB_InvalidHandle; + } + phdcHandle->configStruct = config; + phdcHandle->configuration = 0U; + phdcHandle->alternate = 0xff; + + *handle = (class_handle_t)phdcHandle; + return error; +} + +/*! + * @brief De-initialize the device PHDC class. + * + * The function de-initializes the device PHDC class. + * + * @param handle The PHDC class handle got from usb_device_class_config_struct_t::classHandle. + * + * @retval kStatus_USB_InvalidHandle The device handle not be found. + * @retva; kStatus_USB_Success The PHDC class is de-initialized successful. + */ +usb_status_t USB_DevicePhdcDeinit(class_handle_t handle) +{ + usb_device_phdc_struct_t *phdcHandle; + usb_status_t error = kStatus_USB_Error; + + phdcHandle = (usb_device_phdc_struct_t *)handle; + + if (!phdcHandle) + { + return kStatus_USB_InvalidHandle; + } + error = USB_DevicePhdcEndpointsDeinit(phdcHandle); + USB_DevicePhdcFreeHandle(phdcHandle); + return error; +} + +/*! + * @brief Send data through a specified endpoint. + * + * The function is used to send data through a specified endpoint. + * The function calls #USB_DeviceSendRequest internally. + * + * @param[in] handle The PHDC class handle got from usb_device_class_config_struct_t::classHandle. + * @param[in] ep Endpoint index. + * @param[in] buffer The memory address to hold the data need to be sent. + * @param[in] length The data length need to be sent. + * + * @retval kStatus_USB_InvalidHandle The device handle not be found. + * @retval kStatus_USB_Busy The previous transfer is pending. + * @retva; kStatus_USB_Success The sending is successful. + */ +usb_status_t USB_DevicePhdcSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length) +{ + usb_device_phdc_struct_t *phdcHandle; + usb_device_phdc_pipe_t *pipe; + usb_status_t error; + + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + phdcHandle = (usb_device_phdc_struct_t *)handle; + if (phdcHandle->bulkIn.ep == ep) + { + pipe = &(phdcHandle->bulkIn); + } + else if (phdcHandle->interruptIn.ep == ep) + { + pipe = &(phdcHandle->interruptIn); + } + else + { + return kStatus_USB_InvalidParameter; + } + + if (1U == pipe->isBusy) + { + return kStatus_USB_Busy; + } + pipe->isBusy = 1U; + + if (pipe->pipeStall) + { + pipe->pipeDataBuffer = buffer; + pipe->pipeDataLen = length; + return kStatus_USB_Success; + } + error = USB_DeviceSendRequest(phdcHandle->handle, ep, buffer, length); + if (kStatus_USB_Success != error) + { + pipe->isBusy = 0U; + } + return error; +} + +/*! + * @brief Receive data through a specified endpoint. + * + * The function is used to receive data through a specified endpoint. + * The function calls #USB_DeviceRecvRequest internally. + * + * @param[in] handle The PHDC class handle got from usb_device_class_config_struct_t::classHandle. + * @param[in] ep Endpoint index. + * @param[in] buffer The memory address to save the received data. + * @param[in] length The data length want to be received. + * + * @retval kStatus_USB_InvalidHandle The device handle not be found. + * @retval kStatus_USB_Busy The previous transfer is pending. + * @retva; kStatus_USB_Success The receiving is successful. + */ +usb_status_t USB_DevicePhdcRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length) +{ + usb_device_phdc_struct_t *phdcHandle; + usb_status_t error; + + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + phdcHandle = (usb_device_phdc_struct_t *)handle; + if (1U == phdcHandle->bulkOut.isBusy) + { + return kStatus_USB_Busy; + } + phdcHandle->bulkOut.isBusy = 1U; + + if (phdcHandle->bulkOut.pipeStall) + { + phdcHandle->bulkOut.pipeDataBuffer = buffer; + phdcHandle->bulkOut.pipeDataLen = length; + return kStatus_USB_Success; + } + error = USB_DeviceRecvRequest(phdcHandle->handle, ep, buffer, length); + if (kStatus_USB_Success != error) + { + phdcHandle->bulkOut.isBusy = 0U; + } + return error; +} + +#endif diff --git a/usb/device/class/usb_device_phdc.h b/usb/device/class/usb_device_phdc.h new file mode 100644 index 0000000..55b55b5 --- /dev/null +++ b/usb/device/class/usb_device_phdc.h @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _USB_DEVICE_PHDC_H_ +#define _USB_DEVICE_PHDC_H_ + +/*! + * @addtogroup usb_device_phdc_drv + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief The class code of the PHDC class */ +#define USB_DEVICE_CONFIG_PHDC_CLASS_CODE (0x0F) +/*! @brief The PHDC class set Meta-data message preamble feature request */ +#define USB_DEVICE_PHDC_REQUEST_SET_FEATURE (0x03) +/*! @brief The PHDC class clear Meta-data message preamble feature request */ +#define USB_DEVICE_PHDC_REQUEST_CLEAR_FEATURE (0x01) +/*! @brief The PHDC class get data status request */ +#define USB_DEVICE_PHDC_REQUEST_GET_STATUS (0x00) +/*! @brief Available common EVENT types in PHDC class callback */ +typedef enum +{ + kUSB_DevicePhdcEventInterruptInSendComplete = 0x01, /*!< Send data completed or cancelled etc*/ + kUSB_DevicePhdcEventBulkInSendComplete, /*!< Send data completed or cancelled etc*/ + kUSB_DevicePhdcEventDataReceived, /*!< Data received or cancelled etc*/ + kUSB_DevicePhdcEventSetFeature, /*!< Set feature request */ + kUSB_DevicePhdcEventClearFeature, /*!< Clear feature request */ + kUSB_DevicePhdcEventGetStatus, /*!< Get status request */ +} usb_device_phdc_event_t; + +/*! @brief Definition of pipe structure. */ +typedef struct _usb_device_phdc_pipe +{ + uint8_t *pipeDataBuffer; /*!< pipe data buffer backup when stall */ + uint32_t pipeDataLen; /*!< pipe data length backup when stall */ + uint8_t pipeStall; /*!< pipe is stall */ + uint8_t ep; /*!< The endpoint number of the pipe. */ + uint8_t isBusy; /*!< 1: The pipe is transferring packet, 0: The pipe is idle. */ +} usb_device_phdc_pipe_t; + +/*! @brief The PHDC device class status structure */ +typedef struct _usb_device_phdc_struct +{ + usb_device_handle handle; /*!< The device handle */ + usb_device_class_config_struct_t *configStruct; /*!< The configuration of the class. */ + usb_device_interface_struct_t *interfaceHandle; /*!< Current interface handle */ + usb_device_phdc_pipe_t bulkIn; /*!< The bulk in pipe for sending data */ + usb_device_phdc_pipe_t bulkOut; /*!< The bulk out pipe for receiving data */ + usb_device_phdc_pipe_t interruptIn; /*!< The interrupt in pipe for sending data */ + uint8_t configuration; /*!< Current configuration */ + uint8_t interfaceNumber; /*!< The interface number of the class */ + uint8_t alternate; /*!< Current alternate setting of the interface */ +} usb_device_phdc_struct_t; + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the PHDC class. + * + * This function is used to initialize the PHDC class. + * + * @param controllerId The controller ID of the USB IP. See the enumeration usb_controller_index_t. + * @param config The class configuration information. + * @param handle An output parameter used to return pointer of the PHDC class handle to the caller. + * + * @retval kStatus_USB_Success The PHDC class is initialized successfully. + * @retval kStatus_USB_Busy No PHDC device handle available for allocation. + * @retval kStatus_USB_InvalidHandle The PHDC device handle allocation failure. + * @retval kStatus_USB_InvalidParameter The USB device handle allocation failure. + */ +extern usb_status_t USB_DevicePhdcInit(uint8_t controllerId, + usb_device_class_config_struct_t *config, + class_handle_t *handle); + +/*! + * @brief Deinitializes the device PHDC class. + * + * The function deinitializes the device PHDC class. + * + * @param handle The PHDC class handle received from usb_device_class_config_struct_t::classHandle. + * + * @retval kStatus_USB_InvalidHandle The device handle is not found. + * @retval kStatus_USB_Success The PHDC class is de-initialized successful. + */ +extern usb_status_t USB_DevicePhdcDeinit(class_handle_t handle); + +/*! + * @brief Handles the event passed to the PHDC class. + * + * This function handles the event passed to the PHDC class. + * + * @param[in] handle The PHDC class handle received from the usb_device_class_config_struct_t::classHandle. + * @param[in] event The event codes. See the enumeration usb_device_class_event_t. + * @param[in,out] param The parameter type is determined by the event code. + * + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The device handle is not found. + * @retval kStatus_USB_InvalidRequest The request is invalid and the control pipe is stalled by the caller. + */ +extern usb_status_t USB_DevicePhdcEvent(void *handle, uint32_t event, void *param); + +/*! + * @name USB device PHDC class APIs + * @{ + */ + +/*! + * @brief Sends data through a specified endpoint. + * + * The function is used to send data through a specified endpoint. + * The function calls #USB_DeviceSendRequest internally. + * + * @param[in] handle The PHDC class handle received from the usb_device_class_config_struct_t::classHandle. + * @param[in] ep Endpoint index. + * @param[in] buffer The memory address to hold the data to be sent. + * @param[in] length The data length to be sent. + * + * @retval kStatus_USB_InvalidHandle The device handle is not found. + * @retval kStatus_USB_Busy The previous transfer is pending. + * @retval kStatus_USB_Success The sending is successful. + * + * @note The function can only be called in the same context. + */ +extern usb_status_t USB_DevicePhdcSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length); + +/*! + * @brief Receives data through a specified endpoint. + * + * The function is used to receive data through a specified endpoint. + * The function calls the #USB_DeviceRecvRequest internally. + * + * @param[in] handle The PHDC class handle received from usb_device_class_config_struct_t::classHandle. + * @param[in] ep Endpoint index. + * @param[in] buffer The memory address to save the received data. + * @param[in] length The data length want to be received. + * + * @retval kStatus_USB_InvalidHandle The device handle is not found. + * @retval kStatus_USB_Busy The previous transfer is pending. + * @retval kStatus_USB_Success The receiving is successful. + * + * @note The function can only be called in the same context. + */ +extern usb_status_t USB_DevicePhdcRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length); + +#if defined(__cplusplus) +} +#endif +/*! @}*/ + +/*! @}*/ + +#endif /* _USB_DEVICE_PHDC_H_ */ diff --git a/usb/device/class/usb_device_printer.c b/usb/device/class/usb_device_printer.c new file mode 100644 index 0000000..d144e89 --- /dev/null +++ b/usb/device/class/usb_device_printer.c @@ -0,0 +1,634 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device.h" + +#include "usb_device_class.h" + +#if ((defined(USB_DEVICE_CONFIG_PRINTER)) && (USB_DEVICE_CONFIG_PRINTER > 0U)) +#include "usb_device_printer.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_printer_struct_t + s_PrinterHandle[USB_DEVICE_CONFIG_PRINTER]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +static usb_status_t USB_DevicePrinterAllocateHandle(usb_device_printer_struct_t **printerHandle) +{ + uint8_t index; + + for (index = 0; index < USB_DEVICE_CONFIG_PRINTER; ++index) + { + if (s_PrinterHandle[index].deviceHandle == NULL) + { + *printerHandle = &(s_PrinterHandle[index]); + return kStatus_USB_Success; + } + } + + return kStatus_USB_Busy; +} + +static usb_status_t USB_DevicePrinterFreeHandle(usb_device_printer_struct_t *printerHandle) +{ + /* ensure that printerHandle is not NULL before calling this function */ + printerHandle->deviceHandle = NULL; + printerHandle->classConfig = NULL; + printerHandle->alternate = 0xFFu; + printerHandle->configuration = 0; + printerHandle->interfaceNumber = 0; + + return kStatus_USB_Success; +} + +/*! + * @brief bulk IN endpoint callback function. + * + * This callback function is used to notify upper layer the transfer result of a transfer. + * This callback pointer is passed when the bulk IN pipe initialized. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The result of the bulk IN pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. + * In the class, the value is the printer class handle. + * + * @retval kStatus_USB_Success The transfer is successful. + * @retval kStatus_USB_InvalidHandle The device handle not be found. + */ +static usb_status_t USB_DevicePrinterBulkInCallback(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)callbackParam; + usb_status_t status = kStatus_USB_Error; + + if (callbackParam == NULL) + { + return kStatus_USB_InvalidHandle; + } + + printerHandle->bulkInBusy = 0U; + if ((NULL != printerHandle->classConfig) && (printerHandle->classConfig->classCallback)) + { + /* Notify the application data received by calling the printer class callback. + ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + status = printerHandle->classConfig->classCallback((class_handle_t)printerHandle, + kUSB_DevicePrinterEventSendResponse, message); + } + + return status; +} + +/*! + * @brief bulk OUT endpoint callback function. + * + * This callback function is used to notify upper layer the transfer result of a transfer. + * This callback pointer is passed when the bulk OUT pipe initialized. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The result of the bulk OUT pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. + * In the class, the value is the printer class handle. + * + * @retval kStatus_USB_Success The transfer is successful. + * @retval kStatus_USB_InvalidHandle The device handle not be found. + */ +static usb_status_t USB_DevicePrinterBulkOutCallback(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)callbackParam; + usb_status_t status = kStatus_USB_Error; + + if (printerHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + printerHandle->bulkOutBusy = 0U; + if ((NULL != printerHandle->classConfig) && (printerHandle->classConfig->classCallback)) + { + /* ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + status = printerHandle->classConfig->classCallback((class_handle_t)printerHandle, + kUSB_DevicePrinterEventRecvResponse, message); + } + + return status; +} + +/*! + * @brief Initialize the endpoints of the printer class. + * + * This callback function is used to initialize the endpoints of the printer class. + * + * @param printerHandle The device printer class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DevicePrinterEndpointsInit(usb_device_printer_struct_t *printerHandle) +{ + /* ensure that printerHandle is not NULL before calling this function */ + usb_device_interface_list_t *configInterfaceList; + usb_device_interface_struct_t *interface = NULL; + usb_status_t status = kStatus_USB_Error; + uint8_t interfaceIndex; + uint8_t index; + + /* return error when configuration is invalid (0 or more than the configuration number) */ + if ((printerHandle->configuration == 0U) || + (printerHandle->configuration > printerHandle->classConfig->classInfomation->configurations)) + { + return status; + } + + configInterfaceList = + &(printerHandle->classConfig->classInfomation->interfaceList[printerHandle->configuration - 1]); + for (interfaceIndex = 0; interfaceIndex < configInterfaceList->count; ++interfaceIndex) + { + if (USB_DEVICE_CONFIG_PRINTER_CLASS_CODE == configInterfaceList->interfaces[interfaceIndex].classCode) + { + /* index means the alternate interface's index here */ + for (index = 0; index < configInterfaceList->interfaces[interfaceIndex].count; ++index) + { + if (configInterfaceList->interfaces[interfaceIndex].interface[index].alternateSetting == + printerHandle->alternate) + { + interface = &(configInterfaceList->interfaces[interfaceIndex].interface[index]); + break; + } + } + printerHandle->interfaceNumber = configInterfaceList->interfaces[interfaceIndex].interfaceNumber; + break; + } + } + if (interface == NULL) + { + return status; + } + + /* Keep new interface handle. */ + printerHandle->interfaceHandle = interface; + + /* Initialize the endpoints of the new interface. */ + /* index means the endpoint's index here */ + for (index = 0; index < interface->endpointList.count; ++index) + { + usb_device_endpoint_init_struct_t epInitStruct; + usb_device_endpoint_callback_struct_t epCallback; + epInitStruct.zlt = 0U; + epInitStruct.interval = interface->endpointList.endpoint[index].interval; + epInitStruct.endpointAddress = interface->endpointList.endpoint[index].endpointAddress; + epInitStruct.maxPacketSize = interface->endpointList.endpoint[index].maxPacketSize; + epInitStruct.transferType = interface->endpointList.endpoint[index].transferType; + + if (((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT) == USB_IN) + { + epCallback.callbackFn = USB_DevicePrinterBulkInCallback; + printerHandle->bulkInPipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + printerHandle->bulkInPipeStall = 0U; + printerHandle->bulkInPipeDataLen = 0U; + } + else + { + epCallback.callbackFn = USB_DevicePrinterBulkOutCallback; + printerHandle->bulkOutPipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + printerHandle->bulkOutPipeStall = 0U; + printerHandle->bulkOutPipeDataLen = 0U; + } + epCallback.callbackParam = printerHandle; + + status = USB_DeviceInitEndpoint(printerHandle->deviceHandle, &epInitStruct, &epCallback); + } + + return status; +} + +/*! + * @brief De-initialize the endpoints of the printer class. + * + * This callback function is used to de-initialize the endpoints of the printer class. + * + * @param printerHandle The device printer class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DevicePrinterEndpointsDeinit(usb_device_printer_struct_t *printerHandle) +{ + /* ensure that printerHandle is not NULL before calling this function */ + usb_status_t status = kStatus_USB_Error; + uint8_t index; + + /* return directly when the interfaceHandle is NULL, it means USB_DevicePrinterEndpointsInit is not called */ + if (printerHandle->interfaceHandle == NULL) + { + return kStatus_USB_Success; + } + + for (index = 0; index < printerHandle->interfaceHandle->endpointList.count; ++index) + { + status = USB_DeviceDeinitEndpoint(printerHandle->deviceHandle, + printerHandle->interfaceHandle->endpointList.endpoint[index].endpointAddress); + } + printerHandle->interfaceHandle = NULL; + + return status; +} + +usb_status_t USB_DevicePrinterInit(uint8_t controllerId, + usb_device_class_config_struct_t *config, + class_handle_t *handle) + +{ + usb_device_handle deviceHandle; + usb_device_printer_struct_t *printerHandle; + usb_status_t status = kStatus_USB_Error; + USB_OSA_SR_ALLOC(); + + /* get the controller's device handle */ + status = USB_DeviceClassGetDeviceHandle(controllerId, &deviceHandle); + if (status != kStatus_USB_Success) + { + return status; + } + if (deviceHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + + /* Allocate a printer class handle. */ + USB_OSA_ENTER_CRITICAL(); + status = USB_DevicePrinterAllocateHandle(&printerHandle); + printerHandle->deviceHandle = deviceHandle; /* this printer instance is used */ + USB_OSA_EXIT_CRITICAL(); + if (status != kStatus_USB_Success) + { + return status; + } + + printerHandle->classConfig = config; + printerHandle->alternate = 0xFFu; + printerHandle->configuration = 0; + printerHandle->interfaceNumber = 0; + printerHandle->interfaceHandle = NULL; + + *handle = (class_handle_t)printerHandle; + + return status; +} + +usb_status_t USB_DevicePrinterDeinit(class_handle_t handle) +{ + usb_status_t status; + usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)handle; + + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + + status = USB_DevicePrinterEndpointsDeinit(printerHandle); + USB_DevicePrinterFreeHandle(printerHandle); + + return status; +} + +usb_status_t USB_DevicePrinterEvent(void *handle, uint32_t event, void *param) +{ + usb_status_t status = kStatus_USB_Error; + usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)handle; + uint16_t temp16; + uint8_t temp8; + + if ((handle == NULL) || (param == NULL)) + { + return kStatus_USB_InvalidHandle; + } + + switch (event) + { + case kUSB_DeviceClassEventDeviceReset: + /* de-initialize printer instance */ + printerHandle->interfaceHandle = NULL; + printerHandle->alternate = 0xFFu; + printerHandle->configuration = 0; + printerHandle->interfaceNumber = 0; + printerHandle->bulkInBusy = 0U; + printerHandle->bulkOutBusy = 0U; + status = kStatus_USB_Success; + break; + + case kUSB_DeviceClassEventSetConfiguration: + temp8 = *((uint8_t *)param); + if (printerHandle->classConfig == NULL) + { + break; + } + if (temp8 == printerHandle->configuration) + { + status = kStatus_USB_Success; + break; + } + + /* De-initialize the endpoints when current configuration is none zero. */ + if (printerHandle->configuration != 0) + { + status = USB_DevicePrinterEndpointsDeinit(printerHandle); + } + /* Save new configuration. */ + printerHandle->configuration = temp8; + printerHandle->alternate = 0U; + printerHandle->bulkInBusy = 0U; + printerHandle->bulkOutBusy = 0U; + + /* Initialize the endpoints of the new current configuration */ + status = USB_DevicePrinterEndpointsInit(printerHandle); + break; + + case kUSB_DeviceClassEventSetInterface: + if (printerHandle->classConfig == NULL) + { + break; + } + + /* Get the new alternate setting of the interface */ + temp16 = *((uint16_t *)param); + /* Get the alternate setting value */ + temp8 = (uint8_t)(temp16 & 0xFFU); + /* Whether the interface belongs to the class. */ + if (printerHandle->interfaceNumber != ((uint8_t)(temp16 >> 8U))) + { + break; + } + /* Only handle new alternate setting. */ + if (temp8 == printerHandle->alternate) + { + break; + } + + /* De-initialize old endpoints */ + status = USB_DevicePrinterEndpointsDeinit(printerHandle); + printerHandle->alternate = temp8; + printerHandle->bulkInBusy = 0U; + printerHandle->bulkOutBusy = 0U; + /* Initialize new endpoints */ + status = USB_DevicePrinterEndpointsInit(printerHandle); + break; + + case kUSB_DeviceClassEventSetEndpointHalt: + if ((printerHandle->classConfig == NULL) || (printerHandle->interfaceHandle == NULL)) + { + break; + } + /* Get the endpoint address */ + temp8 = *((uint8_t *)param); + for (temp16 = 0; temp16 < printerHandle->interfaceHandle->endpointList.count; ++temp16) + { + if (temp8 == printerHandle->interfaceHandle->endpointList.endpoint[temp16].endpointAddress) + { + /* Only stall the endpoint belongs to the class */ + if (USB_IN == ((printerHandle->interfaceHandle->endpointList.endpoint[temp16].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) + { + printerHandle->bulkInPipeStall = 1U; + } + else + { + printerHandle->bulkOutPipeStall = 1U; + } + status = USB_DeviceStallEndpoint(printerHandle->deviceHandle, temp8); + break; + } + } + break; + + case kUSB_DeviceClassEventClearEndpointHalt: + if ((printerHandle->classConfig == NULL) || (printerHandle->interfaceHandle == NULL)) + { + break; + } + /* Get the endpoint address */ + temp8 = *((uint8_t *)param); + for (temp16 = 0; temp16 < printerHandle->interfaceHandle->endpointList.count; ++temp16) + { + if (temp8 == printerHandle->interfaceHandle->endpointList.endpoint[temp16].endpointAddress) + { + /* Only un-stall the endpoint belongs to the class */ + status = USB_DeviceUnstallEndpoint(printerHandle->deviceHandle, temp8); + if (USB_IN == (((temp8) & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)) + { + if (printerHandle->bulkInPipeStall) + { + printerHandle->bulkInPipeStall = 0U; + if ((uint8_t*)USB_UNINITIALIZED_VAL_32 != printerHandle->bulkInPipeDataBuffer) + { + status = USB_DeviceSendRequest(printerHandle->deviceHandle, (printerHandle->interfaceHandle->endpointList.endpoint[temp16].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK), + printerHandle->bulkInPipeDataBuffer, printerHandle->bulkInPipeDataLen); + if (kStatus_USB_Success != status) + { + usb_device_endpoint_callback_message_struct_t endpointCallbackMessage; + endpointCallbackMessage.buffer = printerHandle->bulkInPipeDataBuffer; + endpointCallbackMessage.length = printerHandle->bulkInPipeDataLen; + endpointCallbackMessage.isSetup = 0U; + USB_DevicePrinterBulkInCallback(printerHandle->deviceHandle,(void*)&endpointCallbackMessage, handle); + } + printerHandle->bulkInPipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + printerHandle->bulkInPipeDataLen = 0U; + } + } + } + else + { + if (printerHandle->bulkOutPipeStall == 1U) + { + printerHandle->bulkOutPipeStall = 0U; + if ((uint8_t*)USB_UNINITIALIZED_VAL_32 != printerHandle->bulkOutPipeDataBuffer) + { + status = USB_DeviceRecvRequest(printerHandle->deviceHandle, (printerHandle->interfaceHandle->endpointList.endpoint[temp16].endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK), + printerHandle->bulkOutPipeDataBuffer, printerHandle->bulkOutPipeDataLen); + if (kStatus_USB_Success != status) + { + usb_device_endpoint_callback_message_struct_t endpointCallbackMessage; + endpointCallbackMessage.buffer = printerHandle->bulkOutPipeDataBuffer; + endpointCallbackMessage.length = printerHandle->bulkOutPipeDataLen; + endpointCallbackMessage.isSetup = 0U; + USB_DevicePrinterBulkInCallback(printerHandle->deviceHandle, (void*)&endpointCallbackMessage, handle); + } + printerHandle->bulkOutPipeDataBuffer = (uint8_t*)USB_UNINITIALIZED_VAL_32; + printerHandle->bulkOutPipeDataLen = 0U; + } + } + } + break; + } + } + break; + + case kUSB_DeviceClassEventClassRequest: + if (param) + { + /* Handle the printer class specific request. */ + usb_device_control_request_struct_t *controlRequest = (usb_device_control_request_struct_t *)param; + usb_device_printer_class_request_t classRequest; + + if ((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != + USB_REQUEST_TYPE_RECIPIENT_INTERFACE) + { + break; + } + + switch (controlRequest->setup->bRequest) + { + case USB_DEVICE_PRINTER_GET_DEVICE_ID: + /* GET_DEVICE_ID */ + classRequest.configIndex = (uint8_t)controlRequest->setup->wValue; + classRequest.interface = (uint8_t)(controlRequest->setup->wIndex >> 8); + classRequest.alternateSetting = (uint8_t)(controlRequest->setup->wIndex); + /* ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + status = printerHandle->classConfig->classCallback( + (class_handle_t)printerHandle, kUSB_DevicePrinterEventGetDeviceId, &classRequest); + controlRequest->buffer = classRequest.buffer; + controlRequest->length = classRequest.length; + break; + + case USB_DEVICE_PRINTER_GET_PORT_STATUS: + /* GET_PORT_STATUS */ + classRequest.interface = (uint8_t)(controlRequest->setup->wIndex); + if (classRequest.interface != printerHandle->interfaceNumber) + { + controlRequest->buffer = NULL; + controlRequest->length = 0U; + } + else + { + /* ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + status = printerHandle->classConfig->classCallback( + (class_handle_t)printerHandle, kUSB_DevicePrinterEventGetPortStatus, &classRequest); + controlRequest->buffer = classRequest.buffer; + controlRequest->length = classRequest.length; + } + break; + + case USB_DEVICE_PRINTER_SOFT_RESET: + classRequest.interface = (uint8_t)(controlRequest->setup->wIndex); + if (classRequest.interface != printerHandle->interfaceNumber) + { + controlRequest->buffer = NULL; + controlRequest->length = 0U; + } + else + { + /* reset BULK_IN/OUT endpoint and inform application */ + USB_DevicePrinterEndpointsDeinit(printerHandle); + USB_DevicePrinterEndpointsInit(printerHandle); + /* ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + status = printerHandle->classConfig->classCallback( + (class_handle_t)printerHandle, kUSB_DevicePrinterEventGetPortStatus, &classRequest); + } + break; + + default: + break; + } + } + break; + + default: + break; + } + + return status; +} + +usb_status_t USB_DevicePrinterSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length) +{ + usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)handle; + usb_status_t status = kStatus_USB_Error; + + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + + if (printerHandle->bulkInBusy) + { + return kStatus_USB_Busy; + } + printerHandle->bulkInBusy = 1U; + + if (printerHandle->bulkInPipeStall) + { + printerHandle->bulkInPipeDataBuffer = buffer; + printerHandle->bulkInPipeDataLen = length; + return kStatus_USB_Success; + } + + status = USB_DeviceSendRequest(printerHandle->deviceHandle, ep, buffer, length); + if (kStatus_USB_Success != status) + { + printerHandle->bulkInBusy = 0U; + } + return status; +} + +usb_status_t USB_DevicePrinterRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length) +{ + usb_device_printer_struct_t *printerHandle = (usb_device_printer_struct_t *)handle; + usb_status_t status = kStatus_USB_Error; + + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + + if (printerHandle->bulkOutBusy) + { + return kStatus_USB_Busy; + } + printerHandle->bulkOutBusy = 1U; + + if (printerHandle->bulkOutPipeStall) + { + printerHandle->bulkOutPipeDataBuffer = buffer; + printerHandle->bulkOutPipeDataLen = length; + return kStatus_USB_Success; + } + status = USB_DeviceRecvRequest(printerHandle->deviceHandle, ep, buffer, length); + if (kStatus_USB_Success != status) + { + printerHandle->bulkOutBusy = 0U; + } + + return status; +} +#endif diff --git a/usb/device/class/usb_device_printer.h b/usb/device/class/usb_device_printer.h new file mode 100644 index 0000000..2099dc2 --- /dev/null +++ b/usb/device/class/usb_device_printer.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_PRINTER_H__ +#define __USB_DEVICE_PRINTER_H__ + +/*! + * @addtogroup usb_device_printer_drv + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief The class code of the printer class */ +#define USB_DEVICE_CONFIG_PRINTER_CLASS_CODE (0x07) + +/*! @brief class-specific request GET_DEVICE_ID */ +#define USB_DEVICE_PRINTER_GET_DEVICE_ID (0x00U) +/*! @brief class-specific request GET_PORT_STATUS */ +#define USB_DEVICE_PRINTER_GET_PORT_STATUS (0x01U) +/*! @brief class-specific request SOFT_RESET */ +#define USB_DEVICE_PRINTER_SOFT_RESET (0x02U) + +/*! @brief Paper empty bit mask for GET_PORT_STATUS */ +#define USB_DEVICE_PRINTER_PORT_STATUS_PAPER_EMPTRY_MASK (0x20U) +/*! @brief Select bit mask for GET_PORT_STATUS */ +#define USB_DEVICE_PRINTER_PORT_STATUS_SELECT_MASK (0x10U) +/*! @brief Error bit mask for GET_PORT_STATUS */ +#define USB_DEVICE_PRINTER_PORT_STATUS_NOT_ERROR_MASK (0x08U) + +#define USB_DEVICE_PRINTER_PORT_STATUS_DEFAULT_VALUE \ + (USB_DEVICE_PRINTER_PORT_STATUS_SELECT_MASK | USB_DEVICE_PRINTER_PORT_STATUS_NOT_ERROR_MASK) + +/*! @brief Available common EVENT types in printer class callback */ +typedef enum _usb_device_printer_event +{ + kUSB_DevicePrinterEventRecvResponse = 0x01U, /*!< Data received or cancelled etc*/ + kUSB_DevicePrinterEventSendResponse, /*!< Data send done or cancelled etc */ + kUSB_DevicePrinterEventGetDeviceId, /*!< Get device ID request */ + kUSB_DevicePrinterEventGetPortStatus, /*!< Get port status request */ + kUSB_DevicePrinterEventSoftReset, /*!< Soft reset request */ +} usb_device_printer_event_t; + +typedef struct _usb_device_printer_class_request +{ + uint8_t *buffer; /*!< The class specific request buffer address */ + uint32_t length; /*!< The class specific request buffer length */ + uint8_t interface; /*!< The class specific request interface index */ + uint8_t alternateSetting; /*!< GET_DEVICE_ID request alternate setting */ + uint8_t configIndex; /*!< GET_DEVICE_ID request config index */ +} usb_device_printer_class_request_t; + +/*! @brief The printer device class instance structure */ +typedef struct _usb_device_printer_struct +{ + usb_device_handle deviceHandle; /*!< The device handle */ + usb_device_class_config_struct_t *classConfig; /*!< The configuration of the class. */ + usb_device_interface_struct_t *interfaceHandle; /*!< Current interface handle */ + uint8_t *bulkInPipeDataBuffer; /*!< IN pipe data buffer backup when stall */ + uint32_t bulkInPipeDataLen; /*!< IN pipe data length backup when stall */ + uint8_t *bulkOutPipeDataBuffer; /*!< OUT pipe data buffer backup when stall */ + uint32_t bulkOutPipeDataLen; /*!< OUT pipe data length backup when stall */ + uint8_t configuration; /*!< Current configuration */ + uint8_t interfaceNumber; /*!< Interface number in the device descriptor */ + uint8_t alternate; /*!< Interface alternate value */ + uint8_t bulkInBusy; /*!< BULK IN pipe busy flag */ + uint8_t bulkOutBusy; /*!< BULK OUT pipe busy flag */ + uint8_t bulkInPipeStall; /*!< bulk IN pipe stall flag */ + uint8_t bulkOutPipeStall; /*!< bulk OUT pipe stall flag */ +} usb_device_printer_struct_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the printer class. + * + * This function is used to initialize the printer class. This function only can be called by #USB_DeviceClassInit. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t. + * @param[in] config The class configuration information. + * @param[out] handle A parameter used to return a pointer of the printer class handle to the caller. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DevicePrinterInit(uint8_t controllerId, + usb_device_class_config_struct_t *config, + class_handle_t *handle); + +/*! + * @brief De-initializes the device printer class. + * + * The function de-initializes the device printer class. This function only can be called by #USB_DeviceClassDeinit. + * + * @param[in] handle The printer class handle got from usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DevicePrinterDeinit(class_handle_t handle); + +/*! + * @brief Handles the event passed to the printer class. + * + * This function handles the event passed to the printer class. This function only can be called by + * #USB_DeviceClassEvent. + * + * @param[in] handle The printer class handle received from the usb_device_class_config_struct_t::classHandle. + * @param[in] event The event codes. See the enumeration usb_device_class_event_t. + * @param[in,out] param The parameter type is determined by the event code. + * + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Process event successfully. + * @retval kStatus_USB_InvalidHandle The device handle or parameter is invalid. + * @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe is stalled by the caller. + */ +extern usb_status_t USB_DevicePrinterEvent(void *handle, uint32_t event, void *param); + +/*! + * @name USB device printer class APIs + * @{ + */ + +/*! + * @brief Sends data through a specified endpoint. + * + * The function is used to send data through a specified endpoint. + * The function calls #USB_DeviceSendRequest internally. + * + * @param[in] handle The printer class handle received from usb_device_class_config_struct_t::classHandle. + * @param[in] ep Endpoint index. + * @param[in] buffer The memory address to hold the data need to be sent. + * @param[in] length The data length to be sent. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The function can only be called in the same context. + * + * @note The return value indicates whether the sending request is successful or not. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer can begin only when the previous transfer is done (a notification is received through the + * callback). + */ +extern usb_status_t USB_DevicePrinterSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length); + +/*! + * @brief Receives data through a specified endpoint. + * + * The function is used to receive data through a specified endpoint. + * The function calls #USB_DeviceSendRequest internally. + * + * @param[in] handle The printer class handle received from usb_device_class_config_struct_t::classHandle. + * @param[in] ep Endpoint index. + * @param[in] buffer The memory address to hold the data need to be sent. + * @param[in] length The data length to be sent. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The function can only be called in the same context. + * + * @note The return value indicates whether the sending request is successful or not. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer can begin only when the previous transfer is done (a notification is received through the + * callback). + */ +extern usb_status_t USB_DevicePrinterRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length); + +/*! @}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __USB_DEVICE_PRINTER_H__ */ diff --git a/usb/device/class/usb_device_video.c b/usb/device/class/usb_device_video.c new file mode 100644 index 0000000..7beb9c5 --- /dev/null +++ b/usb/device/class/usb_device_video.c @@ -0,0 +1,1437 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device.h" + +#include "usb_device_class.h" + +#if ((defined(USB_DEVICE_CONFIG_VIDEO)) && (USB_DEVICE_CONFIG_VIDEO > 0U)) +#include "usb_device_video.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +static usb_status_t USB_DeviceVideoAllocateHandle(usb_device_video_struct_t **handle); +static usb_status_t USB_DeviceVideoFreeHandle(usb_device_video_struct_t *handle); +static usb_status_t USB_DeviceVideoControlIn(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam); +static usb_status_t USB_DeviceVideoStreamIn(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam); +static usb_status_t USB_DeviceVideoStreamOut(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam); +static usb_status_t USB_DeviceVideoStreamEndpointsInit(usb_device_video_struct_t *videoHandle); +static usb_status_t USB_DeviceVideoStreamEndpointsDeinit(usb_device_video_struct_t *videoHandle); +static usb_status_t USB_DeviceVideoControlEndpointsInit(usb_device_video_struct_t *videoHandle); +static usb_status_t USB_DeviceVideoControlEndpointsDeinit(usb_device_video_struct_t *videoHandle); + +static usb_status_t USB_DeviceVideoVcPowerModeControl(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest); +static usb_status_t USB_DeviceVideoVcInterfaceRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest); +static usb_status_t USB_DeviceVideoVcCameraTerminalRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest); +static usb_status_t USB_DeviceVideoVcProcessingUnitRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest); +static usb_status_t USB_DeviceVideoVcRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest); +static usb_status_t USB_DeviceVideoVsProbeRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest); +static usb_status_t USB_DeviceVideoVsCommitRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest); +static usb_status_t USB_DeviceVideoVsStillProbeRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest); +static usb_status_t USB_DeviceVideoVsStillCommitRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest); +static usb_status_t USB_DeviceVideoVsStillImageTriggerRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest); +static usb_status_t USB_DeviceVideoVsRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_video_struct_t + s_UsbDeviceVideoHandle[USB_DEVICE_CONFIG_VIDEO]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Allocate a device video class handle. + * + * This function allocates a device video class handle. + * + * @param handle It is out parameter, is used to return pointer of the device video class handle to the caller. + * + * @retval kStatus_USB_Success Get a device video class handle successfully. + * @retval kStatus_USB_Busy Cannot allocate a device video class handle. + */ +static usb_status_t USB_DeviceVideoAllocateHandle(usb_device_video_struct_t **handle) +{ + int32_t count; + USB_OSA_SR_ALLOC(); + + USB_OSA_ENTER_CRITICAL(); + for (count = 0U; count < USB_DEVICE_CONFIG_VIDEO; count++) + { + if (NULL == s_UsbDeviceVideoHandle[count].handle) + { + *handle = &s_UsbDeviceVideoHandle[count]; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + } + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Busy; +} + +/*! + * @brief Free a device video class handle. + * + * This function frees a device video class handle. + * + * @param handle The device video class handle. + * + * @retval kStatus_USB_Success Free device video class handle successfully. + */ +static usb_status_t USB_DeviceVideoFreeHandle(usb_device_video_struct_t *handle) +{ + USB_OSA_SR_ALLOC(); + + USB_OSA_ENTER_CRITICAL(); + handle->handle = NULL; + handle->configStruct = (usb_device_class_config_struct_t *)NULL; + handle->configuration = 0U; + handle->controlAlternate = 0U; + handle->streamAlternate = 0U; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; +} + +/*! + * @brief Interrupt IN endpoint callback function. + * + * This callback function is used to notify uplayer the transfser result of a transfer. + * This callback pointer is passed when the interrupt IN pipe initialized. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The result of the interrupt IN pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the video class handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoControlIn(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_video_struct_t *videoHandle; + usb_status_t error = kStatus_USB_Error; + + /* Get the video class handle */ + videoHandle = (usb_device_video_struct_t *)callbackParam; + + if (!videoHandle) + { + return kStatus_USB_InvalidHandle; + } + + if ((NULL != videoHandle->configStruct) && (videoHandle->configStruct->classCallback)) + { + /* Notify the application control data sent by calling the video class callback. + ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = videoHandle->configStruct->classCallback((class_handle_t)videoHandle, + kUSB_DeviceVideoEventControlSendResponse, message); + } + + return error; +} + +/*! + * @brief ISO IN endpoint callback function. + * + * This callback function is used to notify uplayer the transfser result of a transfer. + * This callback pointer is passed when the ISO IN pipe initialized. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The result of the ISO IN pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the video class handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoStreamIn(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_video_struct_t *videoHandle; + usb_status_t error = kStatus_USB_Error; + + /* Get the video class handle */ + videoHandle = (usb_device_video_struct_t *)callbackParam; + + if (!videoHandle) + { + return kStatus_USB_InvalidHandle; + } + videoHandle->streamInPipeBusy = 0U; + if ((NULL != videoHandle->configStruct) && (videoHandle->configStruct->classCallback)) + { + /* Notify the application stream data sent by calling the video class callback. + ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = videoHandle->configStruct->classCallback((class_handle_t)videoHandle, + kUSB_DeviceVideoEventStreamSendResponse, message); + } + + return error; +} + +/*! + * @brief ISO OUT endpoint callback function. + * + * This callback function is used to notify uplayer the transfser result of a transfer. + * This callback pointer is passed when the ISO OUT pipe initialized. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The result of the ISO OUT pipe transfer. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the video class handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoStreamOut(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_device_video_struct_t *videoHandle; + usb_status_t error = kStatus_USB_Error; + + /* Get the video class handle */ + videoHandle = (usb_device_video_struct_t *)callbackParam; + + if (!videoHandle) + { + return kStatus_USB_InvalidHandle; + } + videoHandle->streamOutPipeBusy = 0U; + if ((NULL != videoHandle->configStruct) && (videoHandle->configStruct->classCallback)) + { + /* Notify the application stream data sent by calling the video class callback. + ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = videoHandle->configStruct->classCallback((class_handle_t)videoHandle, + kUSB_DeviceVideoEventStreamRecvResponse, message); + } + + return error; +} + +/*! + * @brief Initialize the stream endpoints of the video class. + * + * This callback function is used to initialize the stream endpoints of the video class. + * + * @param videoHandle The device video class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoStreamEndpointsInit(usb_device_video_struct_t *videoHandle) +{ + usb_device_interface_list_t *interfaceList; + usb_device_interface_struct_t *interface = (usb_device_interface_struct_t *)NULL; + usb_status_t error = kStatus_USB_Error; + + /* Check the configuration is valid or not. */ + if (!videoHandle->configuration) + { + return error; + } + + if (videoHandle->configuration > videoHandle->configStruct->classInfomation->configurations) + { + return error; + } + + /* Get the interface list of the new configuration. */ + if (NULL == videoHandle->configStruct->classInfomation->interfaceList) + { + return error; + } + interfaceList = &videoHandle->configStruct->classInfomation->interfaceList[videoHandle->configuration - 1U]; + + /* Find stream interface by using the alternate setting of the interface. */ + for (int count = 0U; count < interfaceList->count; count++) + { + if ((USB_DEVICE_VIDEO_CC_VIDEO == interfaceList->interfaces[count].classCode) && + (USB_DEVICE_VIDEO_SC_VIDEOSTREAMING == interfaceList->interfaces[count].subclassCode)) + { + for (int index = 0U; index < interfaceList->interfaces[count].count; index++) + { + if (interfaceList->interfaces[count].interface[index].alternateSetting == videoHandle->streamAlternate) + { + interface = &interfaceList->interfaces[count].interface[index]; + break; + } + } + videoHandle->streamInterfaceNumber = interfaceList->interfaces[count].interfaceNumber; + break; + } + } + if (!interface) + { + /* Return error if the stream interface is not found. */ + return error; + } + + /* Keep new stream interface handle. */ + videoHandle->streamInterfaceHandle = interface; + + /* Initialize the endpoints of the new interface. */ + for (int count = 0U; count < interface->endpointList.count; count++) + { + usb_device_endpoint_init_struct_t epInitStruct; + usb_device_endpoint_callback_struct_t epCallback; + epInitStruct.zlt = 0U; + epInitStruct.interval = interface->endpointList.endpoint[count].interval; + epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress; + epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize; + epInitStruct.transferType = interface->endpointList.endpoint[count].transferType; + + if ((USB_ENDPOINT_ISOCHRONOUS == (epInitStruct.transferType & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK)) && + (USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))) + { + epCallback.callbackFn = USB_DeviceVideoStreamIn; + } + else if ((USB_ENDPOINT_ISOCHRONOUS == + (epInitStruct.transferType & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK)) && + (USB_OUT == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))) + { + epCallback.callbackFn = USB_DeviceVideoStreamOut; + } + else + { + continue; + } + epCallback.callbackParam = videoHandle; + + error = USB_DeviceInitEndpoint(videoHandle->handle, &epInitStruct, &epCallback); + } + return error; +} + +/*! + * @brief De-initialize the stream endpoints of the video class. + * + * This callback function is used to de-initialize the stream endpoints of the video class. + * + * @param videoHandle The device video class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoStreamEndpointsDeinit(usb_device_video_struct_t *videoHandle) +{ + usb_status_t error = kStatus_USB_Error; + + if (!videoHandle->streamInterfaceHandle) + { + return error; + } + /* De-initialize all stream endpoints of the interface */ + for (int count = 0U; count < videoHandle->streamInterfaceHandle->endpointList.count; count++) + { + error = USB_DeviceDeinitEndpoint( + videoHandle->handle, videoHandle->streamInterfaceHandle->endpointList.endpoint[count].endpointAddress); + } + videoHandle->streamInterfaceHandle = NULL; + return error; +} + +/*! + * @brief Initialize the control endpoints of the video class. + * + * This callback function is used to initialize the control endpoints of the video class. + * + * @param videoHandle The device video class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoControlEndpointsInit(usb_device_video_struct_t *videoHandle) +{ + usb_device_interface_list_t *interfaceList; + usb_device_interface_struct_t *interface = (usb_device_interface_struct_t *)NULL; + usb_status_t error = kStatus_USB_Error; + + /* Check the configuration is valid or not. */ + if (!videoHandle->configuration) + { + return error; + } + + if (videoHandle->configuration > videoHandle->configStruct->classInfomation->configurations) + { + return error; + } + + /* Get the control interface list of the new configuration. */ + if (NULL == videoHandle->configStruct->classInfomation->interfaceList) + { + return error; + } + interfaceList = &videoHandle->configStruct->classInfomation->interfaceList[videoHandle->configuration - 1U]; + + /* Find control interface by using the alternate setting of the interface. */ + for (int count = 0U; count < interfaceList->count; count++) + { + if ((USB_DEVICE_VIDEO_CC_VIDEO == interfaceList->interfaces[count].classCode) && + (USB_DEVICE_VIDEO_SC_VIDEOCONTROL == interfaceList->interfaces[count].subclassCode)) + { + for (int index = 0U; index < interfaceList->interfaces[count].count; index++) + { + if (interfaceList->interfaces[count].interface[index].alternateSetting == videoHandle->controlAlternate) + { + interface = &interfaceList->interfaces[count].interface[index]; + break; + } + } + videoHandle->controlInterfaceNumber = interfaceList->interfaces[count].interfaceNumber; + break; + } + } + if (!interface) + { + /* Return error if the control interface is not found. */ + return error; + } + /* Keep new control interface handle. */ + videoHandle->controlInterfaceHandle = interface; + + /* Initialize the control endpoints of the new interface. */ + for (int count = 0U; count < interface->endpointList.count; count++) + { + usb_device_endpoint_init_struct_t epInitStruct; + usb_device_endpoint_callback_struct_t epCallback; + epInitStruct.zlt = 0U; + epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress; + epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize; + epInitStruct.transferType = interface->endpointList.endpoint[count].transferType; + + if ((USB_ENDPOINT_INTERRUPT == (epInitStruct.transferType & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK)) && + (USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))) + { + epCallback.callbackFn = USB_DeviceVideoControlIn; + } + else + { + continue; + } + epCallback.callbackParam = videoHandle; + + error = USB_DeviceInitEndpoint(videoHandle->handle, &epInitStruct, &epCallback); + } + return error; +} + +/*! + * @brief De-initialize the control endpoints of the video class. + * + * This callback function is used to de-initialize the control endpoints of the video class. + * + * @param videoHandle The device video class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoControlEndpointsDeinit(usb_device_video_struct_t *videoHandle) +{ + usb_status_t error = kStatus_USB_Error; + + if (!videoHandle->controlInterfaceHandle) + { + return error; + } + /* De-initialize all control endpoints of the interface */ + for (int count = 0U; count < videoHandle->controlInterfaceHandle->endpointList.count; count++) + { + error = USB_DeviceDeinitEndpoint( + videoHandle->handle, videoHandle->controlInterfaceHandle->endpointList.endpoint[count].endpointAddress); + } + videoHandle->controlInterfaceHandle = NULL; + return error; +} + +/*! + * @brief Handle the video device vc power modex control request. + * + * This callback function is used to handle the video device vc power modex control request. + * + * @param videoHandle The device video class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoVcPowerModeControl(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint32_t command = 0U; + + switch (controlRequest->setup->bRequest) + { + case USB_DEVICE_VIDEO_REQUEST_CODE_SET_CUR: + command = USB_DEVICE_VIDEO_SET_CUR_VC_POWER_MODE_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_CUR: + command = USB_DEVICE_VIDEO_GET_CUR_VC_POWER_MODE_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_INFO: + command = USB_DEVICE_VIDEO_GET_INFO_VC_POWER_MODE_CONTROL; + break; + default: + break; + } + if ((command) && (NULL != videoHandle->configStruct) && (videoHandle->configStruct->classCallback)) + { + /* ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = videoHandle->configStruct->classCallback((class_handle_t)videoHandle, command, controlRequest); + } + return error; +} + +/*! + * @brief Handle the video device control interface class-specific request. + * + * This callback function is used to handle the video device control pipe class-specific request. + * + * @param videoHandle The device video class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoVcInterfaceRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t cs = (controlRequest->setup->wValue >> 0x08U) & 0xFFU; + + if (USB_DEVICE_VIDEO_VC_VIDEO_POWER_MODE_CONTROL == cs) + { + /* handle the video device vc power modex control request */ + error = USB_DeviceVideoVcPowerModeControl(videoHandle, controlRequest); + } + else if (USB_DEVICE_VIDEO_VC_REQUEST_ERROR_CODE_CONTROL == cs) + { + } + else + { + } + return error; +} + +/*! + * @brief Handle the video device camera terminal control request. + * + * This callback function is used to handle the video device camera terminal control request. + * + * @param videoHandle The device video class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoVcCameraTerminalRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t cs = (controlRequest->setup->wValue >> 0x08U) & 0xFFU; + + switch (cs) + { + case USB_DEVICE_VIDEO_CT_SCANNING_MODE_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_AE_MODE_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_AE_PRIORITY_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_EXPOSURE_TIME_RELATIVE_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_FOCUS_ABSOLUTE_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_FOCUS_RELATIVE_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_FOCUS_AUTO_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_IRIS_ABSOLUTE_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_IRIS_RELATIVE_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_ZOOM_ABSOLUTE_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_ZOOM_RELATIVE_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_PANTILT_ABSOLUTE_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_PANTILT_RELATIVE_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_ROLL_ABSOLUTE_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_ROLL_RELATIVE_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_PRIVACY_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_FOCUS_SIMPLE_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_WINDOW_CONTROL: + break; + case USB_DEVICE_VIDEO_CT_REGION_OF_INTEREST_CONTROL: + break; + default: + break; + } + return error; +} + +/*! + * @brief Handle the video device processing uint control request. + * + * This callback function is used to handle the video device processing uint control request. + * + * @param videoHandle The device video class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoVcProcessingUnitRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t cs = (controlRequest->setup->wValue >> 0x08U) & 0xFFU; + + switch (cs) + { + case USB_DEVICE_VIDEO_PU_BACKLIGHT_COMPENSATION_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_BRIGHTNESS_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_CONTRAST_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_GAIN_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_POWER_LINE_FREQUENCY_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_HUE_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_SATURATION_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_SHARPNESS_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_GAMMA_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_WHITE_BALANCE_TEMPERATURE_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_WHITE_BALANCE_COMPONENT_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_DIGITAL_MULTIPLIER_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_HUE_AUTO_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_ANALOG_VIDEO_STANDARD_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_ANALOG_LOCK_STATUS_CONTROL: + break; + case USB_DEVICE_VIDEO_PU_CONTRAST_AUTO_CONTROL: + break; + default: + break; + } + + return error; +} + +/*! + * @brief Handle the video device control request. + * + * This callback function is used to handle the video device control request, + * including the control interface, uint or terminal control. + * + * @param videoHandle The device video class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoVcRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_device_video_entities_struct_t *entity_list; + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t entityId = (uint8_t)(controlRequest->setup->wIndex >> 0x08U); + + if (!videoHandle->controlInterfaceHandle) + { + return error; + } + + /* Get the video class-specific information. */ + entity_list = (usb_device_video_entities_struct_t *)videoHandle->controlInterfaceHandle->classSpecific; + + if (0U == entityId) + { + /* Handle the video control interface request. */ + error = USB_DeviceVideoVcInterfaceRequest(videoHandle, controlRequest); + } + else + { + for (int i = 0U; i < entity_list->count; i++) + { + if (entityId == entity_list->entity[i].entityId) + { + switch (entity_list->entity[i].entityType) + { + case USB_DESCRIPTOR_SUBTYPE_VIDEO_VC_INPUT_TERMINAL: + if (USB_DEVICE_VIDEO_ITT_CAMERA == entity_list->entity[i].terminalType) + { + /* Handle the video camera terminal control request. */ + error = USB_DeviceVideoVcCameraTerminalRequest(videoHandle, controlRequest); + } + break; + case USB_DESCRIPTOR_SUBTYPE_VIDEO_VC_OUTPUT_TERMINAL: + break; + case USB_DESCRIPTOR_SUBTYPE_VIDEO_VC_SELECTOR_UNIT: + break; + case USB_DESCRIPTOR_SUBTYPE_VIDEO_VC_PROCESSING_UNIT: + /* Handle the video processing uint control request. */ + error = USB_DeviceVideoVcProcessingUnitRequest(videoHandle, controlRequest); + break; + case USB_DESCRIPTOR_SUBTYPE_VIDEO_VC_EXTENSION_UNIT: + break; + case USB_DESCRIPTOR_SUBTYPE_VIDEO_VC_ENCODING_UNIT: + break; + default: + break; + } + } + } + } + return error; +} + +/*! + * @brief Handle the video device probe control request. + * + * This callback function is used to handle the video device probe control request, + * + * @param videoHandle The device video class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoVsProbeRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint32_t command = 0U; + + switch (controlRequest->setup->bRequest) + { + case USB_DEVICE_VIDEO_REQUEST_CODE_SET_CUR: + command = USB_DEVICE_VIDEO_SET_CUR_VS_PROBE_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_CUR: + command = USB_DEVICE_VIDEO_GET_CUR_VS_PROBE_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_MIN: + command = USB_DEVICE_VIDEO_GET_MIN_VS_PROBE_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_MAX: + command = USB_DEVICE_VIDEO_GET_MAX_VS_PROBE_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_RES: + command = USB_DEVICE_VIDEO_GET_RES_VS_PROBE_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_LEN: + command = USB_DEVICE_VIDEO_GET_LEN_VS_PROBE_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_INFO: + command = USB_DEVICE_VIDEO_GET_INFO_VS_PROBE_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_DEF: + command = USB_DEVICE_VIDEO_GET_DEF_VS_PROBE_CONTROL; + break; + default: + break; + } + if ((command) && (NULL != videoHandle->configStruct) && (videoHandle->configStruct->classCallback)) + { + /*ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit*/ + error = videoHandle->configStruct->classCallback((class_handle_t)videoHandle, command, controlRequest); + } + return error; +} + +/*! + * @brief Handle the video device commit control request. + * + * This callback function is used to handle the video device commit control request, + * + * @param videoHandle The device video class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoVsCommitRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint32_t command = 0U; + + switch (controlRequest->setup->bRequest) + { + case USB_DEVICE_VIDEO_REQUEST_CODE_SET_CUR: + command = USB_DEVICE_VIDEO_SET_CUR_VS_COMMIT_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_CUR: + command = USB_DEVICE_VIDEO_GET_CUR_VS_COMMIT_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_LEN: + command = USB_DEVICE_VIDEO_GET_LEN_VS_COMMIT_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_INFO: + command = USB_DEVICE_VIDEO_GET_INFO_VS_COMMIT_CONTROL; + break; + default: + break; + } + if ((command) && (NULL != videoHandle->configStruct) && (videoHandle->configStruct->classCallback)) + { + /* ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = videoHandle->configStruct->classCallback((class_handle_t)videoHandle, command, controlRequest); + } + return error; +} + +/*! + * @brief Handle the video device still probe control request. + * + * This callback function is used to handle the video device still probe control request, + * + * @param videoHandle The device video class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoVsStillProbeRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint32_t command = 0U; + + switch (controlRequest->setup->bRequest) + { + case USB_DEVICE_VIDEO_REQUEST_CODE_SET_CUR: + command = USB_DEVICE_VIDEO_SET_CUR_VS_STILL_PROBE_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_CUR: + command = USB_DEVICE_VIDEO_GET_CUR_VS_STILL_PROBE_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_MIN: + command = USB_DEVICE_VIDEO_GET_MIN_VS_STILL_PROBE_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_MAX: + command = USB_DEVICE_VIDEO_GET_MAX_VS_STILL_PROBE_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_RES: + command = USB_DEVICE_VIDEO_GET_RES_VS_STILL_PROBE_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_LEN: + command = USB_DEVICE_VIDEO_GET_LEN_VS_STILL_PROBE_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_INFO: + command = USB_DEVICE_VIDEO_GET_INFO_VS_STILL_PROBE_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_DEF: + command = USB_DEVICE_VIDEO_GET_DEF_VS_STILL_PROBE_CONTROL; + break; + default: + break; + } + if ((command) && (NULL != videoHandle->configStruct) && (videoHandle->configStruct->classCallback)) + { + /*ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit*/ + error = videoHandle->configStruct->classCallback((class_handle_t)videoHandle, command, controlRequest); + } + return error; +} + +/*! + * @brief Handle the video device still commit control request. + * + * This callback function is used to handle the video device still commit control request, + * + * @param videoHandle The device video class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoVsStillCommitRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint32_t command = 0U; + + switch (controlRequest->setup->bRequest) + { + case USB_DEVICE_VIDEO_REQUEST_CODE_SET_CUR: + command = USB_DEVICE_VIDEO_SET_CUR_VS_STILL_COMMIT_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_CUR: + command = USB_DEVICE_VIDEO_SET_CUR_VS_STILL_COMMIT_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_LEN: + command = USB_DEVICE_VIDEO_SET_CUR_VS_STILL_COMMIT_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_INFO: + command = USB_DEVICE_VIDEO_SET_CUR_VS_STILL_COMMIT_CONTROL; + break; + default: + break; + } + if ((command) && (NULL != videoHandle->configStruct) && (videoHandle->configStruct->classCallback)) + { + /* ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = videoHandle->configStruct->classCallback((class_handle_t)videoHandle, command, controlRequest); + } + return error; +} + +/*! + * @brief Handle the video device still image trigger control request. + * + * This callback function is used to handle the video device still image trigger control request, + * + * @param videoHandle The device video class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoVsStillImageTriggerRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint32_t command = 0U; + + switch (controlRequest->setup->bRequest) + { + case USB_DEVICE_VIDEO_REQUEST_CODE_SET_CUR: + command = USB_DEVICE_VIDEO_SET_CUR_VS_STILL_IMAGE_TRIGGER_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_CUR: + command = USB_DEVICE_VIDEO_GET_CUR_VS_STILL_IMAGE_TRIGGER_CONTROL; + break; + case USB_DEVICE_VIDEO_REQUEST_CODE_GET_INFO: + command = USB_DEVICE_VIDEO_GET_INFO_VS_STILL_IMAGE_TRIGGER_CONTROL; + break; + default: + break; + } + if ((command) && (NULL != videoHandle->configStruct) && (videoHandle->configStruct->classCallback)) + { + /* ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit */ + error = videoHandle->configStruct->classCallback((class_handle_t)videoHandle, command, controlRequest); + } + return error; +} + +/*! + * @brief Handle the video device stream interface control request. + * + * This callback function is used to handle the video devicestream interface controll request, + * + * @param videoHandle The device video class handle. It equals the value returned from + * usb_device_class_config_struct_t::classHandle. + * @param controlRequest The pointer of the control request structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceVideoVsRequest(usb_device_video_struct_t *videoHandle, + usb_device_control_request_struct_t *controlRequest) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t cs = (controlRequest->setup->wValue >> 0x08U) & 0xFFU; + + switch (cs) + { + case USB_DEVICE_VIDEO_VS_PROBE_CONTROL: + /* Handle device video probe control request. */ + error = USB_DeviceVideoVsProbeRequest(videoHandle, controlRequest); + break; + case USB_DEVICE_VIDEO_VS_COMMIT_CONTROL: + /* Handle device video commit control request. */ + error = USB_DeviceVideoVsCommitRequest(videoHandle, controlRequest); + break; + case USB_DEVICE_VIDEO_VS_STILL_PROBE_CONTROL: + /* Handle device video still probe control request. */ + error = USB_DeviceVideoVsStillProbeRequest(videoHandle, controlRequest); + break; + case USB_DEVICE_VIDEO_VS_STILL_COMMIT_CONTROL: + /* Handle device video still commit control request. */ + error = USB_DeviceVideoVsStillCommitRequest(videoHandle, controlRequest); + break; + case USB_DEVICE_VIDEO_VS_STILL_IMAGE_TRIGGER_CONTROL: + /* Handle device video still image trigger control request. */ + error = USB_DeviceVideoVsStillImageTriggerRequest(videoHandle, controlRequest); + break; + case USB_DEVICE_VIDEO_VS_STREAM_ERROR_CODE_CONTROL: + break; + case USB_DEVICE_VIDEO_VS_GENERATE_KEY_FRAME_CONTROL: + break; + case USB_DEVICE_VIDEO_VS_UPDATE_FRAME_SEGMENT_CONTROL: + break; + case USB_DEVICE_VIDEO_VS_SYNCH_DELAY_CONTROL: + break; + default: + break; + } + + return error; +} + +/*! + * @brief Handle the event passed to the video class. + * + * This function handles the event passed to the video class. + * + * @param handle The video class handle, got from the usb_device_class_config_struct_t::classHandle. + * @param event The event codes. Please refer to the enumeration usb_device_class_event_t. + * @param param The param type is determined by the event code. + * + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The device handle not be found. + * @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe will be stalled by the caller. + */ +usb_status_t USB_DeviceVideoEvent(void *handle, uint32_t event, void *param) +{ + usb_device_video_struct_t *videoHandle; + usb_status_t error = kStatus_USB_Error; + uint16_t interfaceAlternate; + uint8_t *temp8; + uint8_t alternate; + + if ((!param) || (!handle)) + { + return kStatus_USB_InvalidHandle; + } + + /* Get the video class handle. */ + videoHandle = (usb_device_video_struct_t *)handle; + + switch (event) + { + case kUSB_DeviceClassEventDeviceReset: + /* Bus reset, clear the configuration. */ + videoHandle->configuration = 0U; + videoHandle->streamOutPipeBusy = 0U; + videoHandle->streamInPipeBusy = 0U; + break; + case kUSB_DeviceClassEventSetConfiguration: + /* Get the new configuration. */ + temp8 = ((uint8_t *)param); + if (!videoHandle->configStruct) + { + break; + } + if (*temp8 == videoHandle->configuration) + { + break; + } + /* De-initialize the endpoints when current configuration is none zero. */ + if (videoHandle->configuration) + { + error = USB_DeviceVideoControlEndpointsDeinit(videoHandle); + error = USB_DeviceVideoStreamEndpointsDeinit(videoHandle); + } + /* Save new configuration. */ + videoHandle->configuration = *temp8; + /* Clear the alternate setting value. */ + videoHandle->controlAlternate = 0U; + /* Clear the alternate setting value. */ + videoHandle->streamAlternate = 0U; + videoHandle->controlInterfaceHandle = NULL; + videoHandle->streamInterfaceHandle = NULL; + /* Initialize the control endpoints of the new current configuration by using the alternate setting 0. */ + error = USB_DeviceVideoControlEndpointsInit(videoHandle); + /* Initialize the stream endpoints of the new current configuration by using the alternate setting 0. */ + error = USB_DeviceVideoStreamEndpointsInit(videoHandle); + break; + case kUSB_DeviceClassEventSetInterface: + if (!videoHandle->configStruct) + { + break; + } + /* Get the new alternate setting of the interface */ + interfaceAlternate = *((uint16_t *)param); + /* Get the alternate setting value */ + alternate = (uint8_t)(interfaceAlternate & 0xFFU); + + /* Whether the interface belongs to the class. */ + if (videoHandle->controlInterfaceNumber == ((uint8_t)(interfaceAlternate >> 8U))) + { + /* When the interface is control interface. */ + /* Only handle new alternate setting. */ + if (alternate == videoHandle->controlAlternate) + { + break; + } + /* De-initialize old endpoints */ + error = USB_DeviceVideoControlEndpointsDeinit(videoHandle); + videoHandle->controlAlternate = alternate; + /* Initialize new endpoints */ + error = USB_DeviceVideoControlEndpointsInit(videoHandle); + } + else if (videoHandle->streamInterfaceNumber == ((uint8_t)(interfaceAlternate >> 8U))) + { + /* When the interface is stream interface. */ + /* Only handle new alternate setting. */ + if (alternate == videoHandle->streamAlternate) + { + break; + } + /* De-initialize old endpoints */ + error = USB_DeviceVideoStreamEndpointsDeinit(videoHandle); + videoHandle->streamAlternate = alternate; + /* Initialize new endpoints */ + error = USB_DeviceVideoStreamEndpointsInit(videoHandle); + } + else + { + } + break; + case kUSB_DeviceClassEventSetEndpointHalt: + if (!videoHandle->configStruct) + { + break; + } + /* Get the endpoint address */ + temp8 = ((uint8_t *)param); + if (videoHandle->controlInterfaceHandle) + { + for (int count = 0U; count < videoHandle->controlInterfaceHandle->endpointList.count; count++) + { + if (*temp8 == videoHandle->controlInterfaceHandle->endpointList.endpoint[count].endpointAddress) + { + /* Only stall the endpoint belongs to control interface of the class */ + error = USB_DeviceStallEndpoint(videoHandle->handle, *temp8); + } + } + } + if (videoHandle->streamInterfaceHandle) + { + for (int count = 0U; count < videoHandle->streamInterfaceHandle->endpointList.count; count++) + { + if (*temp8 == videoHandle->streamInterfaceHandle->endpointList.endpoint[count].endpointAddress) + { + /* Only stall the endpoint belongs to stream interface of the class */ + error = USB_DeviceStallEndpoint(videoHandle->handle, *temp8); + } + } + } + break; + case kUSB_DeviceClassEventClearEndpointHalt: + if (!videoHandle->configStruct) + { + break; + } + /* Get the endpoint address */ + temp8 = ((uint8_t *)param); + if (videoHandle->controlInterfaceHandle) + { + for (int count = 0U; count < videoHandle->controlInterfaceHandle->endpointList.count; count++) + { + if (*temp8 == videoHandle->controlInterfaceHandle->endpointList.endpoint[count].endpointAddress) + { + /* Only un-stall the endpoint belongs to control interface of the class */ + error = USB_DeviceUnstallEndpoint(videoHandle->handle, *temp8); + } + } + } + if (videoHandle->streamInterfaceHandle) + { + for (int count = 0U; count < videoHandle->streamInterfaceHandle->endpointList.count; count++) + { + if (*temp8 == videoHandle->streamInterfaceHandle->endpointList.endpoint[count].endpointAddress) + { + /* Only un-stall the endpoint belongs to stream interface of the class */ + error = USB_DeviceUnstallEndpoint(videoHandle->handle, *temp8); + } + } + } + break; + case kUSB_DeviceClassEventClassRequest: + if (param) + { + /* Handle the video class specific request. */ + usb_device_control_request_struct_t *controlRequest = (usb_device_control_request_struct_t *)param; + uint8_t interface_index = (uint8_t)controlRequest->setup->wIndex; + + if ((controlRequest->setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != + USB_REQUEST_TYPE_RECIPIENT_INTERFACE) + { + break; + } + + switch (controlRequest->setup->bmRequestType) + { + case USB_DEVICE_VIDEO_SET_REQUEST_INTERFACE: + if (controlRequest->isSetup) + { + /* Get the buffer to receive the data sent from the host. */ + if ((NULL != videoHandle->configStruct) && (videoHandle->configStruct->classCallback)) + { + /*ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap, + it is from the second parameter of classInit*/ + error = videoHandle->configStruct->classCallback( + (class_handle_t)videoHandle, kUSB_DeviceVideoEventClassRequestBuffer, + controlRequest); + } + break; + } + case USB_DEVICE_VIDEO_GET_REQUEST_INTERFACE: + if (videoHandle->controlInterfaceNumber == interface_index) + { + error = USB_DeviceVideoVcRequest(videoHandle, controlRequest); + } + else if (videoHandle->streamInterfaceNumber == interface_index) + { + error = USB_DeviceVideoVsRequest(videoHandle, controlRequest); + } + else + { + } + break; + default: + break; + } + } + break; + default: + break; + } + return error; +} + +/*! + * @brief Initialize the video class. + * + * This function is used to initialize the video class. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param config The class configuration information. + * @param handle It is out parameter, is used to return pointer of the video class handle to the caller. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceVideoInit(uint8_t controllerId, usb_device_class_config_struct_t *config, class_handle_t *handle) +{ + usb_device_video_struct_t *videoHandle; + usb_status_t error = kStatus_USB_Error; + + /* Allocate a video class handle. */ + error = USB_DeviceVideoAllocateHandle(&videoHandle); + + if (kStatus_USB_Success != error) + { + return error; + } + + /* Get the device handle according to the controller id. */ + error = USB_DeviceClassGetDeviceHandle(controllerId, &videoHandle->handle); + + if (kStatus_USB_Success != error) + { + return error; + } + + if (!videoHandle->handle) + { + return kStatus_USB_InvalidHandle; + } + /* Save the configuration of the class. */ + videoHandle->configStruct = config; + /* Clear the configuration value. */ + videoHandle->configuration = 0U; + videoHandle->streamAlternate = 0xffU; + videoHandle->controlAlternate = 0xffU; + + *handle = (class_handle_t)videoHandle; + return error; +} + +/*! + * @brief De-initialize the device video class. + * + * The function de-initializes the device video class. + * + * @param handle The ccid class handle got from usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceVideoDeinit(class_handle_t handle) +{ + usb_device_video_struct_t *videoHandle; + usb_status_t error = kStatus_USB_Error; + + videoHandle = (usb_device_video_struct_t *)handle; + + if (!videoHandle) + { + return kStatus_USB_InvalidHandle; + } + /* De-initialzie the stream endpoints. */ + error = USB_DeviceVideoStreamEndpointsDeinit(videoHandle); + /* De-initialzie the control endpoints. */ + error = USB_DeviceVideoControlEndpointsDeinit(videoHandle); + /* Free the video class handle. */ + USB_DeviceVideoFreeHandle(videoHandle); + return error; +} + +/*! + * @brief Send data through a specified endpoint. + * + * The function is used to send data through a specified endpoint. + * The function calls USB_DeviceSendRequest internally. + * + * @param handle The video class handle got from usb_device_class_config_struct_t::classHandle. + * @param endpointAddress Endpoint index. + * @param buffer The memory address to hold the data need to be sent. + * @param length The data length need to be sent. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value just means if the sending request is successful or not; the transfer done is notified by + * USB_DeviceVideoStreamIn or USB_DeviceVideoControlIn. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceVideoSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length) +{ + usb_device_video_struct_t *videoHandle; + usb_status_t error = kStatus_USB_Error; + + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + videoHandle = (usb_device_video_struct_t *)handle; + + if (videoHandle->streamInPipeBusy) + { + return kStatus_USB_Busy; + } + videoHandle->streamInPipeBusy = 1U; + + error = USB_DeviceSendRequest(videoHandle->handle, ep, buffer, length); + if (kStatus_USB_Success != error) + { + videoHandle->streamInPipeBusy = 0U; + } + return error; +} + +/*! + * @brief Receive data through a specified endpoint. + * + * The function is used to receive data through a specified endpoint. + * The function calls USB_DeviceRecvRequest internally. + * + * @param handle The video class handle got from usb_device_class_config_struct_t::classHandle. + * @param endpointAddress Endpoint index. + * @param buffer The memory address to save the received data. + * @param length The data length want to be received. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value just means if the receiving request is successful or not; the transfer done is notified by + * USB_DeviceVideoStreamOut. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceVideoRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length) +{ + usb_device_video_struct_t *videoHandle; + usb_status_t error = kStatus_USB_Error; + + if (!handle) + { + return kStatus_USB_InvalidHandle; + } + videoHandle = (usb_device_video_struct_t *)handle; + + if (videoHandle->streamOutPipeBusy) + { + return kStatus_USB_Busy; + } + videoHandle->streamOutPipeBusy = 1U; + + error = USB_DeviceRecvRequest(videoHandle->handle, ep, buffer, length); + if (kStatus_USB_Success != error) + { + videoHandle->streamOutPipeBusy = 0U; + } + return error; +} + +#endif diff --git a/usb/device/class/usb_device_video.h b/usb/device/class/usb_device_video.h new file mode 100644 index 0000000..efc9171 --- /dev/null +++ b/usb/device/class/usb_device_video.h @@ -0,0 +1,1009 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_VIDEO_H__ +#define __USB_DEVICE_VIDEO_H__ + +/*! + * @addtogroup usb_device_video_drv + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @name USB Video class codes + * @{ + */ + +/*! @brief Video device class code */ +#define USB_DEVICE_VIDEO_CC_VIDEO (0x0EU) + +/*! @brief Video device subclass code */ +#define USB_DEVICE_VIDEO_SC_UNDEFINED (0x00U) +#define USB_DEVICE_VIDEO_SC_VIDEOCONTROL (0x01U) +#define USB_DEVICE_VIDEO_SC_VIDEOSTREAMING (0x02U) +#define USB_DEVICE_VIDEO_SC_VIDEO_INTERFACE_COLLECTION (0x03U) + +/*! @brief Video device protocol code */ +#define USB_DEVICE_VIDEO_PC_PROTOCOL_UNDEFINED (0x00U) +#define USB_DEVICE_VIDEO_PC_PROTOCOL_15 (0x01U) + +/*! @brief Video device class-specific descriptor type */ +#define USB_DESCRIPTOR_TYPE_VIDEO_CS_UNDEFINED (0x20U) +#define USB_DESCRIPTOR_TYPE_VIDEO_CS_DEVICE (0x21U) +#define USB_DESCRIPTOR_TYPE_VIDEO_CS_CONFIGURATION (0x22U) +#define USB_DESCRIPTOR_TYPE_VIDEO_CS_STRING (0x23U) +#define USB_DESCRIPTOR_TYPE_VIDEO_CS_INTERFACE (0x24U) +#define USB_DESCRIPTOR_TYPE_VIDEO_CS_ENDPOINT (0x25U) + +/*! @brief Video device class-specific VC interface descriptor subtype */ +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VC_DESCRIPTOR_UNDEFINED (0x00U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VC_HEADER (0x01U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VC_INPUT_TERMINAL (0x02U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VC_OUTPUT_TERMINAL (0x03U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VC_SELECTOR_UNIT (0x04U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VC_PROCESSING_UNIT (0x05U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VC_EXTENSION_UNIT (0x06U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VC_ENCODING_UNIT (0x07U) + +/*! @brief Video device class-specific VS interface descriptor subtype */ +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_UNDEFINED (0x00U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_INPUT_HEADER (0x01U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_OUTPUT_HEADER (0x02U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_STILL_IMAGE_FRAME (0x03U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_FORMAT_UNCOMPRESSED (0x04U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_FRAME_UNCOMPRESSED (0x05U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_FORMAT_MJPEG (0x06U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_FRAME_MJPEG (0x07U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_FORMAT_MPEG2TS (0x0AU) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_FORMAT_DV (0x0CU) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_COLORFORMAT (0x0DU) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_FORMAT_FRAME_BASED (0x10U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_FRAME_FRAME_BASED (0x11U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_FORMAT_STREAM_BASED (0x12U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_FORMAT_H264 (0x13U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_FRAME_H264 (0x14U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_FORMAT_H264_SIMULCAST (0x15U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_FORMAT_VP8 (0x16U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_FRAME_VP8 (0x17U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_VS_FORMAT_VP8_SIMULCAST (0x18U) + +/*! @brief Video device class-specific VC endpoint descriptor subtype */ +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_EP_UNDEFINED (0x00U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_EP_GENERAL (0x01U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_EP_ENDPOINT (0x02U) +#define USB_DESCRIPTOR_SUBTYPE_VIDEO_EP_INTERRUPT (0x03U) + +/*! @brief Video device class-specific request code */ +#define USB_DEVICE_VIDEO_REQUEST_CODE_UNDEFINED (0x00U) +#define USB_DEVICE_VIDEO_REQUEST_CODE_SET_CUR (0x01U) +#define USB_DEVICE_VIDEO_REQUEST_CODE_SET_CUR_ALL (0x11U) +#define USB_DEVICE_VIDEO_REQUEST_CODE_GET_CUR (0x81U) +#define USB_DEVICE_VIDEO_REQUEST_CODE_GET_MIN (0x82U) +#define USB_DEVICE_VIDEO_REQUEST_CODE_GET_MAX (0x83U) +#define USB_DEVICE_VIDEO_REQUEST_CODE_GET_RES (0x84U) +#define USB_DEVICE_VIDEO_REQUEST_CODE_GET_LEN (0x85U) +#define USB_DEVICE_VIDEO_REQUEST_CODE_GET_INFO (0x86U) +#define USB_DEVICE_VIDEO_REQUEST_CODE_GET_DEF (0x87U) +#define USB_DEVICE_VIDEO_REQUEST_CODE_GET_CUR_ALL (0x91U) +#define USB_DEVICE_VIDEO_REQUEST_CODE_GET_MIN_ALL (0x92U) +#define USB_DEVICE_VIDEO_REQUEST_CODE_GET_MAX_ALL (0x93U) +#define USB_DEVICE_VIDEO_REQUEST_CODE_GET_RES_ALL (0x94U) +#define USB_DEVICE_VIDEO_REQUEST_CODE_GET_DEF_ALL (0x97U) + +/*! @brief Video device class-specific VideoControl interface control selector */ +#define USB_DEVICE_VIDEO_VC_CONTROL_UNDEFINED (0x00U) +#define USB_DEVICE_VIDEO_VC_VIDEO_POWER_MODE_CONTROL (0x01U) +#define USB_DEVICE_VIDEO_VC_REQUEST_ERROR_CODE_CONTROL (0x02U) + +/*! @brief Video device class-specific Terminal control selector */ +#define USB_DEVICE_VIDEO_TE_CONTROL_UNDEFINED (0x00U) + +/*! @brief Video device class-specific Selector Unit control selector */ +#define USB_DEVICE_VIDEO_SU_CONTROL_UNDEFINED (0x00U) +#define USB_DEVICE_VIDEO_SU_INPUT_SELECT_CONTROL (0x01U) + +/*! @brief Video device class-specific Camera Terminal control selector */ +#define USB_DEVICE_VIDEO_CT_CONTROL_UNDEFINED (0x00U) +#define USB_DEVICE_VIDEO_CT_SCANNING_MODE_CONTROL (0x01U) +#define USB_DEVICE_VIDEO_CT_AE_MODE_CONTROL (0x02U) +#define USB_DEVICE_VIDEO_CT_AE_PRIORITY_CONTROL (0x03U) +#define USB_DEVICE_VIDEO_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL (0x04U) +#define USB_DEVICE_VIDEO_CT_EXPOSURE_TIME_RELATIVE_CONTROL (0x05U) +#define USB_DEVICE_VIDEO_CT_FOCUS_ABSOLUTE_CONTROL (0x06U) +#define USB_DEVICE_VIDEO_CT_FOCUS_RELATIVE_CONTROL (0x07U) +#define USB_DEVICE_VIDEO_CT_FOCUS_AUTO_CONTROL (0x08U) +#define USB_DEVICE_VIDEO_CT_IRIS_ABSOLUTE_CONTROL (0x09U) +#define USB_DEVICE_VIDEO_CT_IRIS_RELATIVE_CONTROL (0x0AU) +#define USB_DEVICE_VIDEO_CT_ZOOM_ABSOLUTE_CONTROL (0x0BU) +#define USB_DEVICE_VIDEO_CT_ZOOM_RELATIVE_CONTROL (0x0CU) +#define USB_DEVICE_VIDEO_CT_PANTILT_ABSOLUTE_CONTROL (0x0DU) +#define USB_DEVICE_VIDEO_CT_PANTILT_RELATIVE_CONTROL (0x0EU) +#define USB_DEVICE_VIDEO_CT_ROLL_ABSOLUTE_CONTROL (0x0FU) +#define USB_DEVICE_VIDEO_CT_ROLL_RELATIVE_CONTROL (0x10U) +#define USB_DEVICE_VIDEO_CT_PRIVACY_CONTROL (0x11U) +#define USB_DEVICE_VIDEO_CT_FOCUS_SIMPLE_CONTROL (0x12U) +#define USB_DEVICE_VIDEO_CT_WINDOW_CONTROL (0x13U) +#define USB_DEVICE_VIDEO_CT_REGION_OF_INTEREST_CONTROL (0x14U) + +/*! @brief Video device class-specific Processing Unit control selector */ +#define USB_DEVICE_VIDEO_PU_CONTROL_UNDEFINED (0x00U) +#define USB_DEVICE_VIDEO_PU_BACKLIGHT_COMPENSATION_CONTROL (0x01U) +#define USB_DEVICE_VIDEO_PU_BRIGHTNESS_CONTROL (0x02U) +#define USB_DEVICE_VIDEO_PU_CONTRAST_CONTROL (0x03U) +#define USB_DEVICE_VIDEO_PU_GAIN_CONTROL (0x04U) +#define USB_DEVICE_VIDEO_PU_POWER_LINE_FREQUENCY_CONTROL (0x05U) +#define USB_DEVICE_VIDEO_PU_HUE_CONTROL (0x06U) +#define USB_DEVICE_VIDEO_PU_SATURATION_CONTROL (0x07U) +#define USB_DEVICE_VIDEO_PU_SHARPNESS_CONTROL (0x08U) +#define USB_DEVICE_VIDEO_PU_GAMMA_CONTROL (0x09U) +#define USB_DEVICE_VIDEO_PU_WHITE_BALANCE_TEMPERATURE_CONTROL (0x0AU) +#define USB_DEVICE_VIDEO_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL (0x0BU) +#define USB_DEVICE_VIDEO_PU_WHITE_BALANCE_COMPONENT_CONTROL (0x0CU) +#define USB_DEVICE_VIDEO_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL (0x0DU) +#define USB_DEVICE_VIDEO_PU_DIGITAL_MULTIPLIER_CONTROL (0x0EU) +#define USB_DEVICE_VIDEO_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL (0x0FU) +#define USB_DEVICE_VIDEO_PU_HUE_AUTO_CONTROL (0x10U) +#define USB_DEVICE_VIDEO_PU_ANALOG_VIDEO_STANDARD_CONTROL (0x11U) +#define USB_DEVICE_VIDEO_PU_ANALOG_LOCK_STATUS_CONTROL (0x12U) +#define USB_DEVICE_VIDEO_PU_CONTRAST_AUTO_CONTROL (0x13U) + +/*! @brief Video device class-specific Encoding Unit control selector */ +#define USB_DEVICE_VIDEO_EU_CONTROL_UNDEFINED (0x00U) +#define USB_DEVICE_VIDEO_EU_SELECT_LAYER_CONTROL (0x01U) +#define USB_DEVICE_VIDEO_EU_PROFILE_TOOLSET_CONTROL (0x02U) +#define USB_DEVICE_VIDEO_EU_VIDEO_RESOLUTION_CONTROL (0x03U) +#define USB_DEVICE_VIDEO_EU_MIN_FRAME_INTERVAL_CONTROL (0x04U) +#define USB_DEVICE_VIDEO_EU_SLICE_MODE_CONTROL (0x05U) +#define USB_DEVICE_VIDEO_EU_RATE_CONTROL_MODE_CONTROL (0x06U) +#define USB_DEVICE_VIDEO_EU_AVERAGE_BITRATE_CONTROL (0x07U) +#define USB_DEVICE_VIDEO_EU_CPB_SIZE_CONTROL (0x08U) +#define USB_DEVICE_VIDEO_EU_PEAK_BIT_RATE_CONTROL (0x09U) +#define USB_DEVICE_VIDEO_EU_QUANTIZATION_PARAMS_CONTROL (0x0AU) +#define USB_DEVICE_VIDEO_EU_SYNC_REF_FRAME_CONTROL (0x0BU) +#define USB_DEVICE_VIDEO_EU_LTR_BUFFER_ CONTROL(0x0CU) +#define USB_DEVICE_VIDEO_EU_LTR_PICTURE_CONTROL (0x0DU) +#define USB_DEVICE_VIDEO_EU_LTR_VALIDATION_CONTROL (0x0EU) +#define USB_DEVICE_VIDEO_EU_LEVEL_IDC_LIMIT_CONTROL (0x0FU) +#define USB_DEVICE_VIDEO_EU_SEI_PAYLOADTYPE_CONTROL (0x10U) +#define USB_DEVICE_VIDEO_EU_QP_RANGE_CONTROL (0x11U) +#define USB_DEVICE_VIDEO_EU_PRIORITY_CONTROL (0x12U) +#define USB_DEVICE_VIDEO_EU_START_OR_STOP_LAYER_CONTROL (0x13U) +#define USB_DEVICE_VIDEO_EU_ERROR_RESILIENCY_CONTROL (0x14U) + +/*! @brief Video device class-specific Extension Unit control selector */ +#define USB_DEVICE_VIDEO_XU_CONTROL_UNDEFINED (0x00U) + +/*! @brief Video device class-specific VideoStreaming Interface control selector */ +#define USB_DEVICE_VIDEO_VS_CONTROL_UNDEFINED (0x00U) +#define USB_DEVICE_VIDEO_VS_PROBE_CONTROL (0x01U) +#define USB_DEVICE_VIDEO_VS_COMMIT_CONTROL (0x02U) +#define USB_DEVICE_VIDEO_VS_STILL_PROBE_CONTROL (0x03U) +#define USB_DEVICE_VIDEO_VS_STILL_COMMIT_CONTROL (0x04U) +#define USB_DEVICE_VIDEO_VS_STILL_IMAGE_TRIGGER_CONTROL (0x05U) +#define USB_DEVICE_VIDEO_VS_STREAM_ERROR_CODE_CONTROL (0x06U) +#define USB_DEVICE_VIDEO_VS_GENERATE_KEY_FRAME_CONTROL (0x07U) +#define USB_DEVICE_VIDEO_VS_UPDATE_FRAME_SEGMENT_CONTROL (0x08U) +#define USB_DEVICE_VIDEO_VS_SYNCH_DELAY_CONTROL (0x09U) + +/*! @}*/ + +/*! + * @name USB Video class terminal types + * @{ + */ + +/*! @brief Video device USB terminal type */ +#define USB_DEVICE_VIDEO_TT_VENDOR_SPECIFIC (0x0100U) +#define USB_DEVICE_VIDEO_TT_STREAMING (0x0101U) + +/*! @brief Video device input terminal type */ +#define USB_DEVICE_VIDEO_ITT_VENDOR_SPECIFIC (0x0200U) +#define USB_DEVICE_VIDEO_ITT_CAMERA (0x0201U) +#define USB_DEVICE_VIDEO_ITT_MEDIA_TRANSPORT_INPUT (0x0202U) + +/*! @brief Video device output terminal type */ +#define USB_DEVICE_VIDEO_OTT_VENDOR_SPECIFIC (0x0300U) +#define USB_DEVICE_VIDEO_OTT_DISPLAY (0x0301U) +#define USB_DEVICE_VIDEO_OTT_MEDIA_TRANSPORT_OUTPUT (0x0302U) + +/*! @brief Video device external terminal type */ +#define USB_DEVICE_VIDEO_ET_VENDOR_SPECIFIC (0x0400U) +#define USB_DEVICE_VIDEO_ET_COMPOSITE_CONNECTOR (0x0401U) +#define USB_DEVICE_VIDEO_ET_SVIDEO_CONNECTOR (0x0402U) +#define USB_DEVICE_VIDEO_ET_COMPONENT_CONNECTOR (0x0403U) + +/*! @}*/ + +/*! + * @name USB Video class setup request types + * @{ + */ + +/*! @brief Video device class setup request set type */ +#define USB_DEVICE_VIDEO_SET_REQUEST_INTERFACE (0x21U) +#define USB_DEVICE_VIDEO_SET_REQUEST_ENDPOINT (0x22U) + +/*! @brief Video device class setup request get type */ +#define USB_DEVICE_VIDEO_GET_REQUEST_INTERFACE (0xA1U) +#define USB_DEVICE_VIDEO_GET_REQUEST_ENDPOINT (0xA2U) + +/*! @}*/ + +/*! @brief Video device still image trigger control */ +#define USB_DEVICE_VIDEO_STILL_IMAGE_TRIGGER_NORMAL_OPERATION (0x00U) +#define USB_DEVICE_VIDEO_STILL_IMAGE_TRIGGER_TRANSMIT_STILL_IMAGE (0x01U) +#define USB_DEVICE_VIDEO_STILL_IMAGE_TRIGGER_TRANSMIT_STILL_IMAGE_VS_DEDICATED_BULK_PIPE (0x02U) +#define USB_DEVICE_VIDEO_STILL_IMAGE_TRIGGER_ABORT_STILL_IMAGE_TRANSMISSION (0x03U) + +/*! + * @name USB Video device class-specific request commands + * @{ + */ + +/*! @brief Video device class-specific request GET CUR COMMAND */ +#define USB_DEVICE_VIDEO_GET_CUR_VC_POWER_MODE_CONTROL (0x8101U) +#define USB_DEVICE_VIDEO_GET_CUR_VC_ERROR_CODE_CONTROL (0x8102U) + +#define USB_DEVICE_VIDEO_GET_CUR_PU_BACKLIGHT_COMPENSATION_CONTROL (0x8121U) +#define USB_DEVICE_VIDEO_GET_CUR_PU_BRIGHTNESS_CONTROL (0x8122U) +#define USB_DEVICE_VIDEO_GET_CUR_PU_CONTRACT_CONTROL (0x8123U) +#define USB_DEVICE_VIDEO_GET_CUR_PU_GAIN_CONTROL (0x8124U) +#define USB_DEVICE_VIDEO_GET_CUR_PU_POWER_LINE_FREQUENCY_CONTROL (0x8125U) +#define USB_DEVICE_VIDEO_GET_CUR_PU_HUE_CONTROL (0x8126U) +#define USB_DEVICE_VIDEO_GET_CUR_PU_SATURATION_CONTROL (0x8127U) +#define USB_DEVICE_VIDEO_GET_CUR_PU_SHARRNESS_CONTROL (0x8128U) +#define USB_DEVICE_VIDEO_GET_CUR_PU_GAMMA_CONTROL (0x8129U) +#define USB_DEVICE_VIDEO_GET_CUR_PU_WHITE_BALANCE_TEMPERATURE_CONTROL (0x812AU) +#define USB_DEVICE_VIDEO_GET_CUR_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL (0x812BU) +#define USB_DEVICE_VIDEO_GET_CUR_PU_WHITE_BALANCE_COMPONENT_CONTROL (0x812CU) +#define USB_DEVICE_VIDEO_GET_CUR_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL (0x812DU) +#define USB_DEVICE_VIDEO_GET_CUR_PU_DIGITAL_MULTIPLIER_CONTROL (0x812EU) +#define USB_DEVICE_VIDEO_GET_CUR_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL (0x812FU) +#define USB_DEVICE_VIDEO_GET_CUR_PU_HUE_AUTO_CONTROL (0x8130U) +#define USB_DEVICE_VIDEO_GET_CUR_PU_ANALOG_VIDEO_STANDARD_CONTROL (0x8131U) +#define USB_DEVICE_VIDEO_GET_CUR_PU_ANALOG_LOCK_STATUS_CONTROL (0x8132U) +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_GET_CUR_PU_CONTRAST_AUTO_CONTROL (0x8133U) +#endif + +#define USB_DEVICE_VIDEO_GET_CUR_CT_SCANNING_MODE_CONTROL (0x8141U) +#define USB_DEVICE_VIDEO_GET_CUR_CT_AE_MODE_CONTROL (0x8142U) +#define USB_DEVICE_VIDEO_GET_CUR_CT_AE_PRIORITY_CONTROL (0x8143U) +#define USB_DEVICE_VIDEO_GET_CUR_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL (0x8144U) +#define USB_DEVICE_VIDEO_GET_CUR_CT_EXPOSURE_TIME_RELATIVE_CONTROL (0x8145U) +#define USB_DEVICE_VIDEO_GET_CUR_CT_FOCUS_ABSOLUTE_CONTROL (0x8146U) +#define USB_DEVICE_VIDEO_GET_CUR_CT_FOCUS_RELATIVE_CONTROL (0x8147U) +#define USB_DEVICE_VIDEO_GET_CUR_CT_FOCUS_AUTO_CONTROL (0x8148U) +#define USB_DEVICE_VIDEO_GET_CUR_CT_IRIS_ABSOLUTE_CONTROL (0x8149U) +#define USB_DEVICE_VIDEO_GET_CUR_CT_IRIS_RELATIVE_CONTROL (0x814AU) +#define USB_DEVICE_VIDEO_GET_CUR_CT_ZOOM_ABSOLUTE_CONTROL (0x814BU) +#define USB_DEVICE_VIDEO_GET_CUR_CT_ZOOM_RELATIVE_CONTROL (0x814CU) +#define USB_DEVICE_VIDEO_GET_CUR_CT_PANTILT_ABSOLUTE_CONTROL (0x814DU) +#define USB_DEVICE_VIDEO_GET_CUR_CT_PANTILT_RELATIVE_CONTROL (0x814EU) +#define USB_DEVICE_VIDEO_GET_CUR_CT_ROLL_ABSOLUTE_CONTROL (0x814FU) +#define USB_DEVICE_VIDEO_GET_CUR_CT_ROLL_RELATIVE_CONTROL (0x8150U) +#define USB_DEVICE_VIDEO_GET_CUR_CT_PRIVACY_CONTROL (0x8151U) +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_GET_CUR_CT_FOCUS_SIMPLE_CONTROL (0x8152U) +#define USB_DEVICE_VIDEO_GET_CUR_CT_DIGITAL_WINDOW_CONTROL (0x8153U) +#define USB_DEVICE_VIDEO_GET_CUR_CT_REGION_OF_INTEREST_CONTROL (0x8154U) +#endif + +#define USB_DEVICE_VIDEO_GET_CUR_VS_PROBE_CONTROL (0x8161U) +#define USB_DEVICE_VIDEO_GET_CUR_VS_COMMIT_CONTROL (0x8162U) +#define USB_DEVICE_VIDEO_GET_CUR_VS_STILL_PROBE_CONTROL (0x8163U) +#define USB_DEVICE_VIDEO_GET_CUR_VS_STILL_COMMIT_CONTROL (0x8164U) +#define USB_DEVICE_VIDEO_GET_CUR_VS_STILL_IMAGE_TRIGGER_CONTROL (0x8165U) +#define USB_DEVICE_VIDEO_GET_CUR_VS_STREAM_ERROR_CODE_CONTROL (0x8166U) +#define USB_DEVICE_VIDEO_GET_CUR_VS_GENERATE_KEY_FRAME_CONTROL (0x8167U) +#define USB_DEVICE_VIDEO_GET_CUR_VS_UPDATE_FRAME_SEGMENT_CONTROL (0x8168U) +#define USB_DEVICE_VIDEO_GET_CUR_VS_SYNCH_DELAY_CONTROL (0x8169U) + +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_GET_CUR_EU_SELECT_LAYER_CONTROL (0x8181U) +#define USB_DEVICE_VIDEO_GET_CUR_EU_PROFILE_TOOLSET_CONTROL (0x8182U) +#define USB_DEVICE_VIDEO_GET_CUR_EU_VIDEO_RESOLUTION_CONTROL (0x8183U) +#define USB_DEVICE_VIDEO_GET_CUR_EU_MIN_FRAME_INTERVAL_CONTROL (0x8184U) +#define USB_DEVICE_VIDEO_GET_CUR_EU_SLICE_MODE_CONTROL (0x8185U) +#define USB_DEVICE_VIDEO_GET_CUR_EU_RATE_CONTROL_MODE_CONTROL (0x8186U) +#define USB_DEVICE_VIDEO_GET_CUR_EU_AVERAGE_BITRATE_CONTROL (0x8187U) +#define USB_DEVICE_VIDEO_GET_CUR_EU_CPB_SIZE_CONTROL (0x8188U) +#define USB_DEVICE_VIDEO_GET_CUR_EU_PEAK_BIT_RATE_CONTROL (0x8189U) +#define USB_DEVICE_VIDEO_GET_CUR_EU_QUANTIZATION_PARAMS_CONTROL (0x818AU) +#define USB_DEVICE_VIDEO_GET_CUR_EU_SYNC_REF_FRAME_CONTROL (0x818BU) +#define USB_DEVICE_VIDEO_GET_CUR_EU_LTR_BUFFER_CONTROL (0x818CU) +#define USB_DEVICE_VIDEO_GET_CUR_EU_LTR_PICTURE_CONTROL (0x818DU) +#define USB_DEVICE_VIDEO_GET_CUR_EU_LTR_VALIDATION_CONTROL (0x818EU) +#define USB_DEVICE_VIDEO_GET_CUR_EU_LEVEL_IDC_LIMIT_CONTROL (0x818FU) +#define USB_DEVICE_VIDEO_GET_CUR_EU_SEI_PAYLOADTYPE_CONTROL (0x8190U) +#define USB_DEVICE_VIDEO_GET_CUR_EU_QP_RANGE_CONTROL (0x8191U) +#define USB_DEVICE_VIDEO_GET_CUR_EU_PRIORITY_CONTROL (0x8192U) +#define USB_DEVICE_VIDEO_GET_CUR_EU_START_OR_STOP_LAYER_CONTROL (0x8193U) +#define USB_DEVICE_VIDEO_GET_CUR_EU_ERROR_RESILIENCY_CONTROL (0x8194U) +#endif + +/*! @brief Video device class-specific request GET MIN COMMAND */ +#define USB_DEVICE_VIDEO_GET_MIN_PU_BACKLIGHT_COMPENSATION_CONTROL (0x8221U) +#define USB_DEVICE_VIDEO_GET_MIN_PU_BRIGHTNESS_CONTROL (0x8222U) +#define USB_DEVICE_VIDEO_GET_MIN_PU_CONTRACT_CONTROL (0x8223U) +#define USB_DEVICE_VIDEO_GET_MIN_PU_GAIN_CONTROL (0x8224U) +#define USB_DEVICE_VIDEO_GET_MIN_PU_HUE_CONTROL (0x8226U) +#define USB_DEVICE_VIDEO_GET_MIN_PU_SATURATION_CONTROL (0x8227U) +#define USB_DEVICE_VIDEO_GET_MIN_PU_SHARRNESS_CONTROL (0x8228U) +#define USB_DEVICE_VIDEO_GET_MIN_PU_GAMMA_CONTROL (0x8229U) +#define USB_DEVICE_VIDEO_GET_MIN_PU_WHITE_BALANCE_TEMPERATURE_CONTROL (0x822AU) +#define USB_DEVICE_VIDEO_GET_MIN_PU_WHITE_BALANCE_COMPONENT_CONTROL (0x822CU) +#define USB_DEVICE_VIDEO_GET_MIN_PU_DIGITAL_MULTIPLIER_CONTROL (0x822EU) +#define USB_DEVICE_VIDEO_GET_MIN_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL (0x822FU) + +#define USB_DEVICE_VIDEO_GET_MIN_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL (0x8244U) +#define USB_DEVICE_VIDEO_GET_MIN_CT_FOCUS_ABSOLUTE_CONTROL (0x8246U) +#define USB_DEVICE_VIDEO_GET_MIN_CT_FOCUS_RELATIVE_CONTROL (0x8247U) +#define USB_DEVICE_VIDEO_GET_MIN_CT_IRIS_ABSOLUTE_CONTROL (0x8249U) +#define USB_DEVICE_VIDEO_GET_MIN_CT_ZOOM_ABSOLUTE_CONTROL (0x824BU) +#define USB_DEVICE_VIDEO_GET_MIN_CT_ZOOM_RELATIVE_CONTROL (0x824CU) +#define USB_DEVICE_VIDEO_GET_MIN_CT_PANTILT_ABSOLUTE_CONTROL (0x824DU) +#define USB_DEVICE_VIDEO_GET_MIN_CT_PANTILT_RELATIVE_CONTROL (0x824EU) +#define USB_DEVICE_VIDEO_GET_MIN_CT_ROLL_ABSOLUTE_CONTROL (0x824FU) +#define USB_DEVICE_VIDEO_GET_MIN_CT_ROLL_RELATIVE_CONTROL (0x8250U) +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_GET_MIN_CT_DIGITAL_WINDOW_CONTROL (0x8251U) +#define USB_DEVICE_VIDEO_GET_MIN_CT_REGION_OF_INTEREST_CONTROL (0x8252U) +#endif + +#define USB_DEVICE_VIDEO_GET_MIN_VS_PROBE_CONTROL (0x8261U) +#define USB_DEVICE_VIDEO_GET_MIN_VS_STILL_PROBE_CONTROL (0x8263U) +#define USB_DEVICE_VIDEO_GET_MIN_VS_UPDATE_FRAME_SEGMENT_CONTROL (0x8268U) +#define USB_DEVICE_VIDEO_GET_MIN_VS_SYNCH_DELAY_CONTROL (0x8269U) + +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_GET_MIN_EU_VIDEO_RESOLUTION_CONTROL (0x8283U) +#define USB_DEVICE_VIDEO_GET_MIN_EU_MIN_FRAME_INTERVAL_CONTROL (0x8284U) +#define USB_DEVICE_VIDEO_GET_MIN_EU_SLICE_MODE_CONTROL (0x8285U) +#define USB_DEVICE_VIDEO_GET_MIN_EU_AVERAGE_BITRATE_CONTROL (0x8287U) +#define USB_DEVICE_VIDEO_GET_MIN_EU_CPB_SIZE_CONTROL (0x8288U) +#define USB_DEVICE_VIDEO_GET_MIN_EU_PEAK_BIT_RATE_CONTROL (0x8289U) +#define USB_DEVICE_VIDEO_GET_MIN_EU_QUANTIZATION_PARAMS_CONTROL (0x828AU) +#define USB_DEVICE_VIDEO_GET_MIN_EU_SYNC_REF_FRAME_CONTROL (0x828BU) +#define USB_DEVICE_VIDEO_GET_MIN_EU_LEVEL_IDC_LIMIT_CONTROL (0x828FU) +#define USB_DEVICE_VIDEO_GET_MIN_EU_SEI_PAYLOADTYPE_CONTROL (0x8290U) +#define USB_DEVICE_VIDEO_GET_MIN_EU_QP_RANGE_CONTROL (0x8291U) +#endif + +/*! @brief Video device class-specific request GET MAX COMMAND */ +#define USB_DEVICE_VIDEO_GET_MAX_PU_BACKLIGHT_COMPENSATION_CONTROL (0x8321U) +#define USB_DEVICE_VIDEO_GET_MAX_PU_BRIGHTNESS_CONTROL (0x8322U) +#define USB_DEVICE_VIDEO_GET_MAX_PU_CONTRACT_CONTROL (0x8323U) +#define USB_DEVICE_VIDEO_GET_MAX_PU_GAIN_CONTROL (0x8324U) +#define USB_DEVICE_VIDEO_GET_MAX_PU_HUE_CONTROL (0x8326U) +#define USB_DEVICE_VIDEO_GET_MAX_PU_SATURATION_CONTROL (0x8327U) +#define USB_DEVICE_VIDEO_GET_MAX_PU_SHARRNESS_CONTROL (0x8328U) +#define USB_DEVICE_VIDEO_GET_MAX_PU_GAMMA_CONTROL (0x8329U) +#define USB_DEVICE_VIDEO_GET_MAX_PU_WHITE_BALANCE_TEMPERATURE_CONTROL (0x832AU) +#define USB_DEVICE_VIDEO_GET_MAX_PU_WHITE_BALANCE_COMPONENT_CONTROL (0x832CU) +#define USB_DEVICE_VIDEO_GET_MAX_PU_DIGITAL_MULTIPLIER_CONTROL (0x832EU) +#define USB_DEVICE_VIDEO_GET_MAX_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL (0x832FU) + +#define USB_DEVICE_VIDEO_GET_MAX_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL (0x8344U) +#define USB_DEVICE_VIDEO_GET_MAX_CT_FOCUS_ABSOLUTE_CONTROL (0x8346U) +#define USB_DEVICE_VIDEO_GET_MAX_CT_FOCUS_RELATIVE_CONTROL (0x8347U) +#define USB_DEVICE_VIDEO_GET_MAX_CT_IRIS_ABSOLUTE_CONTROL (0x8349U) +#define USB_DEVICE_VIDEO_GET_MAX_CT_ZOOM_ABSOLUTE_CONTROL (0x834BU) +#define USB_DEVICE_VIDEO_GET_MAX_CT_ZOOM_RELATIVE_CONTROL (0x834CU) +#define USB_DEVICE_VIDEO_GET_MAX_CT_PANTILT_ABSOLUTE_CONTROL (0x834DU) +#define USB_DEVICE_VIDEO_GET_MAX_CT_PANTILT_RELATIVE_CONTROL (0x834EU) +#define USB_DEVICE_VIDEO_GET_MAX_CT_ROLL_ABSOLUTE_CONTROL (0x834FU) +#define USB_DEVICE_VIDEO_GET_MAX_CT_ROLL_RELATIVE_CONTROL (0x8350U) +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_GET_MAX_CT_DIGITAL_WINDOW_CONTROL (0x8351U) +#define USB_DEVICE_VIDEO_GET_MAX_CT_REGION_OF_INTEREST_CONTROL (0x8352U) +#endif + +#define USB_DEVICE_VIDEO_GET_MAX_VS_PROBE_CONTROL (0x8361U) +#define USB_DEVICE_VIDEO_GET_MAX_VS_STILL_PROBE_CONTROL (0x8363U) +#define USB_DEVICE_VIDEO_GET_MAX_VS_UPDATE_FRAME_SEGMENT_CONTROL (0x8368U) +#define USB_DEVICE_VIDEO_GET_MAX_VS_SYNCH_DELAY_CONTROL (0x8369U) + +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_GET_MAX_EU_VIDEO_RESOLUTION_CONTROL (0x8383U) +#define USB_DEVICE_VIDEO_GET_MAX_EU_MIN_FRAME_INTERVAL_CONTROL (0x8384U) +#define USB_DEVICE_VIDEO_GET_MAX_EU_SLICE_MODE_CONTROL (0x8385U) +#define USB_DEVICE_VIDEO_GET_MAX_EU_AVERAGE_BITRATE_CONTROL (0x8387U) +#define USB_DEVICE_VIDEO_GET_MAX_EU_CPB_SIZE_CONTROL (0x8388U) +#define USB_DEVICE_VIDEO_GET_MAX_EU_PEAK_BIT_RATE_CONTROL (0x8389U) +#define USB_DEVICE_VIDEO_GET_MAX_EU_QUANTIZATION_PARAMS_CONTROL (0x838AU) +#define USB_DEVICE_VIDEO_GET_MAX_EU_SYNC_REF_FRAME_CONTROL (0x838BU) +#define USB_DEVICE_VIDEO_GET_MAX_EU_LTR_BUFFER_CONTROL (0x838CU) +#define USB_DEVICE_VIDEO_GET_MAX_EU_LEVEL_IDC_LIMIT_CONTROL (0x838FU) +#define USB_DEVICE_VIDEO_GET_MAX_EU_SEI_PAYLOADTYPE_CONTROL (0x8390U) +#define USB_DEVICE_VIDEO_GET_MAX_EU_QP_RANGE_CONTROL (0x8391U) +#endif + +/*! @brief Video device class-specific request GET RES COMMAND */ +#define USB_DEVICE_VIDEO_GET_RES_PU_BACKLIGHT_COMPENSATION_CONTROL (0x8421U) +#define USB_DEVICE_VIDEO_GET_RES_PU_BRIGHTNESS_CONTROL (0x8422U) +#define USB_DEVICE_VIDEO_GET_RES_PU_CONTRACT_CONTROL (0x8423U) +#define USB_DEVICE_VIDEO_GET_RES_PU_GAIN_CONTROL (0x8424U) +#define USB_DEVICE_VIDEO_GET_RES_PU_HUE_CONTROL (0x8426U) +#define USB_DEVICE_VIDEO_GET_RES_PU_SATURATION_CONTROL (0x8427U) +#define USB_DEVICE_VIDEO_GET_RES_PU_SHARRNESS_CONTROL (0x8428U) +#define USB_DEVICE_VIDEO_GET_RES_PU_GAMMA_CONTROL (0x8429U) +#define USB_DEVICE_VIDEO_GET_RES_PU_WHITE_BALANCE_TEMPERATURE_CONTROL (0x842AU) +#define USB_DEVICE_VIDEO_GET_RES_PU_WHITE_BALANCE_COMPONENT_CONTROL (0x842CU) +#define USB_DEVICE_VIDEO_GET_RES_PU_DIGITAL_MULTIPLIER_CONTROL (0x842EU) +#define USB_DEVICE_VIDEO_GET_RES_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL (0x842FU) + +#define USB_DEVICE_VIDEO_GET_RES_CT_AE_MODE_CONTROL (0x8442U) +#define USB_DEVICE_VIDEO_GET_RES_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL (0x8444U) +#define USB_DEVICE_VIDEO_GET_RES_CT_FOCUS_ABSOLUTE_CONTROL (0x8446U) +#define USB_DEVICE_VIDEO_GET_RES_CT_FOCUS_RELATIVE_CONTROL (0x8447U) +#define USB_DEVICE_VIDEO_GET_RES_CT_IRIS_ABSOLUTE_CONTROL (0x8449U) +#define USB_DEVICE_VIDEO_GET_RES_CT_ZOOM_ABSOLUTE_CONTROL (0x844BU) +#define USB_DEVICE_VIDEO_GET_RES_CT_ZOOM_RELATIVE_CONTROL (0x844CU) +#define USB_DEVICE_VIDEO_GET_RES_CT_PANTILT_ABSOLUTE_CONTROL (0x844DU) +#define USB_DEVICE_VIDEO_GET_RES_CT_PANTILT_RELATIVE_CONTROL (0x844EU) +#define USB_DEVICE_VIDEO_GET_RES_CT_ROLL_ABSOLUTE_CONTROL (0x844FU) +#define USB_DEVICE_VIDEO_GET_RES_CT_ROLL_RELATIVE_CONTROL (0x8450U) + +#define USB_DEVICE_VIDEO_GET_RES_VS_PROBE_CONTROL (0x8461U) +#define USB_DEVICE_VIDEO_GET_RES_VS_STILL_PROBE_CONTROL (0x8463U) +#define USB_DEVICE_VIDEO_GET_RES_VS_UPDATE_FRAME_SEGMENT_CONTROL (0x8468U) +#define USB_DEVICE_VIDEO_GET_RES_VS_SYNCH_DELAY_CONTROL (0x8469U) + +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_GET_RES_EU_AVERAGE_BITRATE_CONTROL (0x8487U) +#define USB_DEVICE_VIDEO_GET_RES_EU_CPB_SIZE_CONTROL (0x8488U) +#define USB_DEVICE_VIDEO_GET_RES_EU_PEAK_BIT_RATE_CONTROL (0x8489U) +#define USB_DEVICE_VIDEO_GET_RES_EU_QUANTIZATION_PARAMS_CONTROL (0x848AU) +#define USB_DEVICE_VIDEO_GET_RES_EU_ERROR_RESILIENCY_CONTROL (0x8494U) +#endif + +/*! @brief Video device class-specific request GET LEN COMMAND */ + +#define USB_DEVICE_VIDEO_GET_LEN_VS_PROBE_CONTROL (0x8561U) +#define USB_DEVICE_VIDEO_GET_LEN_VS_COMMIT_CONTROL (0x8562U) +#define USB_DEVICE_VIDEO_GET_LEN_VS_STILL_PROBE_CONTROL (0x8563U) +#define USB_DEVICE_VIDEO_GET_LEN_VS_STILL_COMMIT_CONTROL (0x8564U) + +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_GET_LEN_EU_SELECT_LAYER_CONTROL (0x8581U) +#define USB_DEVICE_VIDEO_GET_LEN_EU_PROFILE_TOOLSET_CONTROL (0x8582U) +#define USB_DEVICE_VIDEO_GET_LEN_EU_VIDEO_RESOLUTION_CONTROL (0x8583U) +#define USB_DEVICE_VIDEO_GET_LEN_EU_MIN_FRAME_INTERVAL_CONTROL (0x8584U) +#define USB_DEVICE_VIDEO_GET_LEN_EU_SLICE_MODE_CONTROL (0x8585U) +#define USB_DEVICE_VIDEO_GET_LEN_EU_RATE_CONTROL_MODE_CONTROL (0x8586U) +#define USB_DEVICE_VIDEO_GET_LEN_EU_AVERAGE_BITRATE_CONTROL (0x8587U) +#define USB_DEVICE_VIDEO_GET_LEN_EU_CPB_SIZE_CONTROL (0x8588U) +#define USB_DEVICE_VIDEO_GET_LEN_EU_PEAK_BIT_RATE_CONTROL (0x8589U) +#define USB_DEVICE_VIDEO_GET_LEN_EU_QUANTIZATION_PARAMS_CONTROL (0x858AU) +#define USB_DEVICE_VIDEO_GET_LEN_EU_SYNC_REF_FRAME_CONTROL (0x858BU) +#define USB_DEVICE_VIDEO_GET_LEN_EU_LTR_BUFFER_CONTROL (0x858CU) +#define USB_DEVICE_VIDEO_GET_LEN_EU_LTR_PICTURE_CONTROL (0x858DU) +#define USB_DEVICE_VIDEO_GET_LEN_EU_LTR_VALIDATION_CONTROL (0x858EU) +#define USB_DEVICE_VIDEO_GET_LEN_EU_QP_RANGE_CONTROL (0x8591U) +#define USB_DEVICE_VIDEO_GET_LEN_EU_PRIORITY_CONTROL (0x8592U) +#define USB_DEVICE_VIDEO_GET_LEN_EU_START_OR_STOP_LAYER_CONTROL (0x8593U) +#endif + +/*! @brief Video device class-specific request GET INFO COMMAND */ +#define USB_DEVICE_VIDEO_GET_INFO_VC_POWER_MODE_CONTROL (0x8601U) +#define USB_DEVICE_VIDEO_GET_INFO_VC_ERROR_CODE_CONTROL (0x8602U) + +#define USB_DEVICE_VIDEO_GET_INFO_PU_BACKLIGHT_COMPENSATION_CONTROL (0x8621U) +#define USB_DEVICE_VIDEO_GET_INFO_PU_BRIGHTNESS_CONTROL (0x8622U) +#define USB_DEVICE_VIDEO_GET_INFO_PU_CONTRACT_CONTROL (0x8623U) +#define USB_DEVICE_VIDEO_GET_INFO_PU_GAIN_CONTROL (0x8624U) +#define USB_DEVICE_VIDEO_GET_INFO_PU_POWER_LINE_FREQUENCY_CONTROL (0x8625U) +#define USB_DEVICE_VIDEO_GET_INFO_PU_HUE_CONTROL (0x8626U) +#define USB_DEVICE_VIDEO_GET_INFO_PU_SATURATION_CONTROL (0x8627U) +#define USB_DEVICE_VIDEO_GET_INFO_PU_SHARRNESS_CONTROL (0x8628U) +#define USB_DEVICE_VIDEO_GET_INFO_PU_GAMMA_CONTROL (0x8629U) +#define USB_DEVICE_VIDEO_GET_INFO_PU_WHITE_BALANCE_TEMPERATURE_CONTROL (0x862AU) +#define USB_DEVICE_VIDEO_GET_INFO_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL (0x862BU) +#define USB_DEVICE_VIDEO_GET_INFO_PU_WHITE_BALANCE_COMPONENT_CONTROL (0x862CU) +#define USB_DEVICE_VIDEO_GET_INFO_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL (0x862DU) +#define USB_DEVICE_VIDEO_GET_INFO_PU_DIGITAL_MULTIPLIER_CONTROL (0x862EU) +#define USB_DEVICE_VIDEO_GET_INFO_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL (0x862FU) +#define USB_DEVICE_VIDEO_GET_INFO_PU_HUE_AUTO_CONTROL (0x8630U) +#define USB_DEVICE_VIDEO_GET_INFO_PU_ANALOG_VIDEO_STANDARD_CONTROL (0x8631U) +#define USB_DEVICE_VIDEO_GET_INFO_PU_ANALOG_LOCK_STATUS_CONTROL (0x8632U) +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_GET_INFO_PU_CONTRAST_AUTO_CONTROL (0x8633U) +#endif + +#define USB_DEVICE_VIDEO_GET_INFO_CT_SCANNING_MODE_CONTROL (0x8641U) +#define USB_DEVICE_VIDEO_GET_INFO_CT_AE_MODE_CONTROL (0x8642U) +#define USB_DEVICE_VIDEO_GET_INFO_CT_AE_PRIORITY_CONTROL (0x8643U) +#define USB_DEVICE_VIDEO_GET_INFO_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL (0x8644U) +#define USB_DEVICE_VIDEO_GET_INFO_CT_EXPOSURE_TIME_RELATIVE_CONTROL (0x8645U) +#define USB_DEVICE_VIDEO_GET_INFO_CT_FOCUS_ABSOLUTE_CONTROL (0x8646U) +#define USB_DEVICE_VIDEO_GET_INFO_CT_FOCUS_RELATIVE_CONTROL (0x8647U) +#define USB_DEVICE_VIDEO_GET_INFO_CT_FOCUS_AUTO_CONTROL (0x8648U) +#define USB_DEVICE_VIDEO_GET_INFO_CT_IRIS_ABSOLUTE_CONTROL (0x8649U) +#define USB_DEVICE_VIDEO_GET_INFO_CT_IRIS_RELATIVE_CONTROL (0x864AU) +#define USB_DEVICE_VIDEO_GET_INFO_CT_ZOOM_ABSOLUTE_CONTROL (0x864BU) +#define USB_DEVICE_VIDEO_GET_INFO_CT_ZOOM_RELATIVE_CONTROL (0x864CU) +#define USB_DEVICE_VIDEO_GET_INFO_CT_PANTILT_ABSOLUTE_CONTROL (0x864DU) +#define USB_DEVICE_VIDEO_GET_INFO_CT_PANTILT_RELATIVE_CONTROL (0x864EU) +#define USB_DEVICE_VIDEO_GET_INFO_CT_ROLL_ABSOLUTE_CONTROL (0x864FU) +#define USB_DEVICE_VIDEO_GET_INFO_CT_ROLL_RELATIVE_CONTROL (0x8650U) +#define USB_DEVICE_VIDEO_GET_INFO_CT_PRIVACY_CONTROL (0x8651U) +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_GET_INFO_CT_FOCUS_SIMPLE_CONTROL (0x8652U) +#endif + +#define USB_DEVICE_VIDEO_GET_INFO_VS_PROBE_CONTROL (0x8661U) +#define USB_DEVICE_VIDEO_GET_INFO_VS_COMMIT_CONTROL (0x8662U) +#define USB_DEVICE_VIDEO_GET_INFO_VS_STILL_PROBE_CONTROL (0x8663U) +#define USB_DEVICE_VIDEO_GET_INFO_VS_STILL_COMMIT_CONTROL (0x8664U) +#define USB_DEVICE_VIDEO_GET_INFO_VS_STILL_IMAGE_TRIGGER_CONTROL (0x8665U) +#define USB_DEVICE_VIDEO_GET_INFO_VS_STREAM_ERROR_CODE_CONTROL (0x8666U) +#define USB_DEVICE_VIDEO_GET_INFO_VS_GENERATE_KEY_FRAME_CONTROL (0x8667U) +#define USB_DEVICE_VIDEO_GET_INFO_VS_UPDATE_FRAME_SEGMENT_CONTROL (0x8668U) +#define USB_DEVICE_VIDEO_GET_INFO_VS_SYNCH_DELAY_CONTROL (0x8669U) + +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_GET_INFO_EU_SELECT_LAYER_CONTROL (0x8681U) +#define USB_DEVICE_VIDEO_GET_INFO_EU_PROFILE_TOOLSET_CONTROL (0x8682U) +#define USB_DEVICE_VIDEO_GET_INFO_EU_VIDEO_RESOLUTION_CONTROL (0x8683U) +#define USB_DEVICE_VIDEO_GET_INFO_EU_MIN_FRAME_INTERVAL_CONTROL (0x8684U) +#define USB_DEVICE_VIDEO_GET_INFO_EU_SLICE_MODE_CONTROL (0x8685U) +#define USB_DEVICE_VIDEO_GET_INFO_EU_RATE_CONTROL_MODE_CONTROL (0x8686U) +#define USB_DEVICE_VIDEO_GET_INFO_EU_AVERAGE_BITRATE_CONTROL (0x8687U) +#define USB_DEVICE_VIDEO_GET_INFO_EU_CPB_SIZE_CONTROL (0x8688U) +#define USB_DEVICE_VIDEO_GET_INFO_EU_PEAK_BIT_RATE_CONTROL (0x8689U) +#define USB_DEVICE_VIDEO_GET_INFO_EU_QUANTIZATION_PARAMS_CONTROL (0x868AU) +#define USB_DEVICE_VIDEO_GET_INFO_EU_SYNC_REF_FRAME_CONTROL (0x868BU) +#define USB_DEVICE_VIDEO_GET_INFO_EU_LTR_BUFFER_CONTROL (0x868CU) +#define USB_DEVICE_VIDEO_GET_INFO_EU_LTR_PICTURE_CONTROL (0x868DU) +#define USB_DEVICE_VIDEO_GET_INFO_EU_LTR_VALIDATION_CONTROL (0x868EU) +#define USB_DEVICE_VIDEO_GET_INFO_EU_SEI_PAYLOADTYPE_CONTROL (0x8690U) +#define USB_DEVICE_VIDEO_GET_INFO_EU_QP_RANGE_CONTROL (0x8691U) +#define USB_DEVICE_VIDEO_GET_INFO_EU_PRIORITY_CONTROL (0x8692U) +#define USB_DEVICE_VIDEO_GET_INFO_EU_START_OR_STOP_LAYER_CONTROL (0x8693U) +#endif + +/*! @brief Video device class-specific request GET DEF COMMAND */ +#define USB_DEVICE_VIDEO_GET_DEF_PU_BACKLIGHT_COMPENSATION_CONTROL (0x8721U) +#define USB_DEVICE_VIDEO_GET_DEF_PU_BRIGHTNESS_CONTROL (0x8722U) +#define USB_DEVICE_VIDEO_GET_DEF_PU_CONTRACT_CONTROL (0x8723U) +#define USB_DEVICE_VIDEO_GET_DEF_PU_GAIN_CONTROL (0x8724U) +#define USB_DEVICE_VIDEO_GET_DEF_PU_POWER_LINE_FREQUENCY_CONTROL (0x8725U) +#define USB_DEVICE_VIDEO_GET_DEF_PU_HUE_CONTROL (0x8726U) +#define USB_DEVICE_VIDEO_GET_DEF_PU_SATURATION_CONTROL (0x8727U) +#define USB_DEVICE_VIDEO_GET_DEF_PU_SHARRNESS_CONTROL (0x8728U) +#define USB_DEVICE_VIDEO_GET_DEF_PU_GAMMA_CONTROL (0x8729U) +#define USB_DEVICE_VIDEO_GET_DEF_PU_WHITE_BALANCE_TEMPERATURE_CONTROL (0x872AU) +#define USB_DEVICE_VIDEO_GET_DEF_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL (0x872BU) +#define USB_DEVICE_VIDEO_GET_DEF_PU_WHITE_BALANCE_COMPONENT_CONTROL (0x872CU) +#define USB_DEVICE_VIDEO_GET_DEF_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL (0x872DU) +#define USB_DEVICE_VIDEO_GET_DEF_PU_DIGITAL_MULTIPLIER_CONTROL (0x872EU) +#define USB_DEVICE_VIDEO_GET_DEF_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL (0x872FU) +#define USB_DEVICE_VIDEO_GET_DEF_PU_HUE_AUTO_CONTROL (0x8730U) +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_GET_DEF_PU_CONTRAST_AUTO_CONTROL (0x8731U) +#endif + +#define USB_DEVICE_VIDEO_GET_DEF_CT_AE_MODE_CONTROL (0x8742U) +#define USB_DEVICE_VIDEO_GET_DEF_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL (0x8744U) +#define USB_DEVICE_VIDEO_GET_DEF_CT_FOCUS_ABSOLUTE_CONTROL (0x8746U) +#define USB_DEVICE_VIDEO_GET_DEF_CT_FOCUS_RELATIVE_CONTROL (0x8747U) +#define USB_DEVICE_VIDEO_GET_DEF_CT_FOCUS_AUTO_CONTROL (0x8748U) +#define USB_DEVICE_VIDEO_GET_DEF_CT_IRIS_ABSOLUTE_CONTROL (0x8749U) +#define USB_DEVICE_VIDEO_GET_DEF_CT_ZOOM_ABSOLUTE_CONTROL (0x874BU) +#define USB_DEVICE_VIDEO_GET_DEF_CT_ZOOM_RELATIVE_CONTROL (0x874CU) +#define USB_DEVICE_VIDEO_GET_DEF_CT_PANTILT_ABSOLUTE_CONTROL (0x874DU) +#define USB_DEVICE_VIDEO_GET_DEF_CT_PANTILT_RELATIVE_CONTROL (0x874EU) +#define USB_DEVICE_VIDEO_GET_DEF_CT_ROLL_ABSOLUTE_CONTROL (0x874FU) +#define USB_DEVICE_VIDEO_GET_DEF_CT_ROLL_RELATIVE_CONTROL (0x8750U) +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_GET_DEF_CT_FOCUS_SIMPLE_CONTROL (0x8751U) +#define USB_DEVICE_VIDEO_GET_DEF_CT_DIGITAL_WINDOW_CONTROL (0x8752U) +#define USB_DEVICE_VIDEO_GET_DEF_CT_REGION_OF_INTEREST_CONTROL (0x8753U) +#endif + +#define USB_DEVICE_VIDEO_GET_DEF_VS_PROBE_CONTROL (0x8761U) +#define USB_DEVICE_VIDEO_GET_DEF_VS_STILL_PROBE_CONTROL (0x8763U) +#define USB_DEVICE_VIDEO_GET_DEF_VS_UPDATE_FRAME_SEGMENT_CONTROL (0x8768U) +#define USB_DEVICE_VIDEO_GET_DEF_VS_SYNCH_DELAY_CONTROL (0x8769U) + +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_GET_DEF_EU_PROFILE_TOOLSET_CONTROL (0x8782U) +#define USB_DEVICE_VIDEO_GET_DEF_EU_VIDEO_RESOLUTION_CONTROL (0x8783U) +#define USB_DEVICE_VIDEO_GET_DEF_EU_MIN_FRAME_INTERVAL_CONTROL (0x8784U) +#define USB_DEVICE_VIDEO_GET_DEF_EU_SLICE_MODE_CONTROL (0x8785U) +#define USB_DEVICE_VIDEO_GET_DEF_EU_RATE_CONTROL_MODE_CONTROL (0x8786U) +#define USB_DEVICE_VIDEO_GET_DEF_EU_AVERAGE_BITRATE_CONTROL (0x8787U) +#define USB_DEVICE_VIDEO_GET_DEF_EU_CPB_SIZE_CONTROL (0x8788U) +#define USB_DEVICE_VIDEO_GET_DEF_EU_PEAK_BIT_RATE_CONTROL (0x8789U) +#define USB_DEVICE_VIDEO_GET_DEF_EU_QUANTIZATION_PARAMS_CONTROL (0x878AU) +#define USB_DEVICE_VIDEO_GET_DEF_EU_LTR_BUFFER_CONTROL (0x878CU) +#define USB_DEVICE_VIDEO_GET_DEF_EU_LTR_PICTURE_CONTROL (0x878DU) +#define USB_DEVICE_VIDEO_GET_DEF_EU_LTR_VALIDATION_CONTROL (0x878EU) +#define USB_DEVICE_VIDEO_GET_DEF_EU_LEVEL_IDC_LIMIT_CONTROL (0x878FU) +#define USB_DEVICE_VIDEO_GET_DEF_EU_SEI_PAYLOADTYPE_CONTROL (0x8790U) +#define USB_DEVICE_VIDEO_GET_DEF_EU_QP_RANGE_CONTROL (0x8791U) +#define USB_DEVICE_VIDEO_GET_DEF_EU_ERROR_RESILIENCY_CONTROL (0x8794U) +#endif + +/*! @brief Video device class-specific request SET CUR COMMAND */ +#define USB_DEVICE_VIDEO_SET_CUR_VC_POWER_MODE_CONTROL (0x0101U) + +#define USB_DEVICE_VIDEO_SET_CUR_PU_BACKLIGHT_COMPENSATION_CONTROL (0x0121U) +#define USB_DEVICE_VIDEO_SET_CUR_PU_BRIGHTNESS_CONTROL (0x0122U) +#define USB_DEVICE_VIDEO_SET_CUR_PU_CONTRACT_CONTROL (0x0123U) +#define USB_DEVICE_VIDEO_SET_CUR_PU_GAIN_CONTROL (0x0124U) +#define USB_DEVICE_VIDEO_SET_CUR_PU_POWER_LINE_FREQUENCY_CONTROL (0x0125U) +#define USB_DEVICE_VIDEO_SET_CUR_PU_HUE_CONTROL (0x0126U) +#define USB_DEVICE_VIDEO_SET_CUR_PU_SATURATION_CONTROL (0x0127U) +#define USB_DEVICE_VIDEO_SET_CUR_PU_SHARRNESS_CONTROL (0x0128U) +#define USB_DEVICE_VIDEO_SET_CUR_PU_GAMMA_CONTROL (0x0129U) +#define USB_DEVICE_VIDEO_SET_CUR_PU_WHITE_BALANCE_TEMPERATURE_CONTROL (0x012AU) +#define USB_DEVICE_VIDEO_SET_CUR_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL (0x012BU) +#define USB_DEVICE_VIDEO_SET_CUR_PU_WHITE_BALANCE_COMPONENT_CONTROL (0x012CU) +#define USB_DEVICE_VIDEO_SET_CUR_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL (0x012DU) +#define USB_DEVICE_VIDEO_SET_CUR_PU_DIGITAL_MULTIPLIER_CONTROL (0x012EU) +#define USB_DEVICE_VIDEO_SET_CUR_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL (0x012FU) +#define USB_DEVICE_VIDEO_SET_CUR_PU_HUE_AUTO_CONTROL (0x0130U) +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_SET_CUR_PU_CONTRAST_AUTO_CONTROL (0x0131U) +#endif + +#define USB_DEVICE_VIDEO_SET_CUR_CT_SCANNING_MODE_CONTROL (0x0141U) +#define USB_DEVICE_VIDEO_SET_CUR_CT_AE_MODE_CONTROL (0x0142U) +#define USB_DEVICE_VIDEO_SET_CUR_CT_AE_PRIORITY_CONTROL (0x0143U) +#define USB_DEVICE_VIDEO_SET_CUR_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL (0x0144U) +#define USB_DEVICE_VIDEO_SET_CUR_CT_EXPOSURE_TIME_RELATIVE_CONTROL (0x0145U) +#define USB_DEVICE_VIDEO_SET_CUR_CT_FOCUS_ABSOLUTE_CONTROL (0x0146U) +#define USB_DEVICE_VIDEO_SET_CUR_CT_FOCUS_RELATIVE_CONTROL (0x0147U) +#define USB_DEVICE_VIDEO_SET_CUR_CT_FOCUS_AUTO_CONTROL (0x0148U) +#define USB_DEVICE_VIDEO_SET_CUR_CT_IRIS_ABSOLUTE_CONTROL (0x0149U) +#define USB_DEVICE_VIDEO_SET_CUR_CT_IRIS_RELATIVE_CONTROL (0x014AU) +#define USB_DEVICE_VIDEO_SET_CUR_CT_ZOOM_ABSOLUTE_CONTROL (0x014BU) +#define USB_DEVICE_VIDEO_SET_CUR_CT_ZOOM_RELATIVE_CONTROL (0x014CU) +#define USB_DEVICE_VIDEO_SET_CUR_CT_PANTILT_ABSOLUTE_CONTROL (0x014DU) +#define USB_DEVICE_VIDEO_SET_CUR_CT_PANTILT_RELATIVE_CONTROL (0x014EU) +#define USB_DEVICE_VIDEO_SET_CUR_CT_ROLL_ABSOLUTE_CONTROL (0x014FU) +#define USB_DEVICE_VIDEO_SET_CUR_CT_ROLL_RELATIVE_CONTROL (0x0150U) +#define USB_DEVICE_VIDEO_SET_CUR_CT_PRIVACY_CONTROL (0x0151U) +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_SET_CUR_CT_FOCUS_SIMPLE_CONTROL (0x0152U) +#define USB_DEVICE_VIDEO_SET_CUR_CT_DIGITAL_WINDOW_CONTROL (0x0153U) +#define USB_DEVICE_VIDEO_SET_CUR_CT_REGION_OF_INTEREST_CONTROL (0x0154U) +#endif + +#define USB_DEVICE_VIDEO_SET_CUR_VS_PROBE_CONTROL (0x0161U) +#define USB_DEVICE_VIDEO_SET_CUR_VS_COMMIT_CONTROL (0x0162U) +#define USB_DEVICE_VIDEO_SET_CUR_VS_STILL_PROBE_CONTROL (0x0163U) +#define USB_DEVICE_VIDEO_SET_CUR_VS_STILL_COMMIT_CONTROL (0x0164U) +#define USB_DEVICE_VIDEO_SET_CUR_VS_STILL_IMAGE_TRIGGER_CONTROL (0x0165U) +#define USB_DEVICE_VIDEO_SET_CUR_VS_STREAM_ERROR_CODE_CONTROL (0x0166U) +#define USB_DEVICE_VIDEO_SET_CUR_VS_GENERATE_KEY_FRAME_CONTROL (0x0167U) +#define USB_DEVICE_VIDEO_SET_CUR_VS_UPDATE_FRAME_SEGMENT_CONTROL (0x0168U) +#define USB_DEVICE_VIDEO_SET_CUR_VS_SYNCH_DELAY_CONTROL (0x0169U) + +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 +#define USB_DEVICE_VIDEO_SET_CUR_EU_SELECT_LAYER_CONTROL (0x0181U) +#define USB_DEVICE_VIDEO_SET_CUR_EU_PROFILE_TOOLSET_CONTROL (0x0182U) +#define USB_DEVICE_VIDEO_SET_CUR_EU_VIDEO_RESOLUTION_CONTROL (0x0183U) +#define USB_DEVICE_VIDEO_SET_CUR_EU_MIN_FRAME_INTERVAL_CONTROL (0x0184U) +#define USB_DEVICE_VIDEO_SET_CUR_EU_SLICE_MODE_CONTROL (0x0185U) +#define USB_DEVICE_VIDEO_SET_CUR_EU_RATE_CONTROL_MODE_CONTROL (0x0186U) +#define USB_DEVICE_VIDEO_SET_CUR_EU_AVERAGE_BITRATE_CONTROL (0x0187U) +#define USB_DEVICE_VIDEO_SET_CUR_EU_CPB_SIZE_CONTROL (0x0188U) +#define USB_DEVICE_VIDEO_SET_CUR_EU_PEAK_BIT_RATE_CONTROL (0x0189U) +#define USB_DEVICE_VIDEO_SET_CUR_EU_QUANTIZATION_PARAMS_CONTROL (0x018AU) +#define USB_DEVICE_VIDEO_SET_CUR_EU_SYNC_REF_FRAME_CONTROL (0x018BU) +#define USB_DEVICE_VIDEO_SET_CUR_EU_LTR_BUFFER_CONTROL (0x018CU) +#define USB_DEVICE_VIDEO_SET_CUR_EU_LTR_PICTURE_CONTROL (0x018DU) +#define USB_DEVICE_VIDEO_SET_CUR_EU_LTR_VALIDATION_CONTROL (0x018EU) +#define USB_DEVICE_VIDEO_SET_CUR_EU_LEVEL_IDC_LIMIT_CONTROL (0x018FU) +#define USB_DEVICE_VIDEO_SET_CUR_EU_SEI_PAYLOADTYPE_CONTROL (0x0190U) +#define USB_DEVICE_VIDEO_SET_CUR_EU_QP_RANGE_CONTROL (0x0191U) +#define USB_DEVICE_VIDEO_SET_CUR_EU_PRIORITY_CONTROL (0x0192U) +#define USB_DEVICE_VIDEO_SET_CUR_EU_START_OR_STOP_LAYER_CONTROL (0x0193U) +#define USB_DEVICE_VIDEO_SET_CUR_EU_ERROR_RESILIENCY_CONTROL (0x0194U) +#endif + +/*! @}*/ + +/*! @brief The payload header structure for MJPEG payload format. */ +STRUCT_PACKED +struct _usb_device_video_mjpeg_payload_header_struct +{ + uint8_t bHeaderLength; /*!< The payload header length. */ + union + { + uint8_t bmheaderInfo; /*!< The payload header bitmap field. */ + struct + { + uint8_t frameIdentifier : 1U; /*!< Frame Identifier. This bit toggles at each frame start boundary and stays + constant for the rest of the frame.*/ + uint8_t endOfFrame : 1U; /*!< End of Frame. This bit indicates the end of a video frame and is set in the + last video sample that belongs to a frame.*/ + uint8_t + presentationTimeStamp : 1U; /*!< Presentation Time Stamp. This bit, when set, indicates the presence of + a PTS field.*/ + uint8_t sourceClockReference : 1U; /*!< Source Clock Reference. This bit, when set, indicates the presence + of a SCR field.*/ + uint8_t reserved : 1U; /*!< Reserved. Set to 0. */ + uint8_t stillImage : 1U; /*!< Still Image. This bit, when set, identifies a video sample that belongs to a + still image.*/ + uint8_t errorBit : 1U; /*!< Error Bit. This bit, when set, indicates an error in the device streaming.*/ + uint8_t endOfHeader : 1U; /*!< End of Header. This bit, when set, indicates the end of the BFH fields.*/ + } headerInfoBits; + struct + { + uint8_t FID : 1U; /*!< Frame Identifier. This bit toggles at each frame start boundary and stays constant + for the rest of the frame.*/ + uint8_t EOI : 1U; /*!< End of Frame. This bit indicates the end of a video frame and is set in the last + video sample that belongs to a frame.*/ + uint8_t PTS : 1U; /*!< Presentation Time Stamp. This bit, when set, indicates the presence of a PTS field.*/ + uint8_t SCR : 1U; /*!< Source Clock Reference. This bit, when set, indicates the presence of a SCR field.*/ + uint8_t RES : 1U; /*!< Reserved. Set to 0. */ + uint8_t STI : 1U; /*!< Still Image. This bit, when set, identifies a video sample that belongs to a still + image.*/ + uint8_t ERR : 1U; /*!< Error Bit. This bit, when set, indicates an error in the device streaming.*/ + uint8_t EOH : 1U; /*!< End of Header. This bit, when set, indicates the end of the BFH fields.*/ + } headerInfoBitmap; + } headerInfoUnion; + uint32_t dwPresentationTime; /*!< Presentation time stamp (PTS) field.*/ + uint8_t bSourceClockReference[6]; /*!< Source clock reference (SCR) field.*/ +} STRUCT_UNPACKED; +typedef struct _usb_device_video_mjpeg_payload_header_struct usb_device_video_mjpeg_payload_header_struct_t; + +/*! @brief The Video probe and commit controls structure.*/ +STRUCT_PACKED +struct _usb_device_video_probe_and_commit_controls_struct +{ + union + { + uint8_t bmHint; /*!< Bit-field control indicating to the function what fields shall be kept fixed. */ + struct + { + uint8_t dwFrameInterval : 1U; /*!< dwFrameInterval field.*/ + uint8_t wKeyFrameRate : 1U; /*!< wKeyFrameRate field.*/ + uint8_t wPFrameRate : 1U; /*!< wPFrameRate field.*/ + uint8_t wCompQuality : 1U; /*!< wCompQuality field.*/ + uint8_t wCompWindowSize : 1U; /*!< wCompWindowSize field.*/ + uint8_t reserved : 3U; /*!< Reserved field.*/ + } hintBitmap; + } hintUnion; + union + { + uint8_t bmHint; /*!< Bit-field control indicating to the function what fields shall be kept fixed. */ + struct + { + uint8_t reserved : 8U; /*!< Reserved field.*/ + } hintBitmap; + } hintUnion1; + uint8_t bFormatIndex; /*!< Video format index from a format descriptor.*/ + uint8_t bFrameIndex; /*!< Video frame index from a frame descriptor.*/ + uint32_t dwFrameInterval; /*!< Frame interval in 100ns units.*/ + uint16_t wKeyFrameRate; /*!< Key frame rate in key-frame per video-frame units.*/ + uint16_t wPFrameRate; /*!< PFrame rate in PFrame/key frame units.*/ + uint16_t wCompQuality; /*!< Compression quality control in abstract units 0U (lowest) to 10000U (highest).*/ + uint16_t wCompWindowSize; /*!< Window size for average bit rate control.*/ + uint16_t wDelay; /*!< Internal video streaming interface latency in ms from video data capture to presentation on + the USB.*/ + uint32_t dwMaxVideoFrameSize; /*!< Maximum video frame or codec-specific segment size in bytes.*/ + uint32_t dwMaxPayloadTransferSize; /*!< Specifies the maximum number of bytes that the device can transmit or + receive in a single payload transfer.*/ + uint32_t dwClockFrequency; /*!< The device clock frequency in Hz for the specified format. This specifies the + units used for the time information fields in the Video Payload Headers in the data + stream.*/ + uint8_t bmFramingInfo; /*!< Bit-field control supporting the following values: D0 Frame ID, D1 EOF.*/ + uint8_t bPreferedVersion; /*!< The preferred payload format version supported by the host or device for the + specified bFormatIndex value.*/ + uint8_t bMinVersion; /*!< The minimum payload format version supported by the device for the specified bFormatIndex + value.*/ + uint8_t bMaxVersion; /*!< The maximum payload format version supported by the device for the specified bFormatIndex + value.*/ +#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5 + uint8_t bUsage; /*!< This bitmap enables features reported by the bmUsages field of the Video Frame Descriptor.*/ + uint8_t + bBitDepthLuma; /*!< Represents bit_depth_luma_minus8 + 8U, which must be the same as bit_depth_chroma_minus8 + + 8.*/ + uint8_t bmSettings; /*!< A bitmap of flags that is used to discover and control specific features of a temporally + encoded video stream.*/ + uint8_t bMaxNumberOfRefFramesPlus1; /*!< Host indicates the maximum number of frames stored for use as references.*/ + uint16_t bmRateControlModes; /*!< This field contains 4U sub-fields, each of which is a 4U bit number.*/ + uint64_t bmLayoutPerStream; /*!< This field contains 4U sub-fields, each of which is a 2U byte number.*/ +#endif +} STRUCT_UNPACKED; +typedef struct _usb_device_video_probe_and_commit_controls_struct usb_device_video_probe_and_commit_controls_struct_t; + +/*! @brief The Video still probe and still commit controls structure.*/ +STRUCT_PACKED +struct _usb_device_video_still_probe_and_commit_controls_struct +{ + uint8_t bFormatIndex; /*!< Video format index from a format descriptor.*/ + uint8_t bFrameIndex; /*!< Video frame index from a frame descriptor.*/ + uint8_t bCompressionIndex; /*!< Compression index from a frame descriptor.*/ + uint32_t dwMaxVideoFrameSize; /*!< Maximum still image size in bytes.*/ + uint32_t dwMaxPayloadTransferSize; /*!< Specifies the maximum number of bytes that the device can transmit or + receive in a single payload transfer.*/ +} STRUCT_UNPACKED; +typedef struct _usb_device_video_still_probe_and_commit_controls_struct + usb_device_video_still_probe_and_commit_controls_struct_t; + +/*! @brief Available common event types in video class callback */ +typedef enum _usb_device_video_event +{ + kUSB_DeviceVideoEventStreamSendResponse = 0x01U, /*!< Send data completed or cancelled in stream pipe */ + kUSB_DeviceVideoEventStreamRecvResponse, /*!< Data received or cancelled in stream pipe */ + kUSB_DeviceVideoEventControlSendResponse, /*!< Send data completed or cancelled etc in video control pipe */ + kUSB_DeviceVideoEventClassRequestBuffer, /*!< Get buffer to save the data of the video class-specific request. */ +} usb_device_video_event_t; + +/*! + * @brief The video device class-specific information. + * The structure is used to pass the video entity information filled by application. + * Such as + * entity id (unit or terminal ID), + * entity type (unit or terminal type), + * and terminal type if the entity is a terminal. + */ +typedef struct _usb_device_video_entity_struct +{ + uint8_t entityId; + uint8_t entityType; + uint16_t terminalType; +} usb_device_video_entity_struct_t; + +/*! + * @brief The video device class-specific information list. + * The structure is used to pass the video entity informations filled by the application. + * The type of each entity is the usb_device_video_entity_struct_t. + * The structure pointer is kept in the usb_device_interface_struct_t::classSpecific, + * such as, if there are three entities(out terminal, camera terminal, and processing unit), + * the value of the count field is 3U and the entity field saves the every entity information. + */ +typedef struct _usb_device_video_entities_struct +{ + usb_device_video_entity_struct_t *entity; + uint8_t count; +} usb_device_video_entities_struct_t; + +/*! @brief The video device class status structure */ +typedef struct _usb_device_video_struct +{ + usb_device_handle handle; /*!< The device handle */ + usb_device_class_config_struct_t *configStruct; /*!< The configuration of the class. */ + usb_device_interface_struct_t *controlInterfaceHandle; /*!< Current control interface handle */ + usb_device_interface_struct_t *streamInterfaceHandle; /*!< Current stream interface handle */ + uint8_t configuration; /*!< Current configuration */ + uint8_t controlInterfaceNumber; /*!< The control interface number of the class */ + uint8_t controlAlternate; /*!< Current alternate setting of the control interface */ + uint8_t streamInterfaceNumber; /*!< The stream interface number of the class */ + uint8_t streamAlternate; /*!< Current alternate setting of the stream interface */ + uint8_t streamInPipeBusy; /*!< Stream IN pipe busy flag */ + uint8_t streamOutPipeBusy; /*!< Stream OUT pipe busy flag */ +} usb_device_video_struct_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the video class. + * + * This function is used to initialize the video class. This function can only be called by the #USB_DeviceClassInit. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t. + * @param[in] config The class configuration information. + * @param[in] handle An parameter used to return pointer of the video class handle to the caller. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DeviceVideoInit(uint8_t controllerId, + usb_device_class_config_struct_t *config, + class_handle_t *handle); + +/*! + * @brief Deinitializes the device video class. + * + * The function deinitializes the device video class. This function can only be called by the #USB_DeviceClassDeinit. + * + * @param[in] handle The video class handle received from usb_device_class_config_struct_t::classHandle. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DeviceVideoDeinit(class_handle_t handle); + +/*! + * @brief Handles the event passed to the video class. + * + * This function handles the event passed to the video class. This function can only be called by the + * #USB_DeviceClassEvent. + * + * @param[in] handle The video class handle received from the usb_device_class_config_struct_t::classHandle. + * @param[in] event The event codes. See the enumeration #usb_device_class_event_t. + * @param[in,out] param The parameter type is determined by the event code. + * + * @return A USB error code or kStatus_USB_Success. + * @retval kStatus_USB_Success Free device handle successfully. + * @retval kStatus_USB_InvalidParameter The device handle is not found. + * @retval kStatus_USB_InvalidRequest The request is invalid and the control pipe is stalled by the caller. + */ +extern usb_status_t USB_DeviceVideoEvent(void *handle, uint32_t event, void *param); + +/*! + * @name USB device video class APIs + * @{ + */ + +/*! + * @brief Sends data through a specified endpoint. + * + * The function is used to send data through a specified endpoint. + * The function calls #USB_DeviceSendRequest internally. + * + * @param[in] handle The video class handle received from usb_device_class_config_struct_t::classHandle. + * @param[in] ep Endpoint index. + * @param[in] buffer The memory address to hold the data need to be sent. + * @param[in] length The data length to be sent. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The function can only be called in the same context. + * + * @note The return value indicates whether the sending request is successful or not. The transfer done is notified by + * USB_DeviceVideoStreamIn or USB_DeviceVideoControlIn. + * Currently, only one transfer request can be supported for a specific endpoint. + * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer can begin only when the previous transfer is done (a notification is received through the + * endpoint + * callback). + */ +extern usb_status_t USB_DeviceVideoSend(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length); + +/*! + * @brief Receives data through a specified endpoint. + * + * The function is used to receive data through a specified endpoint. + * The function calls the #USB_DeviceRecvRequest internally. + * + * @param[in] handle The video class handle got from usb_device_class_config_struct_t::classHandle. + * @param[in] ep Endpoint index. + * @param[in] buffer The memory address to save the received data. + * @param[in] length The data length want to be received. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The function can only be called in the same context. + * + * @note The return value indicates whether the receiving request is successful or not. The transfer done is notified by + * USB_DeviceVideoStreamOut. + * Currently, only one transfer request can be supported for a specific endpoint. + * If there is a specific requirement to support multiple transfer requests for a specific endpoint. The application + * should implement a queue in the application level. + * The subsequent transfer can begin only when the previous transfer is done (a notification is received through the + * endpoint + * callback). + */ +extern usb_status_t USB_DeviceVideoRecv(class_handle_t handle, uint8_t ep, uint8_t *buffer, uint32_t length); + +/*! @}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __USB_DEVICE_VIDEO_H__ */ diff --git a/usb/device/include/usb_device.h b/usb/device/include/usb_device.h new file mode 100644 index 0000000..64b29ce --- /dev/null +++ b/usb/device/include/usb_device.h @@ -0,0 +1,635 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_H__ +#define __USB_DEVICE_H__ + +/*! + * @addtogroup usb_device_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Defines Get/Set status Types */ +typedef enum _usb_device_status +{ + kUSB_DeviceStatusTestMode = 1U, /*!< Test mode */ + kUSB_DeviceStatusSpeed, /*!< Current speed */ + kUSB_DeviceStatusOtg, /*!< OTG status */ + kUSB_DeviceStatusDevice, /*!< Device status */ + kUSB_DeviceStatusEndpoint, /*!< Endpoint state usb_device_endpoint_status_t */ + kUSB_DeviceStatusDeviceState, /*!< Device state */ + kUSB_DeviceStatusAddress, /*!< Device address */ + kUSB_DeviceStatusSynchFrame, /*!< Current frame */ + kUSB_DeviceStatusBus, /*!< Bus status */ + kUSB_DeviceStatusBusSuspend, /*!< Bus suspend */ + kUSB_DeviceStatusBusSleep, /*!< Bus suspend */ + kUSB_DeviceStatusBusResume, /*!< Bus resume */ + kUSB_DeviceStatusRemoteWakeup, /*!< Remote wakeup state */ + kUSB_DeviceStatusBusSleepResume, /*!< Bus resume */ +} usb_device_status_t; + +/*! @brief Defines USB 2.0 device state */ +typedef enum _usb_device_state +{ + kUSB_DeviceStateConfigured = 0U, /*!< Device state, Configured*/ + kUSB_DeviceStateAddress, /*!< Device state, Address*/ + kUSB_DeviceStateDefault, /*!< Device state, Default*/ + kUSB_DeviceStateAddressing, /*!< Device state, Address setting*/ + kUSB_DeviceStateTestMode, /*!< Device state, Test mode*/ +} usb_device_state_t; + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) +typedef enum _usb_dcd_detection_sequence_status +{ + kUSB_DcdDetectionNotEnabled = 0x0U, + kUSB_DcdDataPinDetectionCompleted = 0x01U, + kUSB_DcdChargingPortDetectionCompleted = 0x02U, + kUSB_DcdChargerTypeDetectionCompleted = 0x03U, +} usb_dcd_detection_sequence_status_t; + +typedef enum _usb_dcd_detection_sequence_results +{ + kUSB_DcdDetectionNoResults = 0x0U, + kUSB_DcdDetectionStandardHost = 0x01U, + kUSB_DcdDetectionChargingPort = 0x02U, + kUSB_DcdDetectionDedicatedCharger = 0x03U, +} usb_dcd_detection_sequence_results_t; +#endif + +/*! @brief Defines endpoint state */ +typedef enum _usb_endpoint_status +{ + kUSB_DeviceEndpointStateIdle = 0U, /*!< Endpoint state, idle*/ + kUSB_DeviceEndpointStateStalled, /*!< Endpoint state, stalled*/ +} usb_device_endpoint_status_t; + +/*! @brief Control endpoint index */ +#define USB_CONTROL_ENDPOINT (0U) +/*! @brief Control endpoint maxPacketSize */ +#define USB_CONTROL_MAX_PACKET_SIZE (64U) + +#if (USB_DEVICE_CONFIG_EHCI && (USB_CONTROL_MAX_PACKET_SIZE != (64U))) +#error For high speed, USB_CONTROL_MAX_PACKET_SIZE must be 64!!! +#endif + +/*! @brief The setup packet size of USB control transfer. */ +#define USB_SETUP_PACKET_SIZE (8U) +/*! @brief USB endpoint mask */ +#define USB_ENDPOINT_NUMBER_MASK (0x0FU) + +/*! @brief Default invalid value or the endpoint callback length of cancelled transfer */ +#define USB_UNINITIALIZED_VAL_32 (0xFFFFFFFFU) + +/*! @brief Available common EVENT types in device callback */ +typedef enum _usb_device_event +{ + kUSB_DeviceEventBusReset = 1U, /*!< USB bus reset signal detected */ + kUSB_DeviceEventSuspend, /*!< USB bus suspend signal detected */ + kUSB_DeviceEventResume, /*!< USB bus resume signal detected. The resume signal is driven by itself or a host */ + kUSB_DeviceEventSleeped, /*!< USB bus LPM suspend signal detected */ + kUSB_DeviceEventLPMResume, /*!< USB bus LPM resume signal detected. The resume signal is driven by itself or a host + */ + kUSB_DeviceEventError, /*!< An error is happened in the bus. */ + kUSB_DeviceEventDetach, /*!< USB device is disconnected from a host. */ + kUSB_DeviceEventAttach, /*!< USB device is connected to a host. */ + kUSB_DeviceEventSetConfiguration, /*!< Set configuration. */ + kUSB_DeviceEventSetInterface, /*!< Set interface. */ + + kUSB_DeviceEventGetDeviceDescriptor, /*!< Get device descriptor. */ + kUSB_DeviceEventGetConfigurationDescriptor, /*!< Get configuration descriptor. */ + kUSB_DeviceEventGetStringDescriptor, /*!< Get string descriptor. */ + kUSB_DeviceEventGetHidDescriptor, /*!< Get HID descriptor. */ + kUSB_DeviceEventGetHidReportDescriptor, /*!< Get HID report descriptor. */ + kUSB_DeviceEventGetHidPhysicalDescriptor, /*!< Get HID physical descriptor. */ + kUSB_DeviceEventGetBOSDescriptor, /*!< Get configuration descriptor. */ + kUSB_DeviceEventGetDeviceQualifierDescriptor, /*!< Get device qualifier descriptor. */ + kUSB_DeviceEventVendorRequest, /*!< Vendor request. */ + kUSB_DeviceEventSetRemoteWakeup, /*!< Enable or disable remote wakeup function. */ + kUSB_DeviceEventGetConfiguration, /*!< Get current configuration index */ + kUSB_DeviceEventGetInterface, /*!< Get current interface alternate setting value */ + kUSB_DeviceEventSetBHNPEnable, +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) + kUSB_DeviceEventDcdTimeOut, /*!< Dcd detect result is timeout */ + kUSB_DeviceEventDcdUnknownType, /*!< Dcd detect result is unknown type */ + kUSB_DeviceEventSDPDetected, /*!< The SDP facility is detected */ + kUSB_DeviceEventChargingPortDetected, /*!< The charging port is detected */ + kUSB_DeviceEventChargingHostDetected, /*!< The CDP facility is detected */ + kUSB_DeviceEventDedicatedChargerDetected, /*!< The DCP facility is detected */ +#endif +} usb_device_event_t; + +/*! @brief Endpoint callback message structure */ +typedef struct _usb_device_endpoint_callback_message_struct +{ + uint8_t *buffer; /*!< Transferred buffer */ + uint32_t length; /*!< Transferred data length */ + uint8_t isSetup; /*!< Is in a setup phase */ +} usb_device_endpoint_callback_message_struct_t; + +/*! + * @brief Endpoint callback function typedef. + * + * This callback function is used to notify the upper layer what the transfer result is. + * This callback pointer is passed when a specified endpoint is initialized by calling API #USB_DeviceInitEndpoint. + * + * @param handle The device handle. It equals to the value returned from #USB_DeviceInit. + * @param message The result of a transfer, which includes transfer buffer, transfer length, and whether is in a + * setup phase. + * phase for control pipe. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. + * + * @return A USB error code or kStatus_USB_Success. + */ +typedef usb_status_t (*usb_device_endpoint_callback_t)(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam); + +/*! + * @brief Device callback function typedef. + * + * This callback function is used to notify the upper layer that the device status has changed. + * This callback pointer is passed by calling API #USB_DeviceInit. + * + * @param handle The device handle. It equals the value returned from #USB_DeviceInit. + * @param callbackEvent The callback event type. See enumeration #usb_device_event_t. + * @param eventParam The event parameter for this callback. The parameter type is determined by the callback event. + * + * @return A USB error code or kStatus_USB_Success. + */ +typedef usb_status_t (*usb_device_callback_t)(usb_device_handle handle, uint32_t callbackEvent, void *eventParam); + +/*! @brief Endpoint callback structure */ +typedef struct _usb_device_endpoint_callback_struct +{ + usb_device_endpoint_callback_t callbackFn; /*!< Endpoint callback function*/ + void *callbackParam; /*!< Parameter for callback function*/ + uint8_t isBusy; +} usb_device_endpoint_callback_struct_t; + +/*! @brief Endpoint initialization structure */ +typedef struct _usb_device_endpoint_init_struct +{ + uint16_t maxPacketSize; /*!< Endpoint maximum packet size */ + uint8_t endpointAddress; /*!< Endpoint address*/ + uint8_t transferType; /*!< Endpoint transfer type*/ + uint8_t zlt; /*!< ZLT flag*/ + uint8_t interval; /*!< Endpoint interval*/ +} usb_device_endpoint_init_struct_t; + +/*! @brief Endpoint status structure */ +typedef struct _usb_device_endpoint_status_struct +{ + uint8_t endpointAddress; /*!< Endpoint address */ + uint16_t endpointStatus; /*!< Endpoint status : idle or stalled */ +} usb_device_endpoint_status_struct_t; + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) +/*! @brief USB DCD charge timing specification structure */ +typedef struct _usb_device_dcd_charging_time +{ + uint16_t dcdSeqInitTime; /*!< The dcd sequence init time */ + uint16_t dcdDbncTime; /*!< The debounce time period on DP signal */ + uint16_t dcdDpSrcOnTime; /*!< The time period comparator enabled */ + uint16_t dcdTimeWaitAfterPrD; /*!< The time period between primary and secondary detection */ + uint8_t dcdTimeDMSrcOn; /*!< The amount of time that the modules enable the Vdm_src */ +} usb_device_dcd_charging_time_t; +#endif + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @name USB device APIs + * @{ + */ + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @brief Initializes the USB device stack. + * + * This function initializes the USB device module specified by the controllerId. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t. + * @param[in] deviceCallback Function pointer of the device callback. + * @param[out] handle It is an out parameter used to return the pointer of the device handle to the caller. + * + * @retval kStatus_USB_Success The device is initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. + * @retval kStatus_USB_Busy Cannot allocate a device handle. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller according to the controller id. + * @retval kStatus_USB_InvalidControllerInterface The controller driver interfaces is invalid. There is an empty + * interface entity. + * @retval kStatus_USB_Error The macro USB_DEVICE_CONFIG_ENDPOINTS is more than the IP's endpoint number. + * Or, the device has been initialized. + * Or, the mutex or message queue is created failed. + */ +extern usb_status_t USB_DeviceInit(uint8_t controllerId, + usb_device_callback_t deviceCallback, + usb_device_handle *handle); + +/*! + * @brief Enables the device functionality. + * + * The function enables the device functionality, so that the device can be recognized by the host when the device + * detects that it has been connected to a host. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is run successfully. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + * + */ +extern usb_status_t USB_DeviceRun(usb_device_handle handle); + +/*! + * @brief Disables the device functionality. + * + * The function disables the device functionality. After this function called, even if the device is detached to the + * host, + * it can't work. + * + * @param[in] handle The device handle received from #USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is stopped successfully. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid. + */ +extern usb_status_t USB_DeviceStop(usb_device_handle handle); + +/*! + * @brief De-initializes the device controller. + * + * The function de-initializes the device controller specified by the handle. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is stopped successfully. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid. + */ +extern usb_status_t USB_DeviceDeinit(usb_device_handle handle); + +/*! + * @brief Sends data through a specified endpoint. + * + * The function is used to send data through a specified endpoint. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint index. + * @param[in] buffer The memory address to hold the data need to be sent. The function is not reentrant. + * @param[in] length The data length need to be sent. + * + * @retval kStatus_USB_Success The send request is sent successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_Busy Cannot allocate DTDS for current transfer in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error The device is doing reset. + * + * @note The return value indicates whether the sending request is successful or not. The transfer done is notified by + * the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue on the application level. + * The subsequent transfer can begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +extern usb_status_t USB_DeviceSendRequest(usb_device_handle handle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! + * @brief Receives data through a specified endpoint. + * + * The function is used to receive data through a specified endpoint. The function is not reentrant. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint index. + * @param[in] buffer The memory address to save the received data. + * @param[in] length The data length want to be received. + * + * @retval kStatus_USB_Success The receive request is sent successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_Busy Cannot allocate DTDS for current transfer in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error The device is doing reset. + * + * @note The return value indicates whether the receiving request is successful or not. The transfer done is notified by + * the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue on the application level. + * The subsequent transfer can begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +extern usb_status_t USB_DeviceRecvRequest(usb_device_handle handle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! + * @brief Cancels the pending transfer in a specified endpoint. + * + * The function is used to cancel the pending transfer in a specified endpoint. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT. + * + * @retval kStatus_USB_Success The transfer is cancelled. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer or the controller handle is invalid. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +extern usb_status_t USB_DeviceCancel(usb_device_handle handle, uint8_t endpointAddress); + +/*! + * @brief Initializes a specified endpoint. + * + * The function is used to initialize a specified endpoint. The corresponding endpoint callback is also initialized. + * + * @param[in] handle The device handle received from #USB_DeviceInit. + * @param[in] epInit Endpoint initialization structure. See the structure usb_device_endpoint_init_struct_t. + * @param[in] epCallback Endpoint callback structure. See the structure + * usb_device_endpoint_callback_struct_t. + * + * @retval kStatus_USB_Success The endpoint is initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The epInit or epCallback is NULL pointer. Or the endpoint number is + * more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +extern usb_status_t USB_DeviceInitEndpoint(usb_device_handle handle, + usb_device_endpoint_init_struct_t *epInit, + usb_device_endpoint_callback_struct_t *epCallback); + +/*! + * @brief Deinitializes a specified endpoint. + * + * The function is used to deinitializes a specified endpoint. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is de-initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +extern usb_status_t USB_DeviceDeinitEndpoint(usb_device_handle handle, uint8_t endpointAddress); + +/*! + * @brief Stalls a specified endpoint. + * + * The function is used to stall a specified endpoint. + * + * @param[in] handle The device handle received from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is stalled successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +extern usb_status_t USB_DeviceStallEndpoint(usb_device_handle handle, uint8_t endpointAddress); + +/*! + * @brief Un-stall a specified endpoint. + * + * The function is used to unstall a specified endpoint. + * + * @param[in] handle The device handle received from #USB_DeviceInit. + * @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is un-stalled successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +extern usb_status_t USB_DeviceUnstallEndpoint(usb_device_handle handle, uint8_t endpointAddress); + +/*! + * @brief Gets the status of the selected item. + * + * The function is used to get the status of the selected item. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] type The selected item. See the structure #usb_device_status_t. + * @param[out] param The parameter type is determined by the selected item. + * + * @retval kStatus_USB_Success Get status successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The parameter is NULL pointer. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error Unsupported type. + */ +extern usb_status_t USB_DeviceGetStatus(usb_device_handle handle, usb_device_status_t type, void *param); + +/*! + * @brief Sets the status of the selected item. + * + * The function is used to set the status of the selected item. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] type The selected item. See the structure #usb_device_status_t. + * @param[in] param The parameter type is determined by the selected item. + * + * @retval kStatus_USB_Success Set status successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error Unsupported type or the parameter is NULL pointer. + */ +extern usb_status_t USB_DeviceSetStatus(usb_device_handle handle, usb_device_status_t type, void *param); + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) +/*! + * @brief Initializes the device dcd module. + * + * The function initializes the device dcd module. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] time_param The time parameter used to config the dcd timing registers. + * + * @retval kStatus_USB_Success The device is run successfully. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + * + */ +extern usb_status_t USB_DeviceDcdInitModule(usb_device_handle handle, void *time_param); + +/*! + * @brief De-initializes the device dcd module. + * + * The function de-initializes the device dcd module specified by the handle. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is stopped successfully. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid. + */ +extern usb_status_t USB_DeviceDcdDeinitModule(usb_device_handle handle); +#endif +/*! + * @brief Device task function. + * + * The function is used to handle the controller message. + * This function should not be called in the application directly. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceTaskFunction(void *deviceHandle); + +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) +/*! + * @brief Device KHCI task function. + * + * The function is used to handle the KHCI controller message. + * In the bare metal environment, this function should be called periodically in the main function. + * In the RTOS environment, this function should be used as a function entry to create a task. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +#define USB_DeviceKhciTaskFunction(deviceHandle) USB_DeviceTaskFunction(deviceHandle) +#endif + +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) +/*! + * @brief Device EHCI task function. + * + * The function is used to handle the EHCI controller message. + * In the bare metal environment, this function should be called periodically in the main function. + * In the RTOS environment, this function should be used as a function entry to create a task. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +#define USB_DeviceEhciTaskFunction(deviceHandle) USB_DeviceTaskFunction(deviceHandle) +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) +/*! + * @brief Device EHCI DCD ISR function. + * + * The function is the EHCI DCD interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceDcdHSIsrFunction(void *deviceHandle); +#endif +#endif + +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +/*! + * @brief Device LPC ip3511 controller task function. + * + * The function is used to handle the LPC ip3511 controller message. + * In the bare metal environment, this function should be called periodically in the main function. + * In the RTOS environment, this function should be used as a function entry to create a task. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +#define USB_DeviceLpcIp3511TaskFunction(deviceHandle) USB_DeviceTaskFunction(deviceHandle) +#endif + +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) +/*! + * @brief Device KHCI ISR function. + * + * The function is the KHCI interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceKhciIsrFunction(void *deviceHandle); +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) +/*! + * @brief Device KHCI DCD ISR function. + * + * The function is the KHCI DCD interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceDcdIsrFunction(void *deviceHandle); +#endif +#endif + +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) +/*! + * @brief Device EHCI ISR function. + * + * The function is the EHCI interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceEhciIsrFunction(void *deviceHandle); +#endif + +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +/*! + * @brief Device LPC USB ISR function. + * + * The function is the LPC USB interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceLpcIp3511IsrFunction(void *deviceHandle); +#endif + +#if (((defined(USB_DEVICE_CONFIG_DWC3)) && (USB_DEVICE_CONFIG_DWC3 > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_DWC3)) && (USB_DEVICE_CONFIG_DWC3 > 0U))) +/*! + * @brief Device USB DWC3 ISR function. + * + * The function is the USB interrupt service routine. + * + * @param[in] deviceHandle The device handle got from #USB_DeviceInit. + */ +extern void USB_DeviceDwc3IsrFunction(void *deviceHandle); +#endif + +/*! + * @brief Gets the device stack version function. + * + * The function is used to get the device stack version. + * + * @param[out] version The version structure pointer to keep the device stack version. + * + */ +extern void USB_DeviceGetVersion(uint32_t *version); + +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) +/*! + * @brief Update the hardware tick. + * + * The function is used to update the hardware tick. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] tick Current hardware tick(uint is ms). + * + */ +extern usb_status_t USB_DeviceUpdateHwTick(usb_device_handle handle, uint64_t tick); +#endif + +/*! @}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/*! @}*/ + +#endif /* __USB_DEVICE_H__ */ diff --git a/usb/device/source/ehci/usb_device_ehci.c b/usb/device/source/ehci/usb_device_ehci.c new file mode 100644 index 0000000..ced89f3 --- /dev/null +++ b/usb/device/source/ehci/usb_device_ehci.c @@ -0,0 +1,1856 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb_device_config.h" +#include "fsl_device_registers.h" +#include "usb.h" +#include "usb_device.h" +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) + +#include "usb_device_dci.h" + +#include "usb_device_ehci.h" +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +#include "usb_phy.h" +#endif + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#if defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM > 0U) + +#error The SOC does not suppoort dedicated RAM case. + +#endif + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +static void USB_DeviceEhciSetDefaultState(usb_device_ehci_state_struct_t *ehciState); +static usb_status_t USB_DeviceEhciEndpointInit(usb_device_ehci_state_struct_t *ehciState, + usb_device_endpoint_init_struct_t *epInit); +static usb_status_t USB_DeviceEhciEndpointDeinit(usb_device_ehci_state_struct_t *ehciState, uint8_t ep); +static usb_status_t USB_DeviceEhciEndpointStall(usb_device_ehci_state_struct_t *ehciState, uint8_t ep); +static usb_status_t USB_DeviceEhciEndpointUnstall(usb_device_ehci_state_struct_t *ehciState, uint8_t ep); +static void USB_DeviceEhciFillSetupBuffer(usb_device_ehci_state_struct_t *ehciState, uint8_t ep); +static void USB_DeviceEhciCancelControlPipe(usb_device_ehci_state_struct_t *ehciState, + uint8_t endpoint, + uint8_t direction); +static void USB_DeviceEhciInterruptTokenDone(usb_device_ehci_state_struct_t *ehciState); +static void USB_DeviceEhciInterruptPortChange(usb_device_ehci_state_struct_t *ehciState); +static void USB_DeviceEhciInterruptReset(usb_device_ehci_state_struct_t *ehciState); +static void USB_DeviceEhciInterruptSof(usb_device_ehci_state_struct_t *ehciState); +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +static void USB_DeviceEhciInterruptSuspend(usb_device_ehci_state_struct_t *ehciState); +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ +static usb_status_t USB_DeviceEhciTransfer(usb_device_ehci_state_struct_t *ehciState, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +extern usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Apply for QH buffer, 2048-byte alignment */ +USB_RAM_ADDRESS_ALIGNMENT(2048) +USB_CONTROLLER_DATA static uint8_t qh_buffer[(USB_DEVICE_CONFIG_EHCI - 1) * 2048 + + 2 * USB_DEVICE_CONFIG_ENDPOINTS * 2 * sizeof(usb_device_ehci_qh_struct_t)]; + +/* Apply for DTD buffer, 32-byte alignment */ +USB_RAM_ADDRESS_ALIGNMENT(32) +USB_CONTROLLER_DATA static usb_device_ehci_dtd_struct_t + s_UsbDeviceEhciDtd[USB_DEVICE_CONFIG_EHCI][USB_DEVICE_CONFIG_EHCI_MAX_DTD]; + +/* Apply for ehci device state structure */ +static usb_device_ehci_state_struct_t g_UsbDeviceEhciState[USB_DEVICE_CONFIG_EHCI]; + +/* Apply for whether the corresponding g_UsbDeviceEhciState is used or not, if used, it is set to 1, if not used, it is set to 0 */ +static uint8_t g_UsbDeviceEhciStateStatus[USB_DEVICE_CONFIG_EHCI]= {0}; + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) +/* Apply for device dcd state structure */ +static usb_device_dcd_state_struct_t s_UsbDeviceDcdHSState[USB_DEVICE_CONFIG_EHCI]; +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +/*! + * @brief EHCI NC get USB NC bass address. + * + * This function is used to get USB NC bass address. + * + * @param[in] controllerId EHCI controller ID; See the #usb_controller_index_t. + * + * @retval USB NC bass address. + */ +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) +void *USB_EhciNCGetBase(uint8_t controllerId) +{ + void *usbNCBase = NULL; +#if ((defined FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + uint32_t instance; + uint32_t newinstance = 0; + uint32_t usbnc_base_temp[] = USBNC_BASE_ADDRS; + uint32_t usbnc_base[] = USBNC_BASE_ADDRS; + + if (controllerId < kUSB_ControllerEhci0) + { + return NULL; + } + + controllerId = controllerId - kUSB_ControllerEhci0; + + for (instance = 0; instance < (sizeof(usbnc_base_temp) / sizeof(usbnc_base_temp[0])); instance++) + { + if (usbnc_base_temp[instance]) + { + usbnc_base[newinstance++] = usbnc_base_temp[instance]; + } + } + if (controllerId > newinstance) + { + return NULL; + } + + usbNCBase = (void *)usbnc_base[controllerId]; +#endif + return usbNCBase; +} +#endif +#endif + +/*! + * @brief Set device controller state to default state. + * + * The function is used to set device controller state to default state. + * The function will be called when USB_DeviceEhciInit called or the control type kUSB_DeviceControlGetEndpointStatus + * received in USB_DeviceEhciControl. + * + * @param ehciState Pointer of the device EHCI state structure. + * + */ +static void USB_DeviceEhciSetDefaultState(usb_device_ehci_state_struct_t *ehciState) +{ + usb_device_ehci_dtd_struct_t *p; + + /* Initialize the dtd free queue */ + ehciState->dtdFree = ehciState->dtd; + p = ehciState->dtdFree; + for (uint32_t i = 1U; i < USB_DEVICE_CONFIG_EHCI_MAX_DTD; i++) + { + p->nextDtdPointer = (uint32_t)&ehciState->dtd[i]; + p = (usb_device_ehci_dtd_struct_t *)p->nextDtdPointer; + } + p->nextDtdPointer = 0U; + ehciState->dtdCount = USB_DEVICE_CONFIG_EHCI_MAX_DTD; + + /* Not use interrupt threshold. */ + ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_ITC_MASK; + ehciState->registerBase->USBCMD |= USBHS_USBCMD_ITC(0U); + + /* Disable setup lockout, please refer to "Control Endpoint Operation" section in RM. */ + ehciState->registerBase->USBMODE |= USBHS_USBMODE_SLOM_MASK; + +/* Set the endian by using CPU's endian */ +#if (ENDIANNESS == USB_BIG_ENDIAN) + ehciState->registerBase->USBMODE |= USBHS_USBMODE_ES_MASK; +#else + ehciState->registerBase->USBMODE &= ~USBHS_USBMODE_ES_MASK; +#endif + /* Initialize the QHs of endpoint. */ + for (uint32_t i = 0U; i < (USB_DEVICE_CONFIG_ENDPOINTS * 2U); i++) + { + ehciState->qh[i].nextDtdPointer = USB_DEVICE_ECHI_DTD_TERMINATE_MASK; + ehciState->qh[i].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.maxPacketSize = + USB_CONTROL_MAX_PACKET_SIZE; + ehciState->dtdHard[i] = NULL; + ehciState->dtdTail[i] = NULL; + ehciState->qh[i].endpointStatusUnion.endpointStatusBitmap.isOpened = 0U; + } + + /* Add QH buffer address to USBHS_EPLISTADDR_REG */ + ehciState->registerBase->EPLISTADDR = (uint32_t)ehciState->qh; + + /* Clear device address */ + ehciState->registerBase->DEVICEADDR = 0U; + +#if defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U) + ehciState->registerBase->OTGSC = ehciState->registerBase->OTGSC & 0x0000FFFF; + ehciState->registerBase->OTGSC |= USBHS_OTGSC_BSVIE_MASK; +#endif /* USB_DEVICE_CONFIG_DETACH_ENABLE */ + + /* Enable USB Interrupt, USB Error Interrupt, Port Change detect Interrupt, USB-Reset Interrupt*/ + ehciState->registerBase->USBINTR = + (USBHS_USBINTR_UE_MASK | USBHS_USBINTR_UEE_MASK | USBHS_USBINTR_PCE_MASK | USBHS_USBINTR_URE_MASK +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + | USBHS_USBINTR_SLE_MASK +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ + ); + + /* Clear reset flag */ + ehciState->isResetting = 0U; +} + +/*! + * @brief Initialize a specified endpoint. + * + * The function is used to initialize a specified endpoint. + * + * @param ehciState Pointer of the device EHCI state structure. + * @param epInit The endpoint initialization structure pointer. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceEhciEndpointInit(usb_device_ehci_state_struct_t *ehciState, + usb_device_endpoint_init_struct_t *epInit) +{ + uint32_t primeBit = 1U << ((epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK) + + ((epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> 0x03U)); + uint16_t maxPacketSize = epInit->maxPacketSize & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK; + uint8_t endpoint = (epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK); + uint8_t direction = (epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | direction; + uint8_t transferType = epInit->transferType & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK; + + /* Cancel pending transfer of the endpoint */ + USB_DeviceEhciCancel(ehciState, epInit->endpointAddress); + + if ((ehciState->registerBase->EPPRIME & primeBit) || (ehciState->registerBase->EPSR & primeBit)) + { + return kStatus_USB_Busy; + } + + /* Make the endpoint max packet size align with USB Specification 2.0. */ + if (USB_ENDPOINT_ISOCHRONOUS == transferType) + { + if (maxPacketSize > USB_DEVICE_MAX_HS_ISO_MAX_PACKET_SIZE) + { + maxPacketSize = USB_DEVICE_MAX_HS_ISO_MAX_PACKET_SIZE; + } + ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.mult = + 1U + ((epInit->maxPacketSize & USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK) >> + USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_SHFIT); + } + else + { + ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.mult = 0U; + } + + /* Save the max packet size of the endpoint */ + ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.maxPacketSize = + maxPacketSize; + ehciState->qh[index].endpointStatusUnion.endpointStatusBitmap.zlt = epInit->zlt; + if ((USB_CONTROL_ENDPOINT == endpoint)) + { + /* Set ZLT bit. disable control endpoint automatic zlt by default,only send zlt when it is needed*/ + ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.zlt = 1U; + } + else + { + /* Set ZLT bit. */ + ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.zlt = !epInit->zlt; + } + + /* Enable the endpoint. */ + if (USB_ENDPOINT_CONTROL == transferType) + { + ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.ios = 1U; + ehciState->registerBase->EPCR0 |= + (direction ? + (USBHS_EPCR_TXE_MASK | USBHS_EPCR_TXR_MASK | ((uint32_t)transferType << USBHS_EPCR_TXT_SHIFT)) : + (USBHS_EPCR_RXE_MASK | USBHS_EPCR_RXR_MASK | ((uint32_t)transferType << USBHS_EPCR_RXT_SHIFT))); + } + else + { + ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.ios = 0U; + ehciState->registerBase->EPCR[endpoint - 1U] |= + (direction ? + (USBHS_EPCR_TXE_MASK | USBHS_EPCR_TXR_MASK | ((uint32_t)transferType << USBHS_EPCR_TXT_SHIFT)) : + (USBHS_EPCR_RXE_MASK | USBHS_EPCR_RXR_MASK | ((uint32_t)transferType << USBHS_EPCR_RXT_SHIFT))); + } + + ehciState->qh[index].endpointStatusUnion.endpointStatusBitmap.isOpened = 1U; + return kStatus_USB_Success; +} + +/*! + * @brief De-initialize a specified endpoint. + * + * The function is used to de-initialize a specified endpoint. + * Current transfer of the endpoint will be cancelled and the specified endpoint will be disabled. + * + * @param ehciState Pointer of the device EHCI state structure. + * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceEhciEndpointDeinit(usb_device_ehci_state_struct_t *ehciState, uint8_t ep) +{ + uint32_t primeBit = + 1U << ((ep & USB_ENDPOINT_NUMBER_MASK) + ((ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> 0x03U)); + uint8_t endpoint = (ep & USB_ENDPOINT_NUMBER_MASK); + uint8_t direction = + (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | direction; + + ehciState->qh[index].endpointStatusUnion.endpointStatusBitmap.isOpened = 0U; + + /* Cancel the transfer of the endpoint */ + USB_DeviceEhciCancel(ehciState, ep); + + if ((ehciState->registerBase->EPPRIME & primeBit) || (ehciState->registerBase->EPSR & primeBit)) + { + return kStatus_USB_Busy; + } + + /* Clear endpoint state */ + ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristics = 0U; + /* Disable the endpoint */ + if (!endpoint) + { + ehciState->registerBase->EPCR0 &= + ~(direction ? (USBHS_EPCR_TXE_MASK | USBHS_EPCR_TXT_MASK) : (USBHS_EPCR_RXE_MASK | USBHS_EPCR_RXT_MASK)); + } + else + { + ehciState->registerBase->EPCR[endpoint - 1U] &= + ~(direction ? (USBHS_EPCR_TXE_MASK | USBHS_EPCR_TXT_MASK) : (USBHS_EPCR_RXE_MASK | USBHS_EPCR_RXT_MASK)); + } + + return kStatus_USB_Success; +} + +/*! + * @brief Stall a specified endpoint. + * + * The function is used to stall a specified endpoint. + * Current transfer of the endpoint will be cancelled and the specified endpoint will be stalled. + * + * @param ehciState Pointer of the device EHCI state structure. + * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceEhciEndpointStall(usb_device_ehci_state_struct_t *ehciState, uint8_t ep) +{ + uint8_t endpoint = ep & USB_ENDPOINT_NUMBER_MASK; + uint8_t direction = + (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | direction; + + /* Cancel the transfer of the endpoint */ + USB_DeviceEhciCancel(ehciState, ep); + + /* Set endpoint stall flag. */ + if (ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.ios) + { + if (!endpoint) + { + ehciState->registerBase->EPCR0 |= (USBHS_EPCR_TXS_MASK | USBHS_EPCR_RXS_MASK); + } + else + { + ehciState->registerBase->EPCR[endpoint - 1U] |= (USBHS_EPCR_TXS_MASK | USBHS_EPCR_RXS_MASK); + } + } + else + { + if (!endpoint) + { + ehciState->registerBase->EPCR0 |= (direction ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK); + } + else + { + ehciState->registerBase->EPCR[endpoint - 1U] |= (direction ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK); + } + } + + return kStatus_USB_Success; +} + +/*! + * @brief Un-stall a specified endpoint. + * + * The function is used to un-stall a specified endpoint. + * Current transfer of the endpoint will be cancelled and the specified endpoint will be un-stalled. + * + * @param ehciState Pointer of the device EHCI state structure. + * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceEhciEndpointUnstall(usb_device_ehci_state_struct_t *ehciState, uint8_t ep) +{ + uint8_t endpoint = ep & USB_ENDPOINT_NUMBER_MASK; + uint8_t direction = + (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + + /* Clear the endpoint stall state */ + if (!endpoint) + { + ehciState->registerBase->EPCR0 &= ~(direction ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK); + } + else + { + ehciState->registerBase->EPCR[endpoint - 1U] &= ~(direction ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK); + ehciState->registerBase->EPCR[endpoint - 1U] |= (direction ? USBHS_EPCR_TXR_MASK : USBHS_EPCR_RXR_MASK); + } + /* Cancel the transfer of the endpoint */ + USB_DeviceEhciCancel(ehciState, ep); + + return kStatus_USB_Success; +} + +/*! + * @brief Get setup packet data. + * + * The function is used to get setup packet data and copy to a backup buffer. + * + * @param ehciState Pointer of the device EHCI state structure. + * @param ep The endpoint number. + * + */ +static void USB_DeviceEhciFillSetupBuffer(usb_device_ehci_state_struct_t *ehciState, uint8_t ep) +{ + uint8_t waitingSafelyAccess = 1U; + uint8_t index = (ep * 2U) | USB_OUT; + + /* Write 1U to clear corresponding bit in EPSETUPSR. */ + ehciState->registerBase->EPSETUPSR = 1U << ep; + + while (waitingSafelyAccess) + { + /* Set the setup tripwire bit. */ + ehciState->registerBase->USBCMD |= USBHS_USBCMD_SUTW_MASK; + + /* Copy setup packet data to backup buffer */ + ehciState->qh[index].setupBufferBack[0] = ehciState->qh[index].setupBuffer[0]; + ehciState->qh[index].setupBufferBack[1] = ehciState->qh[index].setupBuffer[1]; + + /* Read the USBCMD[SUTW] bit. If set, jump out from the while loop; if cleared continue */ + if (ehciState->registerBase->USBCMD & USBHS_USBCMD_SUTW_MASK) + { + waitingSafelyAccess = 0U; + } + } + /* Clear the setup tripwire bit */ + ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_SUTW_MASK; +} + +/*! + * @brief Cancel the transfer of the control pipe. + * + * The function is used to cancel the transfer of the control pipe. + * + * @param ehciState Pointer of the device EHCI state structure. + * @param endpoint The endpoint number. + * @param direction The direction of the endpoint. + * + */ +static void USB_DeviceEhciCancelControlPipe(usb_device_ehci_state_struct_t *ehciState, + uint8_t endpoint, + uint8_t direction) +{ + usb_device_ehci_dtd_struct_t *currentDtd; + uint32_t index = ((uint32_t)endpoint << 1U) + (uint32_t)direction; + usb_device_callback_message_struct_t message; + + message.buffer = NULL; + message.length = 0U; + /* Get the dtd of the control pipe */ + currentDtd = + (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK); + while (currentDtd) + { + /* Pass the transfer buffer address */ + if (NULL == message.buffer) + { + uint32_t bufferAddress = currentDtd->bufferPointerPage[0]; + message.buffer = (uint8_t *)((bufferAddress & USB_DEVICE_ECHI_DTD_PAGE_MASK) | + (currentDtd->reservedUnion.originalBufferInfo.originalBufferOffest)); + } + /* If the dtd is active, set the message length to USB_UNINITIALIZED_VAL_32. Or set the length by using finished + * length. */ + if (currentDtd->dtdTokenUnion.dtdTokenBitmap.status & USB_DEVICE_ECHI_DTD_STATUS_ACTIVE) + { + message.length = USB_UNINITIALIZED_VAL_32; + } + else + { + message.length += (currentDtd->reservedUnion.originalBufferInfo.originalBufferLength - + currentDtd->dtdTokenUnion.dtdTokenBitmap.totalBytes); + } + + /* Move the dtd head pointer to next. */ + /* If the pointer of the head equals to the tail, set the dtd queue to null. */ + if (ehciState->dtdHard[index] == ehciState->dtdTail[index]) + { + ehciState->dtdHard[index] = NULL; + ehciState->dtdTail[index] = NULL; + ehciState->qh[index].nextDtdPointer = USB_DEVICE_ECHI_DTD_TERMINATE_MASK; + ehciState->qh[index].dtdTokenUnion.dtdToken = 0U; + } + else + { + ehciState->dtdHard[index] = (usb_device_ehci_dtd_struct_t *)ehciState->dtdHard[index]->nextDtdPointer; + } + + /* When the ioc is set or the dtd queue is empty, the up layer will be notified. */ + if ((currentDtd->dtdTokenUnion.dtdTokenBitmap.ioc) || + (0 == ((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK))) + { + message.code = endpoint | (uint8_t)((uint32_t)direction << 0x07U); + message.isSetup = 0U; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + message.buffer = NULL; + message.length = 0U; + } + + /* Clear the token field of the dtd. */ + currentDtd->dtdTokenUnion.dtdToken = 0U; + /* Add the dtd to the free dtd queue. */ + currentDtd->nextDtdPointer = (uint32_t)ehciState->dtdFree; + ehciState->dtdFree = currentDtd; + ehciState->dtdCount++; + + /* Get the next in-used dtd. */ + currentDtd = + (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK); + } +} + +/*! + * @brief Handle the endpoint token done interrupt. + * + * The function is used to handle the endpoint token done interrupt. + * + * @param ehciState Pointer of the device EHCI state structure. + * + */ +static void USB_DeviceEhciInterruptTokenDone(usb_device_ehci_state_struct_t *ehciState) +{ + uint32_t status; + uint32_t primeBit; + usb_device_ehci_dtd_struct_t *currentDtd; + usb_device_callback_message_struct_t message; + uint8_t endpoint; + uint8_t direction; + uint8_t count; + uint8_t index; + + /* Get the EPSETUPSR to check the setup packect received in which one endpoint. */ + status = ehciState->registerBase->EPSETUPSR; + + if (status) + { + for (endpoint = 0U; endpoint < USB_DEVICE_CONFIG_ENDPOINTS; endpoint++) + { + /* Check the endpoint receive the setup packet. */ + if (status & (1U << endpoint)) + { + /* Get last setup packet */ + usb_setup_struct_t *deviceSetup = + (usb_setup_struct_t *)&ehciState->qh[(uint8_t)((uint32_t)endpoint << 1U) + USB_OUT].setupBufferBack; + + /* Check the direction of the data phase. */ + direction = (deviceSetup->bmRequestType & USB_REQUEST_TYPE_DIR_IN) >> USB_REQUEST_TYPE_DIR_SHIFT; + /* Cancel the data phase transfer */ + USB_DeviceEhciCancelControlPipe(ehciState, endpoint, direction); + /* Cancel the status phase transfer */ + USB_DeviceEhciCancelControlPipe(ehciState, endpoint, 1U ^ direction); + message.code = (endpoint) | (USB_OUT << 0x07U); + message.buffer = (uint8_t *)deviceSetup; + message.length = USB_SETUP_PACKET_SIZE; + message.isSetup = 1U; + /* Fill the setup packet to the backup buffer */ + USB_DeviceEhciFillSetupBuffer(ehciState, endpoint); + /* Notify the up layer the EHCI status changed. */ + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + } + } + } + /* Read the USBHS_EPCOMPLETE_REG to get the endpoint transfer done status */ + status = ehciState->registerBase->EPCOMPLETE; + /* Clear the endpoint transfer done status */ + ehciState->registerBase->EPCOMPLETE = status; + + if (status) + { + for (count = 0U; count < 32U; count++) + { + /* Check the transfer is done or not in the specified endpoint. */ + if (status & ((uint32_t)(1U << count))) + { + if (count > 15U) + { + endpoint = count - 16U; + direction = USB_IN; + } + else + { + endpoint = count; + direction = USB_OUT; + } + if (endpoint >= USB_DEVICE_CONFIG_ENDPOINTS) + { + continue; + } + index = (endpoint << 1U) + direction; + message.buffer = NULL; + message.length = 0U; + if ((USB_CONTROL_ENDPOINT == endpoint) && (USB_IN == direction)) + { + if (1U == ehciState->qh[index].endpointStatusUnion.endpointStatusBitmap.zlt) + { + if(!ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.zlt) + { + /*disable zlt after send zlt*/ + ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.zlt = 1U; + } + } + } + /* Get the in-used dtd of the specified endpoint. */ + currentDtd = (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & + USB_DEVICE_ECHI_DTD_POINTER_MASK); + while (currentDtd) + { + uint8_t isTokenDone = 0; + /* Get the in-used dtd of the specified endpoint. */ + currentDtd = (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & + USB_DEVICE_ECHI_DTD_POINTER_MASK); + + while (currentDtd) + { + /* Don't handle the active dtd. */ + if ((currentDtd->dtdTokenUnion.dtdTokenBitmap.status & USB_DEVICE_ECHI_DTD_STATUS_ACTIVE) || + (currentDtd->dtdTokenUnion.dtdTokenBitmap.ioc)) + { + if ((!(currentDtd->dtdTokenUnion.dtdTokenBitmap.status & + USB_DEVICE_ECHI_DTD_STATUS_ACTIVE)) && + (currentDtd->dtdTokenUnion.dtdTokenBitmap.ioc)) + { + isTokenDone = 1U; + } + break; + } + currentDtd = (usb_device_ehci_dtd_struct_t *)(currentDtd->nextDtdPointer & + USB_DEVICE_ECHI_DTD_POINTER_MASK); + } + + if ((0 == isTokenDone) && (currentDtd)) + { + break; + } + + /* Get the in-used dtd of the specified endpoint. */ + currentDtd = (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & + USB_DEVICE_ECHI_DTD_POINTER_MASK); + while (currentDtd) + { + /* Don't handle the active dtd. */ + if (currentDtd->dtdTokenUnion.dtdTokenBitmap.status & USB_DEVICE_ECHI_DTD_STATUS_ACTIVE) + { + break; + } + + /* Save the transfer buffer address */ + if (NULL == message.buffer) + { + message.buffer = + (uint8_t *)((currentDtd->bufferPointerPage[0] & USB_DEVICE_ECHI_DTD_PAGE_MASK) | + (currentDtd->reservedUnion.originalBufferInfo.originalBufferOffest)); + } + /* Save the transferred data length */ + message.length += (currentDtd->reservedUnion.originalBufferInfo.originalBufferLength - + currentDtd->dtdTokenUnion.dtdTokenBitmap.totalBytes); + + /* Move the dtd queue head pointer to next */ + if (ehciState->dtdHard[index] == ehciState->dtdTail[index]) + { + ehciState->dtdHard[index] = NULL; + ehciState->dtdTail[index] = NULL; + ehciState->qh[index].nextDtdPointer = USB_DEVICE_ECHI_DTD_TERMINATE_MASK; + ehciState->qh[index].dtdTokenUnion.dtdToken = 0U; + } + else + { + ehciState->dtdHard[index] = + (usb_device_ehci_dtd_struct_t *)ehciState->dtdHard[index]->nextDtdPointer; + } + + /* When the ioc is set or the dtd queue is empty, the up layer will be notified. */ + if ((currentDtd->dtdTokenUnion.dtdTokenBitmap.ioc) || + (0 == ((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK))) + { + message.code = endpoint | (uint8_t)((uint32_t)direction << 0x07U); + message.isSetup = 0U; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + message.buffer = NULL; + message.length = 0U; + } + /* Clear the token field of the dtd */ + currentDtd->dtdTokenUnion.dtdToken = 0U; + currentDtd->nextDtdPointer = (uint32_t)ehciState->dtdFree; + ehciState->dtdFree = currentDtd; + ehciState->dtdCount++; + /* Get the next in-used dtd */ + currentDtd = (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & + USB_DEVICE_ECHI_DTD_POINTER_MASK); + + if ((NULL != currentDtd) && + (currentDtd->dtdTokenUnion.dtdTokenBitmap.status & USB_DEVICE_ECHI_DTD_STATUS_ACTIVE)) + { + primeBit = 1U << (endpoint + 16U * direction); + + /* Try to prime the next dtd. */ + ehciState->registerBase->EPPRIME = primeBit; + + /* Whether the endpoint transmit/receive buffer is ready or not. If not, wait for prime bit + * cleared and prime the next dtd. */ + if (!(ehciState->registerBase->EPSR & primeBit)) + { + /* Wait for the endpoint prime bit cleared by HW */ + while (ehciState->registerBase->EPPRIME & primeBit) + { + } + + /* If the endpoint transmit/receive buffer is not ready */ + if (!(ehciState->registerBase->EPSR & primeBit)) + { + /* Prime next dtd and prime the transfer */ + ehciState->qh[index].nextDtdPointer = (uint32_t)currentDtd; + ehciState->qh[index].dtdTokenUnion.dtdToken = 0U; + ehciState->registerBase->EPPRIME = primeBit; + } + } + } + } + } + } + } + } +} + +/*! + * @brief Handle the port status change interrupt. + * + * The function is used to handle the port status change interrupt. + * + * @param ehciState Pointer of the device EHCI state structure. + * + */ +static void USB_DeviceEhciInterruptPortChange(usb_device_ehci_state_struct_t *ehciState) +{ + usb_device_callback_message_struct_t message; + + message.buffer = (uint8_t *)NULL; + message.length = 0U; + message.isSetup = 0U; + + /* Whether the port is doing reset. */ + if (!(ehciState->registerBase->PORTSC1 & USBHS_PORTSC1_PR_MASK)) + { + /* If not, update the USB speed. */ + if (ehciState->registerBase->PORTSC1 & USBHS_PORTSC1_HSP_MASK) + { + ehciState->speed = USB_SPEED_HIGH; + } + else + { + ehciState->speed = USB_SPEED_FULL; + } + + /* If the device reset flag is non-zero, notify the up layer the device reset finished. */ + if (ehciState->isResetting) + { + message.code = kUSB_DeviceNotifyBusReset; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + ehciState->isResetting = 0U; + } + } + +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + if ((ehciState->isSuspending) && (!(ehciState->registerBase->PORTSC1 & USBHS_PORTSC1_SUSP_MASK))) + { + /* Set the resume flag */ + ehciState->isSuspending = 0U; + + message.code = kUSB_DeviceNotifyResume; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + } +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ +} + +/*! + * @brief Handle the reset interrupt. + * + * The function is used to handle the reset interrupt. + * + * @param ehciState Pointer of the device EHCI state structure. + * + */ +static void USB_DeviceEhciInterruptReset(usb_device_ehci_state_struct_t *ehciState) +{ + uint32_t status = 0U; + + /* Clear the setup flag */ + status = ehciState->registerBase->EPSETUPSR; + ehciState->registerBase->EPSETUPSR = status; + /* Clear the endpoint complete flag */ + status = ehciState->registerBase->EPCOMPLETE; + ehciState->registerBase->EPCOMPLETE = status; + + do + { + /* Flush the pending transfers */ + ehciState->registerBase->EPFLUSH = USBHS_EPFLUSH_FERB_MASK | USBHS_EPFLUSH_FETB_MASK; + } while (ehciState->registerBase->EPPRIME & (USBHS_EPPRIME_PERB_MASK | USBHS_EPPRIME_PETB_MASK)); + + /* Whether is the port reset. If yes, set the isResetting flag. Or, notify the up layer. */ + if (ehciState->registerBase->PORTSC1 & USBHS_PORTSC1_PR_MASK) + { + ehciState->isResetting = 1U; + } + else + { + usb_device_callback_message_struct_t message; + message.buffer = (uint8_t *)NULL; + message.code = kUSB_DeviceNotifyBusReset; + message.length = 0U; + message.isSetup = 0U; + + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + } +} + +/*! + * @brief Handle the sof interrupt. + * + * The function is used to handle the sof interrupt. + * + * @param ehciState Pointer of the device EHCI state structure. + * + */ +static void USB_DeviceEhciInterruptSof(usb_device_ehci_state_struct_t *ehciState) +{ +} + +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +/*! + * @brief Handle the suspend interrupt. + * + * The function is used to handle the suspend interrupt. + * + * @param ehciState Pointer of the device EHCI state structure. + * + */ +static void USB_DeviceEhciInterruptSuspend(usb_device_ehci_state_struct_t *ehciState) +{ + /* If the port is in suspend state, notify the up layer */ + if (ehciState->registerBase->PORTSC1 & USBHS_PORTSC1_SUSP_MASK) + { +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) +#else + if (ehciState->registerPhyBase->USB1_VBUS_DET_STAT & USBPHY_USB1_VBUS_DET_STAT_VBUS_VALID_3V_MASK) +#endif + { + usb_device_callback_message_struct_t message; + message.buffer = (uint8_t *)NULL; + message.length = 0U; + message.isSetup = 0U; + message.code = kUSB_DeviceNotifySuspend; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + } + } +} +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ + +/*! + * @brief Get dtds and link to QH. + * + * The function is used to get dtds and link to QH. + * + * @param ehciState Pointer of the device EHCI state structure. + * @param endpointAddress The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN. + * @param buffer The memory address needed to be transferred. + * @param length Data length. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceEhciTransfer(usb_device_ehci_state_struct_t *ehciState, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length) +{ + usb_device_ehci_dtd_struct_t *dtd; + usb_device_ehci_dtd_struct_t *dtdHard; + uint32_t index = ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) << 1U) | + ((endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT); + uint32_t primeBit = 1U << ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) + + ((endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> 0x03U)); + uint32_t epStatus = primeBit; + uint32_t sendLength; + uint32_t currentIndex = 0U; + uint32_t dtdRequestCount = (length + USB_DEVICE_ECHI_DTD_TOTAL_BYTES - 1U) / USB_DEVICE_ECHI_DTD_TOTAL_BYTES; + uint8_t qhIdle = 0U; + uint8_t waitingSafelyAccess = 1U; + uint32_t primeTimesCount = 0U; + USB_OSA_SR_ALLOC(); + + if (!ehciState) + { + return kStatus_USB_InvalidHandle; + } + + if (0U == ehciState->qh[index].endpointStatusUnion.endpointStatusBitmap.isOpened) + { + return kStatus_USB_Error; + } + /* Return error when ehci is doing reset */ + if (ehciState->isResetting) + { + return kStatus_USB_Error; + } + + if (!dtdRequestCount) + { + dtdRequestCount = 1U; + } + + USB_OSA_ENTER_CRITICAL(); + /* The free dtd count need to not less than the transfer requests. */ + if (dtdRequestCount > (uint32_t)ehciState->dtdCount) + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Busy; + } + + do + { + /* The transfer length need to not more than USB_DEVICE_ECHI_DTD_TOTAL_BYTES for each dtd. */ + if (length > USB_DEVICE_ECHI_DTD_TOTAL_BYTES) + { + sendLength = USB_DEVICE_ECHI_DTD_TOTAL_BYTES; + } + else + { + sendLength = length; + } + length -= sendLength; + + /* Get a free dtd */ + dtd = ehciState->dtdFree; + + ehciState->dtdFree = (usb_device_ehci_dtd_struct_t *)dtd->nextDtdPointer; + ehciState->dtdCount--; + + /* Save the dtd head when current active buffer offset is zero. */ + if (!currentIndex) + { + dtdHard = dtd; + } + + /* Set the dtd field */ + dtd->nextDtdPointer = USB_DEVICE_ECHI_DTD_TERMINATE_MASK; + dtd->dtdTokenUnion.dtdToken = 0U; + dtd->bufferPointerPage[0] = (uint32_t)(buffer + currentIndex); + dtd->bufferPointerPage[1] = + (dtd->bufferPointerPage[0] + USB_DEVICE_ECHI_DTD_PAGE_BLOCK) & USB_DEVICE_ECHI_DTD_PAGE_MASK; + dtd->bufferPointerPage[2] = dtd->bufferPointerPage[1] + USB_DEVICE_ECHI_DTD_PAGE_BLOCK; + dtd->bufferPointerPage[3] = dtd->bufferPointerPage[2] + USB_DEVICE_ECHI_DTD_PAGE_BLOCK; + dtd->bufferPointerPage[4] = dtd->bufferPointerPage[3] + USB_DEVICE_ECHI_DTD_PAGE_BLOCK; + + dtd->dtdTokenUnion.dtdTokenBitmap.totalBytes = sendLength; + + /* Save the data length needed to be transferred. */ + dtd->reservedUnion.originalBufferInfo.originalBufferLength = sendLength; + /* Save the original buffer address */ + dtd->reservedUnion.originalBufferInfo.originalBufferOffest = + dtd->bufferPointerPage[0] & USB_DEVICE_ECHI_DTD_PAGE_OFFSET_MASK; + dtd->reservedUnion.originalBufferInfo.dtdInvalid = 0U; + + /* Set the IOC field in last dtd. */ + if (!length) + { + dtd->dtdTokenUnion.dtdTokenBitmap.ioc = 1U; + } + + /* Set dtd active */ + dtd->dtdTokenUnion.dtdTokenBitmap.status = USB_DEVICE_ECHI_DTD_STATUS_ACTIVE; + + /* Move the buffer offset index */ + currentIndex += sendLength; + + /* Add dtd to the in-used dtd queue */ + if (ehciState->dtdTail[index]) + { + ehciState->dtdTail[index]->nextDtdPointer = (uint32_t)dtd; + ehciState->dtdTail[index] = dtd; + } + else + { + ehciState->dtdHard[index] = dtd; + ehciState->dtdTail[index] = dtd; + qhIdle = 1U; + } + } while (length); + if ((USB_CONTROL_ENDPOINT == (endpointAddress & USB_ENDPOINT_NUMBER_MASK)) && (USB_IN == ((endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))) + { + uint8_t setupindex = ((endpointAddress & USB_ENDPOINT_NUMBER_MASK)* 2U); + /* Get last setup packet */ + usb_setup_struct_t *deviceSetup = + (usb_setup_struct_t *)&ehciState->qh[setupindex].setupBufferBack[0]; + if (1U == ehciState->qh[index].endpointStatusUnion.endpointStatusBitmap.zlt) + { + if ((sendLength) && (sendLength < deviceSetup->wLength) && (!(sendLength % ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.maxPacketSize))) + { + /* enable ZLT. */ + ehciState->qh[index].capabilttiesCharacteristicsUnion.capabilttiesCharacteristicsBitmap.zlt = 0U; + } + } + } + /* If the QH is not empty */ + if (!qhIdle) + { + /* If the prime bit is set, nothing need to do. */ + if (ehciState->registerBase->EPPRIME & primeBit) + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + + /* To safely a dtd */ + while (waitingSafelyAccess) + { + /* set the ATDTW flag to USBHS_USBCMD_REG. */ + ehciState->registerBase->USBCMD |= USBHS_USBCMD_ATDTW_MASK; + /* Read EPSR */ + epStatus = ehciState->registerBase->EPSR; + /* Wait the ATDTW bit set */ + if (ehciState->registerBase->USBCMD & USBHS_USBCMD_ATDTW_MASK) + { + waitingSafelyAccess = 0U; + } + } + /* Clear the ATDTW bit */ + ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_ATDTW_MASK; + } + + /* If QH is empty or the endpoint is not primed, need to link current dtd head to the QH. */ + /* When the endpoint is not primed if qhIdle is zero, it means the QH is empty. */ + if ((qhIdle) || (!(epStatus & primeBit))) + { + ehciState->qh[index].nextDtdPointer = (uint32_t)dtdHard; + ehciState->qh[index].dtdTokenUnion.dtdToken = 0U; + ehciState->registerBase->EPPRIME = primeBit; + while (!(ehciState->registerBase->EPSR & primeBit)) + { + primeTimesCount++; + if (primeTimesCount == USB_DEVICE_MAX_TRANSFER_PRIME_TIMES) + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Error; + } + if (ehciState->registerBase->EPCOMPLETE & primeBit) + { + break; + } + else + { + ehciState->registerBase->EPPRIME = primeBit; + } + } + } + + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; +} + +/*! + * @brief Get a valid device EHCI state for the device EHCI instance. + * + * This function gets a valid device EHCI state for the USB device EHCI module specified by the controllerId. + * + * @param instanceIndex The instanceIndex is used for other EHCI device structure to identify their instance index. + * + * @return A valid EHCI state or NULL. + */ +void *USB_EhciGetValidEhciState(uint8_t *instanceIndex) +{ + for (uint8_t instance = 0; instance < USB_DEVICE_CONFIG_EHCI; instance++) + { + if (!g_UsbDeviceEhciStateStatus[instance]) + { + g_UsbDeviceEhciStateStatus[instance] = 1; + *instanceIndex = instance; + return &g_UsbDeviceEhciState[instance]; + } + } + return NULL; +} + +/*! + * @brief Initialize the USB device EHCI instance. + * + * This function initializes the USB device EHCI module specified by the controllerId. + * + * @param controllerId The controller id of the USB IP. Please refer to enumeration type usb_controller_index_t. + * @param handle Pointer of the device handle, used to identify the device object is belonged to. + * @param ehciHandle It is out parameter, is used to return pointer of the device EHCI handle to the caller. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceEhciInit(uint8_t controllerId, + usb_device_handle handle, + usb_device_controller_handle *ehciHandle) +{ + usb_device_ehci_state_struct_t *ehciState; + uint32_t ehci_base[] = USBHS_BASE_ADDRS; + uint8_t intanceIndex; + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) + usb_device_dcd_state_struct_t *dcdHSState; + uint32_t dcd_base[] = USBHSDCD_BASE_ADDRS; + usb_device_callback_message_struct_t message; +#endif + + if ((controllerId < kUSB_ControllerEhci0) || + ((uint32_t)(controllerId - kUSB_ControllerEhci0) >= (sizeof(ehci_base) / sizeof(uint32_t)))) + { + return kStatus_USB_ControllerNotFound; + } + + ehciState = USB_EhciGetValidEhciState(&intanceIndex); + + ehciState->dtd = s_UsbDeviceEhciDtd[intanceIndex]; + ehciState->qh = (usb_device_ehci_qh_struct_t *)&qh_buffer[intanceIndex * 2048]; + + ehciState->controllerId = controllerId; + + ehciState->registerBase = (USBHS_Type *)ehci_base[controllerId - kUSB_ControllerEhci0]; +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + ehciState->registerPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId); + +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + ehciState->registerNcBase = (USBNC_Type *)USB_EhciNCGetBase(controllerId); +#endif + +#endif + + /* Get the HW's endpoint count */ + ehciState->endpointCount = + (uint8_t)((ehciState->registerBase->DCCPARAMS & USBHS_DCCPARAMS_DEN_MASK) >> USBHS_DCCPARAMS_DEN_SHIFT); + + if (ehciState->endpointCount < USB_DEVICE_CONFIG_ENDPOINTS) + { + return kStatus_USB_Error; + } + ehciState->deviceHandle = (usb_device_struct_t *)handle; + + /* Clear the controller mode field and set to device mode. */ + ehciState->registerBase->USBMODE &= ~USBHS_USBMODE_CM_MASK; + ehciState->registerBase->USBMODE |= USBHS_USBMODE_CM(0x02U); + + /* Set the EHCI to default status. */ + USB_DeviceEhciSetDefaultState(ehciState); + *ehciHandle = (usb_device_controller_handle)ehciState; +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) + dcdHSState = &s_UsbDeviceDcdHSState[controllerId - kUSB_ControllerEhci0]; + + dcdHSState->controllerId = controllerId; + + dcdHSState->dcdRegisterBase = (USBHSDCD_Type *)dcd_base[controllerId - kUSB_ControllerEhci0]; + + dcdHSState->deviceHandle = (usb_device_struct_t *)handle; + + message.buffer = (uint8_t *)NULL; + message.length = 0U; + message.isSetup = 0U; + if (ehciState->registerBase->OTGSC & USBHS_OTGSC_BSV_MASK) + { + /* Device is connected to a host. */ + message.code = kUSB_DeviceNotifyAttach; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + } +#endif + + return kStatus_USB_Success; +} + +/*! + * @brief De-initialize the USB device EHCI instance. + * + * This function de-initializes the USB device EHCI module. + * + * @param ehciHandle Pointer of the device EHCI handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceEhciDeinit(usb_device_controller_handle ehciHandle) +{ + usb_device_ehci_state_struct_t *ehciState = (usb_device_ehci_state_struct_t *)ehciHandle; + + if (!ehciHandle) + { + return kStatus_USB_InvalidHandle; + } + for (uint8_t instance = 0; instance < USB_DEVICE_CONFIG_EHCI; instance++) + { + if (ehciState == &g_UsbDeviceEhciState[instance]) + { + g_UsbDeviceEhciStateStatus[instance] = 0; + } + } + + /* Disable all interrupt. */ + ehciState->registerBase->USBINTR = 0U; + /* Stop the device functionality. */ + ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_RS_MASK; + /* Reset the controller. */ + ehciState->registerBase->USBCMD |= USBHS_USBCMD_RST_MASK; + + return kStatus_USB_Success; +} + +/*! + * @brief Send data through a specified endpoint. + * + * This function sends data through a specified endpoint. + * + * @param ehciHandle Pointer of the device EHCI handle. + * @param endpointAddress Endpoint index. + * @param buffer The memory address to hold the data need to be sent. + * @param length The data length need to be sent. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value just means if the sending request is successful or not; the transfer done is notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceEhciSend(usb_device_controller_handle ehciHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length) +{ + /* Add dtd to the QH */ + return USB_DeviceEhciTransfer( + (usb_device_ehci_state_struct_t *)ehciHandle, + (endpointAddress & USB_ENDPOINT_NUMBER_MASK) | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT), + buffer, length); +} + +/*! + * @brief Receive data through a specified endpoint. + * + * This function Receives data through a specified endpoint. + * + * @param ehciHandle Pointer of the device EHCI handle. + * @param endpointAddress Endpoint index. + * @param buffer The memory address to save the received data. + * @param length The data length want to be received. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value just means if the receiving request is successful or not; the transfer done is notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceEhciRecv(usb_device_controller_handle ehciHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length) +{ + /* Add dtd to the QH */ + return USB_DeviceEhciTransfer( + (usb_device_ehci_state_struct_t *)ehciHandle, + (endpointAddress & USB_ENDPOINT_NUMBER_MASK) | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT), + buffer, length); +} + +/*! + * @brief Cancel the pending transfer in a specified endpoint. + * + * The function is used to cancel the pending transfer in a specified endpoint. + * + * @param ehciHandle Pointer of the device EHCI handle. + * @param ep Endpoint address, bit7 is the direction of endpoint, 1U - IN, 0U - OUT. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceEhciCancel(usb_device_controller_handle ehciHandle, uint8_t ep) +{ + usb_device_ehci_state_struct_t *ehciState = (usb_device_ehci_state_struct_t *)ehciHandle; + usb_device_callback_message_struct_t message; + usb_device_ehci_dtd_struct_t *currentDtd; + uint32_t primeBit = + 1U << ((ep & USB_ENDPOINT_NUMBER_MASK) + ((ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> 0x03U)); + uint8_t index = + ((ep & USB_ENDPOINT_NUMBER_MASK) << 1U) | ((ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> 0x07U); + + USB_OSA_SR_ALLOC(); + + if (!ehciHandle) + { + return kStatus_USB_InvalidHandle; + } + + USB_OSA_ENTER_CRITICAL(); + + message.buffer = NULL; + message.length = USB_UNINITIALIZED_VAL_32; + + /* Get the first dtd */ + currentDtd = + (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK); + + while (currentDtd) + { + currentDtd->reservedUnion.originalBufferInfo.dtdInvalid = 1U; + currentDtd = (usb_device_ehci_dtd_struct_t *)(currentDtd->nextDtdPointer & USB_DEVICE_ECHI_DTD_POINTER_MASK); + } + + /* Get the first dtd */ + currentDtd = + (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK); + while (currentDtd) + { + if (!currentDtd->reservedUnion.originalBufferInfo.dtdInvalid) + { + break; + } + else + { + if (currentDtd->dtdTokenUnion.dtdTokenBitmap.status & USB_DEVICE_ECHI_DTD_STATUS_ACTIVE) + { + /* Flush the endpoint to stop a transfer. */ + do + { + /* Set the corresponding bit(s) in the EPFLUSH register */ + ehciState->registerBase->EPFLUSH |= primeBit; + + /* Wait until all bits in the EPFLUSH register are cleared. */ + while (ehciState->registerBase->EPFLUSH & primeBit) + { + } + /* + * Read the EPSR register to ensure that for all endpoints + * commanded to be flushed, that the corresponding bits + * are now cleared. + */ + } while (ehciState->registerBase->EPSR & primeBit); + } + + /* Save the original buffer address. */ + if (NULL == message.buffer) + { + message.buffer = (uint8_t *)((currentDtd->bufferPointerPage[0] & USB_DEVICE_ECHI_DTD_PAGE_MASK) | + (currentDtd->reservedUnion.originalBufferInfo.originalBufferOffest)); + } + + /* Remove the dtd from the dtd in-used queue. */ + if (ehciState->dtdHard[index] == ehciState->dtdTail[index]) + { + ehciState->dtdHard[index] = NULL; + ehciState->dtdTail[index] = NULL; + } + else + { + ehciState->dtdHard[index] = (usb_device_ehci_dtd_struct_t *)ehciState->dtdHard[index]->nextDtdPointer; + } + + /* When the ioc is set or the dtd queue is empty, the up layer will be notified. */ + if ((currentDtd->dtdTokenUnion.dtdTokenBitmap.ioc) || + (0 == ((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK))) + { + message.code = ep; + message.isSetup = 0U; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + message.buffer = NULL; + } + /* Clear the token field. */ + currentDtd->dtdTokenUnion.dtdToken = 0U; + /* Save the dtd to the free queue. */ + currentDtd->nextDtdPointer = (uint32_t)ehciState->dtdFree; + ehciState->dtdFree = currentDtd; + ehciState->dtdCount++; + } + /* Get the next dtd. */ + currentDtd = + (usb_device_ehci_dtd_struct_t *)((uint32_t)ehciState->dtdHard[index] & USB_DEVICE_ECHI_DTD_POINTER_MASK); + } + if (!currentDtd) + { + /* Set the QH to empty. */ + ehciState->qh[index].nextDtdPointer = USB_DEVICE_ECHI_DTD_TERMINATE_MASK; + ehciState->qh[index].dtdTokenUnion.dtdToken = 0U; + } + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; +} + +/*! + * @brief Control the status of the selected item. + * + * The function is used to control the status of the selected item. + * + * @param ehciHandle Pointer of the device EHCI handle. + * @param type The selected item. Please refer to enumeration type usb_device_control_type_t. + * @param param The param type is determined by the selected item. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceEhciControl(usb_device_controller_handle ehciHandle, usb_device_control_type_t type, void *param) +{ + usb_device_ehci_state_struct_t *ehciState = (usb_device_ehci_state_struct_t *)ehciHandle; + usb_status_t error = kStatus_USB_Error; + uint16_t *temp16; + uint8_t *temp8; +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) + usb_device_dcd_state_struct_t *dcdHSState; + dcdHSState = + &s_UsbDeviceDcdHSState[ehciState->controllerId - kUSB_ControllerEhci0]; /*The hard code should be replaced*/ + usb_device_dcd_charging_time_t *deviceDcdTimingConfig = (usb_device_dcd_charging_time_t *)param; +#endif +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + usb_device_struct_t *deviceHandle; + uint64_t startTick; +#endif + + if (!ehciHandle) + { + return kStatus_USB_InvalidHandle; + } + +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + deviceHandle = (usb_device_struct_t *)ehciState->deviceHandle; +#endif + + switch (type) + { + case kUSB_DeviceControlRun: + ehciState->registerBase->USBCMD |= USBHS_USBCMD_RS_MASK; + error = kStatus_USB_Success; + break; + case kUSB_DeviceControlStop: + ehciState->registerBase->USBCMD &= ~USBHS_USBCMD_RS_MASK; + error = kStatus_USB_Success; + break; + case kUSB_DeviceControlEndpointInit: + if (param) + { + error = USB_DeviceEhciEndpointInit(ehciState, (usb_device_endpoint_init_struct_t *)param); + } + break; + case kUSB_DeviceControlEndpointDeinit: + if (param) + { + temp8 = (uint8_t *)param; + error = USB_DeviceEhciEndpointDeinit(ehciState, *temp8); + } + break; + case kUSB_DeviceControlEndpointStall: + if (param) + { + temp8 = (uint8_t *)param; + error = USB_DeviceEhciEndpointStall(ehciState, *temp8); + } + break; + case kUSB_DeviceControlEndpointUnstall: + if (param) + { + temp8 = (uint8_t *)param; + error = USB_DeviceEhciEndpointUnstall(ehciState, *temp8); + } + break; + case kUSB_DeviceControlGetDeviceStatus: + if (param) + { + temp16 = (uint16_t *)param; + *temp16 = (USB_DEVICE_CONFIG_SELF_POWER << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_SELF_POWERED_SHIFT)) +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + | (deviceHandle->remotewakeup << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_REMOTE_WARKUP_SHIFT)) +#endif + ; + error = kStatus_USB_Success; + } + break; + case kUSB_DeviceControlGetEndpointStatus: + if (param) + { + usb_device_endpoint_status_struct_t *endpointStatus = (usb_device_endpoint_status_struct_t *)param; + uint8_t ep = (endpointStatus->endpointAddress) & USB_ENDPOINT_NUMBER_MASK; + uint8_t direction = + ((endpointStatus->endpointAddress) & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + + if (ep < USB_DEVICE_CONFIG_ENDPOINTS) + { + if (ep) + { + endpointStatus->endpointStatus = (ehciState->registerBase->EPCR[ep - 1U] & + (direction ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK)) ? + kUSB_DeviceEndpointStateStalled : + kUSB_DeviceEndpointStateIdle; + } + else + { + endpointStatus->endpointStatus = + (ehciState->registerBase->EPCR0 & (direction ? USBHS_EPCR_TXS_MASK : USBHS_EPCR_RXS_MASK)) ? + kUSB_DeviceEndpointStateStalled : + kUSB_DeviceEndpointStateIdle; + } + error = kStatus_USB_Success; + } + } + break; + case kUSB_DeviceControlSetDeviceAddress: + if (param) + { + temp8 = (uint8_t *)param; + ehciState->registerBase->DEVICEADDR = (((uint32_t)(*temp8)) << USBHS_DEVICEADDR_USBADR_SHIFT); + error = kStatus_USB_Success; + } + break; + case kUSB_DeviceControlGetSynchFrame: + break; +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +#if defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U) + case kUSB_DeviceControlResume: +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + ehciState->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK; +#else + ehciState->registerBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK; +#endif + ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK; + ehciState->registerBase->PORTSC1 |= USBHS_PORTSC1_FPR_MASK; + startTick = deviceHandle->hwTick; + while ((deviceHandle->hwTick - startTick) < 10) + { + __ASM("nop"); + } + ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_FPR_MASK; + error = kStatus_USB_Success; + break; +#endif /* USB_DEVICE_CONFIG_REMOTE_WAKEUP */ + case kUSB_DeviceControlSuspend: + ehciState->registerBase->OTGSC |= 0x007F0000U; + ehciState->registerPhyBase->PWD = 0xFFFFFFFF; + /* ehciState->registerBase->OTGCTL |= ((1U<<10) | (1U<<17) | (1U<<16)); */ + while (ehciState->registerPhyBase->CTRL & (USBPHY_CTRL_UTMI_SUSPENDM_MASK)) + { + __ASM("nop"); + } + /* ehciState->registerPhyBase->CTRL |= ((1U << 21) | (1U << 22) | (1U << 23)); */ + ehciState->registerBase->USBSTS |= USBHS_USBSTS_SRI_MASK; + ehciState->registerBase->PORTSC1 |= USBHS_PORTSC1_PHCD_MASK; +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + ehciState->registerPhyBase->CTRL |= USBPHY_CTRL_ENVBUSCHG_WKUP_MASK | USBPHY_CTRL_ENIDCHG_WKUP_MASK | + USBPHY_CTRL_ENDPDMCHG_WKUP_MASK | USBPHY_CTRL_ENIRQRESUMEDETECT_MASK; + ehciState->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WKUP_ID_EN_MASK | + USBNC_USB_OTGn_CTRL_WKUP_VBUS_EN_MASK | + USBNC_USB_OTGn_CTRL_WKUP_DPDM_EN_MASK; + ehciState->registerNcBase->USB_OTGn_CTRL |= USBNC_USB_OTGn_CTRL_WIE_MASK; +#else + ehciState->registerBase->USBGENCTRL = USBHS_USBGENCTRL_WU_IE_MASK; +#endif + ehciState->registerPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK; + ehciState->isSuspending = 1U; + error = kStatus_USB_Success; + break; +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ + case kUSB_DeviceControlSetDefaultStatus: + for (uint8_t count = 0U; count < USB_DEVICE_CONFIG_ENDPOINTS; count++) + { + USB_DeviceEhciEndpointDeinit(ehciState, (count | (USB_IN << 0x07U))); + USB_DeviceEhciEndpointDeinit(ehciState, (count | (USB_OUT << 0x07U))); + } + USB_DeviceEhciSetDefaultState(ehciState); + error = kStatus_USB_Success; + break; + case kUSB_DeviceControlGetSpeed: + if (param) + { + temp8 = (uint8_t *)param; + *temp8 = ehciState->speed; + error = kStatus_USB_Success; + } + break; + case kUSB_DeviceControlGetOtgStatus: + break; + case kUSB_DeviceControlSetOtgStatus: + break; +#if (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U)) + case kUSB_DeviceControlSetTestMode: + if (param) + { + temp8 = (uint8_t *)param; + ehciState->registerBase->PORTSC1 |= ((uint32_t)(*temp8) << 16U); + error = kStatus_USB_Success; + } + break; +#endif +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) + case kUSB_DeviceControlDcdInitModule: + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + dcdHSState->dcdRegisterBase->TIMER0 = USBDCD_TIMER0_TSEQ_INIT(deviceDcdTimingConfig->dcdSeqInitTime); + dcdHSState->dcdRegisterBase->TIMER1 = USBDCD_TIMER1_TDCD_DBNC(deviceDcdTimingConfig->dcdDbncTime); + dcdHSState->dcdRegisterBase->TIMER1 |= USBDCD_TIMER1_TVDPSRC_ON(deviceDcdTimingConfig->dcdDpSrcOnTime); + dcdHSState->dcdRegisterBase->TIMER2_BC12 = + USBDCD_TIMER2_BC12_TWAIT_AFTER_PRD(deviceDcdTimingConfig->dcdTimeWaitAfterPrD); + dcdHSState->dcdRegisterBase->TIMER2_BC12 |= + USBDCD_TIMER2_BC12_TVDMSRC_ON(deviceDcdTimingConfig->dcdTimeDMSrcOn); + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_IE_MASK; + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_BC12_MASK; + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_START_MASK; + break; + case kUSB_DeviceControlDcdDeinitModule: + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + break; +#endif + + default: + break; + } + + return error; +} + +/*! + * @brief Handle the EHCI device interrupt. + * + * The function is used to handle the EHCI device interrupt. + * + * @param deviceHandle The device handle got from USB_DeviceInit. + * + */ +void USB_DeviceEhciIsrFunction(void *deviceHandle) +{ + usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle; + usb_device_ehci_state_struct_t *ehciState; + uint32_t status; + + if (NULL == deviceHandle) + { + return; + } + + ehciState = (usb_device_ehci_state_struct_t *)(handle->controllerHandle); + +#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + + if (ehciState->registerNcBase->USB_OTGn_CTRL & USBNC_USB_OTGn_CTRL_WIE_MASK) + { + if (ehciState->registerNcBase->USB_OTGn_CTRL & USBNC_USB_OTGn_CTRL_WIR_MASK) + { + ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK; + ehciState->registerNcBase->USB_OTGn_CTRL &= ~USBNC_USB_OTGn_CTRL_WIE_MASK; + } + } + else + { + } + +#else + if (ehciState->registerBase->USBGENCTRL & USBHS_USBGENCTRL_WU_IE_MASK) + { + if (ehciState->registerBase->USBGENCTRL & (1U << 8)) + { + ehciState->registerBase->USBGENCTRL &= ~(1U << 8); + ehciState->registerBase->USBGENCTRL |= USBHS_USBGENCTRL_WU_INT_CLR_MASK; + ehciState->registerBase->PORTSC1 &= ~USBHS_PORTSC1_PHCD_MASK; + ehciState->registerBase->USBGENCTRL &= ~USBHS_USBGENCTRL_WU_IE_MASK; + } + } + else + { + } +#endif + +#endif + +#if defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U) + if (ehciState->registerBase->OTGSC & USBHS_OTGSC_BSVIS_MASK) + { + usb_device_callback_message_struct_t message; + + ehciState->registerBase->OTGSC |= USBHS_OTGSC_BSVIS_MASK; + + message.buffer = (uint8_t *)NULL; + message.length = 0U; + message.isSetup = 0U; + if (ehciState->registerBase->OTGSC & USBHS_OTGSC_BSV_MASK) + { + /* Device is connected to a host. */ + message.code = kUSB_DeviceNotifyAttach; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + } + else + { + /* Device is disconnected from a host. */ + message.code = kUSB_DeviceNotifyDetach; + USB_DeviceNotificationTrigger(ehciState->deviceHandle, &message); + } + } +#endif /* USB_DEVICE_CONFIG_DETACH_ENABLE */ + + status = ehciState->registerBase->USBSTS; + status &= ehciState->registerBase->USBINTR; + + ehciState->registerBase->USBSTS = status; + +#if defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U) + if (status & USBHS_USBSTS_UEI_MASK) + { + /* Error interrupt */ + USB_DeviceEhciInterruptError(ehciState); + } +#endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */ + + if (status & USBHS_USBSTS_URI_MASK) + { + /* Reset interrupt */ + USB_DeviceEhciInterruptReset(ehciState); + } + + if (status & USBHS_USBSTS_UI_MASK) + { + /* Token done interrupt */ + USB_DeviceEhciInterruptTokenDone(ehciState); + } + + if (status & USBHS_USBSTS_PCI_MASK) + { + /* Port status change interrupt */ + USB_DeviceEhciInterruptPortChange(ehciState); + } + +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + if (status & USBHS_USBSTS_SLI_MASK) + { + /* Suspend interrupt */ + USB_DeviceEhciInterruptSuspend(ehciState); + } +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ + + if (status & USBHS_USBSTS_SRI_MASK) + { + /* Sof interrupt */ + USB_DeviceEhciInterruptSof(ehciState); + } +} + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) +void USB_DeviceDcdHSIsrFunction(void *deviceHandle) +{ + usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle; + usb_device_ehci_state_struct_t *ehciState; + usb_device_dcd_state_struct_t *dcdHSState; + uint32_t status; + uint32_t chargerType; + usb_device_callback_message_struct_t message; + + if (NULL == deviceHandle) + { + return; + } + + ehciState = (usb_device_ehci_state_struct_t *)(handle->controllerHandle); + + dcdHSState = &s_UsbDeviceDcdHSState[ehciState->controllerId - kUSB_ControllerEhci0]; + + status = dcdHSState->dcdRegisterBase->STATUS; + + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_IACK_MASK; + + message.buffer = (uint8_t *)NULL; + message.length = 0U; + message.isSetup = 0U; + + if (status & USBDCD_STATUS_ERR_MASK) + { + if (status & USBDCD_STATUS_TO_MASK) + { + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + message.code = kUSB_DeviceNotifyDcdTimeOut; + USB_DeviceNotificationTrigger(dcdHSState->deviceHandle, &message); + } + else + { + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + message.code = kUSB_DeviceNotifyDcdUnknownPortType; + USB_DeviceNotificationTrigger(dcdHSState->deviceHandle, &message); + } + } + else + { + switch (status & USBDCD_STATUS_SEQ_STAT_MASK) + { + case USBDCD_STATUS_SEQ_STAT(kUSB_DcdChargingPortDetectionCompleted): + chargerType = status & USBDCD_STATUS_SEQ_RES_MASK; + if (chargerType == USBDCD_STATUS_SEQ_RES(kUSB_DcdDetectionStandardHost)) + { + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + message.code = kUSB_DeviceNotifySDPDetected; + USB_DeviceNotificationTrigger(dcdHSState->deviceHandle, &message); + } + else if (chargerType == USBDCD_STATUS_SEQ_RES(kUSB_DcdDetectionChargingPort)) + { + message.code = kUSB_DeviceNotifyChargingPortDetected; + USB_DeviceNotificationTrigger(dcdHSState->deviceHandle, &message); + } + break; + case USBDCD_STATUS_SEQ_STAT(kUSB_DcdChargerTypeDetectionCompleted): + chargerType = status & USBDCD_STATUS_SEQ_RES_MASK; + if (chargerType == USBDCD_STATUS_SEQ_RES(kUSB_DcdDetectionChargingPort)) + { + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + message.code = kUSB_DeviceNotifyChargingHostDetected; + USB_DeviceNotificationTrigger(dcdHSState->deviceHandle, &message); + } + else if (chargerType == USBDCD_STATUS_SEQ_RES(kUSB_DcdDetectionDedicatedCharger)) + { + dcdHSState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + message.code = kUSB_DeviceNotifyDedicatedChargerDetected; + USB_DeviceNotificationTrigger(dcdHSState->deviceHandle, &message); + } + break; + + default: + break; + } + } +} +#endif + +#endif /* USB_DEVICE_CONFIG_EHCI */ diff --git a/usb/device/source/ehci/usb_device_ehci.h b/usb/device/source/ehci/usb_device_ehci.h new file mode 100644 index 0000000..e071a98 --- /dev/null +++ b/usb/device/source/ehci/usb_device_ehci.h @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_EHCI_H__ +#define __USB_DEVICE_EHCI_H__ + + +/*! + * @addtogroup usb_device_controller_ehci_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief The maximum value of ISO type maximum packet size for HS in USB specification 2.0 */ +#define USB_DEVICE_MAX_HS_ISO_MAX_PACKET_SIZE (1024U) + +/*! @brief The maximum value of interrupt type maximum packet size for HS in USB specification 2.0 */ +#define USB_DEVICE_MAX_HS_INTERUPT_MAX_PACKET_SIZE (1024U) + +/*! @brief The maximum value of bulk type maximum packet size for HS in USB specification 2.0 */ +#define USB_DEVICE_MAX_HS_BULK_MAX_PACKET_SIZE (512U) + +/*! @brief The maximum value of control type maximum packet size for HS in USB specification 2.0 */ +#define USB_DEVICE_MAX_HS_CONTROL_MAX_PACKET_SIZE (64U) + +#define USB_DEVICE_MAX_TRANSFER_PRIME_TIMES (10000000U) /* The max prime times of EPPRIME, if still doesn't take effect, means status has been reset*/ + +/* Device QH */ +#define USB_DEVICE_EHCI_QH_POINTER_MASK (0xFFFFFFC0U) +#define USB_DEVICE_EHCI_QH_MULT_MASK (0xC0000000U) +#define USB_DEVICE_EHCI_QH_ZLT_MASK (0x20000000U) +#define USB_DEVICE_EHCI_QH_MAX_PACKET_SIZE_MASK (0x07FF0000U) +#define USB_DEVICE_EHCI_QH_MAX_PACKET_SIZE (0x00000800U) +#define USB_DEVICE_EHCI_QH_IOS_MASK (0x00008000U) + +/* Device DTD */ +#define USB_DEVICE_ECHI_DTD_POINTER_MASK (0xFFFFFFE0U) +#define USB_DEVICE_ECHI_DTD_TERMINATE_MASK (0x00000001U) +#define USB_DEVICE_ECHI_DTD_PAGE_MASK (0xFFFFF000U) +#define USB_DEVICE_ECHI_DTD_PAGE_OFFSET_MASK (0x00000FFFU) +#define USB_DEVICE_ECHI_DTD_PAGE_BLOCK (0x00001000U) +#define USB_DEVICE_ECHI_DTD_TOTAL_BYTES_MASK (0x7FFF0000U) +#define USB_DEVICE_ECHI_DTD_TOTAL_BYTES (0x00004000U) +#define USB_DEVICE_ECHI_DTD_IOC_MASK (0x00008000U) +#define USB_DEVICE_ECHI_DTD_MULTIO_MASK (0x00000C00U) +#define USB_DEVICE_ECHI_DTD_STATUS_MASK (0x000000FFU) +#define USB_DEVICE_EHCI_DTD_STATUS_ERROR_MASK (0x00000068U) +#define USB_DEVICE_ECHI_DTD_STATUS_ACTIVE (0x00000080U) +#define USB_DEVICE_ECHI_DTD_STATUS_HALTED (0x00000040U) +#define USB_DEVICE_ECHI_DTD_STATUS_DATA_BUFFER_ERROR (0x00000020U) +#define USB_DEVICE_ECHI_DTD_STATUS_TRANSACTION_ERROR (0x00000008U) + +typedef struct _usb_device_ehci_qh_struct +{ + union + { + volatile uint32_t capabilttiesCharacteristics; + struct + { + volatile uint32_t reserved1 : 15; + volatile uint32_t ios : 1; + volatile uint32_t maxPacketSize : 11; + volatile uint32_t reserved2 : 2; + volatile uint32_t zlt : 1; + volatile uint32_t mult : 2; + } capabilttiesCharacteristicsBitmap; + } capabilttiesCharacteristicsUnion; + volatile uint32_t currentDtdPointer; + volatile uint32_t nextDtdPointer; + union + { + volatile uint32_t dtdToken; + struct + { + volatile uint32_t status : 8; + volatile uint32_t reserved1 : 2; + volatile uint32_t multiplierOverride : 2; + volatile uint32_t reserved2 : 3; + volatile uint32_t ioc : 1; + volatile uint32_t totalBytes : 15; + volatile uint32_t reserved3 : 1; + } dtdTokenBitmap; + } dtdTokenUnion; + volatile uint32_t bufferPointerPage[5]; + volatile uint32_t reserved1; + uint32_t setupBuffer[2]; + uint32_t setupBufferBack[2]; + union + { + uint32_t endpointStatus; + struct + { + uint32_t isOpened : 1; + uint32_t zlt: 1; + uint32_t : 30; + } endpointStatusBitmap; + } endpointStatusUnion; + uint32_t reserved2; +} usb_device_ehci_qh_struct_t; + +typedef struct _usb_device_ehci_dtd_struct +{ + volatile uint32_t nextDtdPointer; + union + { + volatile uint32_t dtdToken; + struct + { + volatile uint32_t status : 8; + volatile uint32_t reserved1 : 2; + volatile uint32_t multiplierOverride : 2; + volatile uint32_t reserved2 : 3; + volatile uint32_t ioc : 1; + volatile uint32_t totalBytes : 15; + volatile uint32_t reserved3 : 1; + } dtdTokenBitmap; + } dtdTokenUnion; + volatile uint32_t bufferPointerPage[5]; + union + { + volatile uint32_t reserved; + struct + { + uint32_t originalBufferOffest : 12; + uint32_t originalBufferLength : 19; + uint32_t dtdInvalid : 1; + } originalBufferInfo; + } reservedUnion; +} usb_device_ehci_dtd_struct_t; + +/*! @brief EHCI state structure */ +typedef struct _usb_device_ehci_state_struct +{ + usb_device_struct_t *deviceHandle; /*!< Device handle used to identify the device object is belonged to */ + USBHS_Type *registerBase; /*!< The base address of the register */ +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + USBPHY_Type *registerPhyBase; /*!< The base address of the PHY register */ +#if (defined(FSL_FEATURE_SOC_USBNC_COUNT) && (FSL_FEATURE_SOC_USBNC_COUNT > 0U)) + USBNC_Type *registerNcBase; /*!< The base address of the USBNC register */ +#endif +#endif + usb_device_ehci_qh_struct_t *qh; /*!< The QH structure base address */ + usb_device_ehci_dtd_struct_t *dtd; /*!< The DTD structure base address */ + usb_device_ehci_dtd_struct_t *dtdFree; /*!< The idle DTD list head */ + usb_device_ehci_dtd_struct_t + *dtdHard[USB_DEVICE_CONFIG_ENDPOINTS * 2]; /*!< The transferring DTD list head for each endpoint */ + usb_device_ehci_dtd_struct_t + *dtdTail[USB_DEVICE_CONFIG_ENDPOINTS * 2]; /*!< The transferring DTD list tail for each endpoint */ + int8_t dtdCount; /*!< The idle DTD node count */ + uint8_t endpointCount; /*!< The endpoint number of EHCI */ + uint8_t isResetting; /*!< Whether a PORT reset is occurring or not */ + uint8_t controllerId; /*!< Controller ID */ + uint8_t speed; /*!< Current speed of EHCI */ + uint8_t isSuspending; /*!< Is suspending of the PORT */ +} usb_device_ehci_state_struct_t; + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U)) +typedef struct _usb_device_dcd_state_struct +{ + usb_device_struct_t *deviceHandle; /*!< Device handle used to identify the device object belongs to */ + USBHSDCD_Type *dcdRegisterBase; /*!< The base address of the dcd module */ + uint8_t controllerId; /*!< Controller ID */ +} usb_device_dcd_state_struct_t; +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name USB device EHCI functions + * @{ + */ + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @brief Initializes the USB device EHCI instance. + * + * This function initializes the USB device EHCI module specified by the controllerId. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration type usb_controller_index_t. + * @param[in] handle Pointer of the device handle used to identify the device object is belonged to. + * @param[out] ehciHandle An out parameter used to return the pointer of the device EHCI handle to the caller. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceEhciInit(uint8_t controllerId, + usb_device_handle handle, + usb_device_controller_handle *ehciHandle); + +/*! + * @brief Deinitializes the USB device EHCI instance. + * + * This function deinitializes the USB device EHCI module. + * + * @param[in] ehciHandle Pointer of the device EHCI handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceEhciDeinit(usb_device_controller_handle ehciHandle); + +/*! + * @brief Sends data through a specified endpoint. + * + * This function sends data through a specified endpoint. + * + * @param[in] ehciHandle Pointer of the device EHCI handle. + * @param[in] endpointAddress Endpoint index. + * @param[in] buffer The memory address to hold the data need to be sent. + * @param[in] length The data length to be sent. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value means whether the sending request is successful or not. The transfer completion is indicated + * by the + * corresponding callback function. + * Currently, only one transfer request can be supported for a specific endpoint. + * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer can begin only when the previous transfer is done (a notification is received through the + * endpoint + * callback). + */ +usb_status_t USB_DeviceEhciSend(usb_device_controller_handle ehciHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! + * @brief Receive data through a specified endpoint. + * + * This function Receives data through a specified endpoint. + * + * @param[in] ehciHandle Pointer of the device EHCI handle. + * @param[in] endpointAddress Endpoint index. + * @param[in] buffer The memory address to save the received data. + * @param[in] length The data length want to be received. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value just means if the receiving request is successful or not; the transfer done is notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceEhciRecv(usb_device_controller_handle ehciHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! + * @brief Cancels the pending transfer in a specified endpoint. + * + * The function is used to cancel the pending transfer in a specified endpoint. + * + * @param[in] ehciHandle Pointer of the device EHCI handle. + * @param[in] ep Endpoint address, bit7 is the direction of endpoint, 1U - IN, 0U - OUT. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceEhciCancel(usb_device_controller_handle ehciHandle, uint8_t ep); + +/*! + * @brief Controls the status of the selected item. + * + * The function is used to control the status of the selected item. + * + * @param[in] ehciHandle Pointer of the device EHCI handle. + * @param[in] type The selected item. See enumeration type usb_device_control_type_t. + * @param[in,out] param The parameter type is determined by the selected item. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceEhciControl(usb_device_controller_handle ehciHandle, + usb_device_control_type_t type, + void *param); + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* __USB_DEVICE_EHCI_H__ */ diff --git a/usb/device/source/khci/usb_device_khci.c b/usb/device/source/khci/usb_device_khci.c new file mode 100644 index 0000000..73e6876 --- /dev/null +++ b/usb/device/source/khci/usb_device_khci.c @@ -0,0 +1,1652 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb_device_config.h" +#include "usb.h" + +#include "usb_device.h" + +#include "fsl_device_registers.h" + +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) + +#include "usb_device_dci.h" + +#include "usb_device_khci.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#if defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM > 0U) + +/* USB_STACK_USE_DEDICATED_RAM */ +#if defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U) + +#if (USB_STACK_USE_DEDICATED_RAM == USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL) +#if (FSL_FEATURE_USB_KHCI_USB_RAM > 512U) +#else +#error The dedicated RAM length is not more than 512 Bytes, the SOC does not support this case. +#endif +#endif /* USB_STACK_USE_DEDICATED_RAM */ + +#else +#error The SOC does not suppoort dedicated RAM case. +#endif /* USB_STACK_USE_DEDICATED_RAM */ + +#endif + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static usb_status_t USB_DeviceKhciEndpointTransfer( + usb_device_khci_state_struct_t *khciState, uint8_t endpoint, uint8_t direction, uint8_t *buffer, uint32_t length); +static void USB_DeviceKhciPrimeNextSetup(usb_device_khci_state_struct_t *khciState); +static void USB_DeviceKhciSetDefaultState(usb_device_khci_state_struct_t *khciState); +static usb_status_t USB_DeviceKhciEndpointInit(usb_device_khci_state_struct_t *khciState, + usb_device_endpoint_init_struct_t *epInit); +static usb_status_t USB_DeviceKhciEndpointDeinit(usb_device_khci_state_struct_t *khciState, uint8_t ep); +static usb_status_t USB_DeviceKhciEndpointStall(usb_device_khci_state_struct_t *khciState, uint8_t ep); +static usb_status_t USB_DeviceKhciEndpointUnstall(usb_device_khci_state_struct_t *khciState, uint8_t ep); +static void USB_DeviceKhciInterruptTokenDone(usb_device_khci_state_struct_t *khciState); +static void USB_DeviceKhciInterruptReset(usb_device_khci_state_struct_t *khciState); +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +static void USB_DeviceKhciInterruptSleep(usb_device_khci_state_struct_t *khciState); +static void USB_DeviceKhciInterruptResume(usb_device_khci_state_struct_t *khciState); +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ +static void USB_DeviceKhciInterruptStall(usb_device_khci_state_struct_t *khciState); +#if defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U) +static void USB_DeviceKhciInterruptError(usb_device_khci_state_struct_t *khciState); +#endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */ + +extern usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Apply for BDT buffer, 512-byte alignment */ +USB_BDT USB_RAM_ADDRESS_ALIGNMENT(512) static uint8_t s_UsbDeviceKhciBdtBuffer[USB_DEVICE_CONFIG_KHCI][512U]; + +/* Apply for khci device state structure */ +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_khci_state_struct_t + s_UsbDeviceKhciState[USB_DEVICE_CONFIG_KHCI]; + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) +/* Apply for device dcd state structure */ +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_dcd_state_struct_t + s_UsbDeviceDcdState[USB_DEVICE_CONFIG_KHCI]; +#endif + +/* Apply for KHCI DMA aligned buffer when macro USB_DEVICE_CONFIG_KHCI_DMA_ALIGN enabled */ +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint32_t s_UsbDeviceKhciDmaAlignBuffer + [USB_DEVICE_CONFIG_KHCI][((USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH - 1U) >> 2U) + 1U]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Write the BDT to start a transfer. + * + * The function is used to start a transfer by writing the BDT. + * + * @param khciState Pointer of the device KHCI state structure. + * @param endpoint Endpoint number. + * @param direction The direction of the endpoint, 0U - USB_OUT, 1U - USB_IN. + * @param buffer The memory address to save the received data, or the memory address to hold the data need to + * be sent. + * @param length The length of the data. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceKhciEndpointTransfer( + usb_device_khci_state_struct_t *khciState, uint8_t endpoint, uint8_t direction, uint8_t *buffer, uint32_t length) +{ + uint32_t index = ((uint32_t)endpoint << 1U) | (uint32_t)direction; + USB_OSA_SR_ALLOC(); + + /* Enter critical */ + USB_OSA_ENTER_CRITICAL(); + + /* Flag the endpoint is busy. */ + khciState->endpointState[index].stateUnion.stateBitField.transferring = 1U; + + /* Add the data buffer address to the BDT. */ + USB_KHCI_BDT_SET_ADDRESS((uint32_t)khciState->bdt, endpoint, direction, + khciState->endpointState[index].stateUnion.stateBitField.bdtOdd, (uint32_t)buffer); + + /* Change the BDT control field to start the transfer. */ + USB_KHCI_BDT_SET_CONTROL( + (uint32_t)khciState->bdt, endpoint, direction, khciState->endpointState[index].stateUnion.stateBitField.bdtOdd, + USB_LONG_TO_LITTLE_ENDIAN(USB_KHCI_BDT_BC(length) | USB_KHCI_BDT_OWN | USB_KHCI_BDT_DTS | + USB_KHCI_BDT_DATA01(khciState->endpointState[index].stateUnion.stateBitField.data0))); + + /* Exit critical */ + USB_OSA_EXIT_CRITICAL(); + + /* Clear the token busy state */ + khciState->registerBase->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; + return kStatus_USB_Success; +} + +/*! + * @brief Prime a next setup transfer. + * + * The function is used to prime a buffer in control out pipe to wait for receiving the host's setup packet. + * + * @param khciState Pointer of the device KHCI state structure. + * + */ +static void USB_DeviceKhciPrimeNextSetup(usb_device_khci_state_struct_t *khciState) +{ +/* Update the endpoint state */ +/* Save the buffer address used to receive the setup packet. */ +#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \ + defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \ + defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U) + /* In case of lowpower mode enabled, it requires to put the setup packet buffer(16 bytes) into the USB RAM so + * that the setup packet would wake up the USB. + */ + khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferBuffer = + (uint8_t *)(khciState->bdt + 0x200U - 0x10U) + + khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.bdtOdd * + USB_SETUP_PACKET_SIZE; +#else + khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferBuffer = + (uint8_t *)&khciState->setupPacketBuffer[0] + + khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.bdtOdd * + USB_SETUP_PACKET_SIZE; +#endif + /* Clear the transferred length. */ + khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferDone = 0U; + /* Save the data length expected to get from a host. */ + khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferLength = USB_SETUP_PACKET_SIZE; + /* Save the data buffer DMA align flag. */ + khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.dmaAlign = 1U; + /* Set the DATA0/1 to DATA0. */ + khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.data0 = 0U; + + USB_DeviceKhciEndpointTransfer(khciState, USB_CONTROL_ENDPOINT, USB_OUT, + khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferBuffer, + USB_SETUP_PACKET_SIZE); +} + +/*! + * @brief Set device controller state to default state. + * + * The function is used to set device controller state to default state. + * The function will be called when USB_DeviceKhciInit called or the control type kUSB_DeviceControlGetEndpointStatus + * received in USB_DeviceKhciControl. + * + * @param khciState Pointer of the device KHCI state structure. + * + */ +static void USB_DeviceKhciSetDefaultState(usb_device_khci_state_struct_t *khciState) +{ + uint8_t interruptFlag; + + /* Clear the error state register */ + khciState->registerBase->ERRSTAT = 0xFFU; + + /* Setting this bit to 1U resets all the BDT ODD ping/pong fields to 0U, which then specifies the EVEN BDT bank. */ + khciState->registerBase->CTL |= USB_CTL_ODDRST_MASK; + + /* Clear the device address */ + khciState->registerBase->ADDR = 0U; + + /* Clear the endpoint state and disable the endpoint */ + for (uint8_t count = 0U; count < USB_DEVICE_CONFIG_ENDPOINTS; count++) + { + USB_KHCI_BDT_SET_CONTROL((uint32_t)khciState->bdt, count, USB_OUT, 0U, 0U); + USB_KHCI_BDT_SET_CONTROL((uint32_t)khciState->bdt, count, USB_OUT, 1U, 0U); + USB_KHCI_BDT_SET_CONTROL((uint32_t)khciState->bdt, count, USB_IN, 0U, 0U); + USB_KHCI_BDT_SET_CONTROL((uint32_t)khciState->bdt, count, USB_IN, 1U, 0U); + + khciState->endpointState[((uint32_t)count << 1U) | USB_OUT].stateUnion.state = 0U; + khciState->endpointState[((uint32_t)count << 1U) | USB_IN].stateUnion.state = 0U; + khciState->registerBase->ENDPOINT[count].ENDPT = 0x00U; + } + khciState->isDmaAlignBufferInusing = 0U; + + /* Clear the BDT odd reset flag */ + khciState->registerBase->CTL &= ~USB_CTL_ODDRST_MASK; + + /* Enable all error */ + khciState->registerBase->ERREN = 0xFFU; + + /* Enable reset, sof, token, stall interrupt */ + interruptFlag = kUSB_KhciInterruptReset +#if 0U + | kUSB_KhciInterruptSofToken +#endif + | kUSB_KhciInterruptTokenDone | kUSB_KhciInterruptStall; + +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + /* Enable suspend interruprt */ + interruptFlag |= kUSB_KhciInterruptSleep; +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ + +#if defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U) + /* Enable error interruprt */ + interruptFlag |= kUSB_KhciInterruptError; +#endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */ + /* Write the interrupt enable register */ + khciState->registerBase->INTEN = interruptFlag; + + /* Clear reset flag */ + khciState->isResetting = 0U; + + khciState->registerBase->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; +} + +/*! + * @brief Initialize a specified endpoint. + * + * The function is used to initialize a specified endpoint. + * + * @param khciState Pointer of the device KHCI state structure. + * @param epInit The endpoint initialization structure pointer. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceKhciEndpointInit(usb_device_khci_state_struct_t *khciState, + usb_device_endpoint_init_struct_t *epInit) +{ + uint16_t maxPacketSize = epInit->maxPacketSize; + uint8_t endpoint = (epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK); + uint8_t direction = (epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction; + + /* Make the endpoint max packet size align with USB Specification 2.0. */ + if (USB_ENDPOINT_ISOCHRONOUS == epInit->transferType) + { + if (maxPacketSize > USB_DEVICE_MAX_FS_ISO_MAX_PACKET_SIZE) + { + maxPacketSize = USB_DEVICE_MAX_FS_ISO_MAX_PACKET_SIZE; + } + } + else + { + if (maxPacketSize > USB_DEVICE_MAX_FS_NONE_ISO_MAX_PACKET_SIZE) + { + maxPacketSize = USB_DEVICE_MAX_FS_NONE_ISO_MAX_PACKET_SIZE; + } + /* Enable an endpoint to perform handshaking during a transaction to this endpoint. */ + khciState->registerBase->ENDPOINT[endpoint].ENDPT |= USB_ENDPT_EPHSHK_MASK; + } + /* Set the endpoint idle */ + khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U; + /* Save the max packet size of the endpoint */ + khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize = maxPacketSize; + /* Set the data toggle to DATA0 */ + khciState->endpointState[index].stateUnion.stateBitField.data0 = 0U; + /* Clear the endpoint stalled state */ + khciState->endpointState[index].stateUnion.stateBitField.stalled = 0U; + /* Set the ZLT field */ + khciState->endpointState[index].stateUnion.stateBitField.zlt = epInit->zlt; + /* Enable the endpoint. */ + khciState->registerBase->ENDPOINT[endpoint].ENDPT |= + (USB_IN == direction) ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK; +#if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_LOW) && (FSL_FEATURE_USB_KHCI_HAS_STALL_LOW > 0U) + /*control endpoint bidirection stall default state should be enable, iso doesn't support stall*/ + if ((USB_ENDPOINT_BULK == epInit->transferType) || (USB_ENDPOINT_INTERRUPT == epInit->transferType)) + { + if(USB_IN == direction) + { + if (endpoint < 8) + { + khciState->registerBase->STALL_IL_DIS |= (1< 0U) + else if ((endpoint >= 8) && (endpoint < 16)) + { + khciState->registerBase->STALL_IH_DIS |= (1<<(endpoint-8)); + } +#endif + } + else + { + if (endpoint < 8) + { + khciState->registerBase->STALL_OL_DIS |= (1< 0U) + else if ((endpoint >= 8) && (endpoint < 16)) + { + khciState->registerBase->STALL_OH_DIS |= (1<<(endpoint-8)); + } +#endif + } + } + else if ((USB_ENDPOINT_CONTROL == epInit->transferType)) + { + khciState->registerBase->STALL_IL_DIS &= ~(1<registerBase->STALL_OL_DIS &= ~(1<> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction; + + /* Cancel the transfer of the endpoint */ + USB_DeviceKhciCancel(khciState, ep); + + /* Disable the endpoint */ + khciState->registerBase->ENDPOINT[endpoint].ENDPT = 0x00U; + /* Clear the max packet size */ + khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize = 0U; + + return kStatus_USB_Success; +} + +/*! + * @brief Stall a specified endpoint. + * + * The function is used to stall a specified endpoint. + * Current transfer of the endpoint will be canceled and the specified endpoint will be stalled. + * + * @param khciState Pointer of the device KHCI state structure. + * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceKhciEndpointStall(usb_device_khci_state_struct_t *khciState, uint8_t ep) +{ + uint8_t endpoint = ep & USB_ENDPOINT_NUMBER_MASK; + uint8_t direction = + (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction; + + /* Cancel the transfer of the endpoint */ + USB_DeviceKhciCancel(khciState, ep); + + /* Set endpoint stall flag. */ + khciState->endpointState[index].stateUnion.stateBitField.stalled = 1U; +#if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_LOW) && (FSL_FEATURE_USB_KHCI_HAS_STALL_LOW > 0U) + if (USB_CONTROL_ENDPOINT != endpoint) + { + if(USB_IN == direction) + { + if (endpoint < 8) + { + khciState->registerBase->STALL_IL_DIS &= ~(1< 0U) + else if ((endpoint >= 8) && (endpoint < 16)) + { + khciState->registerBase->STALL_IH_DIS &= ~(1<<(endpoint-8)); + } +#endif + } + else + { + if (endpoint < 8) + { + khciState->registerBase->STALL_OL_DIS &= ~(1< 0U) + else if ((endpoint >= 8) && (endpoint < 16)) + { + khciState->registerBase->STALL_OH_DIS &= ~(1<<(endpoint-8)); + } +#endif + } + } +#endif + /* Set endpoint stall in BDT. And then if the host send a IN/OUT tansaction, the device will response a STALL state. + */ + USB_KHCI_BDT_SET_CONTROL( + (uint32_t)khciState->bdt, endpoint, direction, khciState->endpointState[index].stateUnion.stateBitField.bdtOdd, + USB_LONG_TO_LITTLE_ENDIAN( + (uint32_t)(USB_KHCI_BDT_BC(khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize) | + USB_KHCI_BDT_DTS | USB_KHCI_BDT_STALL | USB_KHCI_BDT_OWN))); + + khciState->registerBase->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; + + return kStatus_USB_Success; +} + +/*! + * @brief Un-stall a specified endpoint. + * + * The function is used to un-stall a specified endpoint. + * Current transfer of the endpoint will be canceled and the specified endpoint will be un-stalled. + * + * @param khciState Pointer of the device KHCI state structure. + * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceKhciEndpointUnstall(usb_device_khci_state_struct_t *khciState, uint8_t ep) +{ + uint8_t endpoint = ep & USB_ENDPOINT_NUMBER_MASK; + uint8_t direction = + (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction; + + /* Clear the endpoint stall state */ + khciState->endpointState[index].stateUnion.stateBitField.stalled = 0U; + /* Reset the endpoint data toggle to DATA0 */ + khciState->endpointState[index].stateUnion.stateBitField.data0 = 0U; + + /* Clear stall state in BDT */ + for (uint8_t i = 0U; i < 2U; i++) + { + USB_KHCI_BDT_SET_CONTROL( + (uint32_t)khciState->bdt, endpoint, direction, i, + USB_LONG_TO_LITTLE_ENDIAN( + (uint32_t)(USB_KHCI_BDT_BC(khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize) | + USB_KHCI_BDT_DTS | USB_KHCI_BDT_DATA01(0U)))); + } + + /* Clear stall state in endpoint control register */ + khciState->registerBase->ENDPOINT[endpoint].ENDPT &= ~USB_ENDPT_EPSTALL_MASK; +#if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_LOW) && (FSL_FEATURE_USB_KHCI_HAS_STALL_LOW > 0U) + if (USB_CONTROL_ENDPOINT != endpoint) + { + if(USB_IN == direction) + { + if (endpoint < 8) + { + khciState->registerBase->STALL_IL_DIS |= (1< 0U) + else if ((endpoint >= 8) && (endpoint < 16)) + { + khciState->registerBase->STALL_IH_DIS |= (1<<(endpoint-8)); + } +#endif + } + else + { + if (endpoint < 8) + { + khciState->registerBase->STALL_OL_DIS |= (1< 0U) + else if ((endpoint >= 8) && (endpoint < 16)) + { + khciState->registerBase->STALL_OH_DIS |= (1<<(endpoint-8)); + } +#endif + } + } +#endif + if ((USB_CONTROL_ENDPOINT != endpoint)) + { + /* Cancel the transfer of the endpoint */ + USB_DeviceKhciCancel(khciState, ep); + } + + /* Prime a transfer to receive next setup packet when the endpoint is a control out endpoint. */ + if ((USB_CONTROL_ENDPOINT == endpoint) && (USB_OUT == direction)) + { + USB_DeviceKhciPrimeNextSetup(khciState); + } + + khciState->registerBase->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; + + return kStatus_USB_Success; +} + +/*! + * @brief Handle the token done interrupt. + * + * The function is used to handle the token done interrupt. + * + * @param khciState Pointer of the device KHCI state structure. + * + */ +static void USB_DeviceKhciInterruptTokenDone(usb_device_khci_state_struct_t *khciState) +{ + uint32_t control; + uint32_t length; + uint32_t remainingLength; + uint8_t *bdtBuffer; + usb_device_callback_message_struct_t message; + uint8_t endpoint; + uint8_t direction; + uint8_t bdtOdd; + uint8_t isSetup; + uint8_t index; + uint8_t stateRegister = khciState->registerBase->STAT; + + /* Get the endpoint number to identify which one triggers the token done interrupt. */ + endpoint = (stateRegister & USB_STAT_ENDP_MASK) >> USB_STAT_ENDP_SHIFT; + + /* Get the direction of the endpoint number. */ + direction = (stateRegister & USB_STAT_TX_MASK) >> USB_STAT_TX_SHIFT; + + /* Get the finished BDT ODD. */ + bdtOdd = (stateRegister & USB_STAT_ODD_MASK) >> USB_STAT_ODD_SHIFT; + + /* Clear token done interrupt flag. */ + khciState->registerBase->ISTAT = kUSB_KhciInterruptTokenDone; + + /* Get the Control field of the BDT element according to the endpoint number, the direction and finished BDT ODD. */ + control = USB_KHCI_BDT_GET_CONTROL((uint32_t)khciState->bdt, endpoint, direction, bdtOdd); + + /* Get the buffer field of the BDT element according to the endpoint number, the direction and finished BDT ODD. */ + bdtBuffer = (uint8_t *)USB_KHCI_BDT_GET_ADDRESS((uint32_t)khciState->bdt, endpoint, direction, bdtOdd); + + /* Get the transferred length. */ + length = ((USB_LONG_FROM_LITTLE_ENDIAN(control)) >> 16U) & 0x3FFU; + + /* Get the transferred length. */ + isSetup = (USB_KHCI_BDT_DEVICE_SETUP_TOKEN == ((uint8_t)(((USB_LONG_FROM_LITTLE_ENDIAN(control)) >> 2U) & 0x0FU))) ? + 1U : + 0U; + + index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction; + + if (0U == khciState->endpointState[index].stateUnion.stateBitField.transferring) + { + return; + } + + if (isSetup) + { + khciState->setupBufferIndex = bdtOdd; + } + + /* USB_IN, Send completed */ + if (direction == USB_IN) + { + /* The transferred length */ + khciState->endpointState[index].transferDone += length; + + /* Remaining length */ + remainingLength = khciState->endpointState[index].transferLength - khciState->endpointState[index].transferDone; + + /* Change the data toggle flag */ + khciState->endpointState[index].stateUnion.stateBitField.data0 ^= 1U; + /* Change the BDT odd toggle flag */ + khciState->endpointState[index].stateUnion.stateBitField.bdtOdd ^= 1U; + + /* Whether the transfer is completed or not. */ + /* + * The transfer is completed when one of the following conditions meet: + * 1. The remaining length is zero. + * 2. The length of current tansaction is less than the max packet size of the current pipe. + */ + if ((0U == remainingLength) || + (khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize > length)) + { + message.length = khciState->endpointState[index].transferDone; + message.buffer = khciState->endpointState[index].transferBuffer; + khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U; + + /* + * Whether need to send ZLT when the pipe is control in pipe and the transferred length of current + * transaction equals to max packet size. + */ + if ((length) && (!(length % khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize))) + { + if (USB_CONTROL_ENDPOINT == endpoint) + { + usb_setup_struct_t *setup_packet = + (usb_setup_struct_t + *)(&khciState->setupPacketBuffer[(USB_SETUP_PACKET_SIZE * khciState->setupBufferIndex)]); + /* + * Send the ZLT and terminate the token done interrupt service when the transferred length in data + * phase + * is less than the host request. + */ + if (USB_SHORT_FROM_LITTLE_ENDIAN(setup_packet->wLength) > + khciState->endpointState[index].transferLength) + { + (void)USB_DeviceKhciEndpointTransfer(khciState, endpoint, USB_IN, (uint8_t *)NULL, 0U); + return; + } + } + else if (khciState->endpointState[index].stateUnion.stateBitField.zlt) + { + (void)USB_DeviceKhciEndpointTransfer(khciState, endpoint, USB_IN, (uint8_t *)NULL, 0U); + return; + } + else + { + } + } + } + else + { + /* Send remaining data and terminate the token done interrupt service. */ + (void)USB_DeviceKhciSend(khciState, endpoint | (USB_IN << 0x07U), + khciState->endpointState[index].transferBuffer, remainingLength); + return; + } + } + else + { + if ((USB_CONTROL_ENDPOINT == endpoint) && (0U == length)) + { + message.length = 0U; + message.buffer = (uint8_t *)NULL; + } + else + { + if (0U == khciState->endpointState[index].stateUnion.stateBitField.dmaAlign) + { + uint8_t *buffer = (uint8_t *)USB_LONG_FROM_LITTLE_ENDIAN( + USB_KHCI_BDT_GET_ADDRESS((uint32_t)khciState->bdt, endpoint, USB_OUT, + khciState->endpointState[index].stateUnion.stateBitField.bdtOdd)); + uint8_t *transferBuffer = + khciState->endpointState[index].transferBuffer + khciState->endpointState[index].transferDone; + if (buffer != transferBuffer) + { + for (uint32_t i = 0U; i < length; i++) + { + transferBuffer[i] = buffer[i]; + } + } + khciState->isDmaAlignBufferInusing = 0U; + } + /* The transferred length */ + khciState->endpointState[index].transferDone += length; + /* Remaining length */ + remainingLength = + khciState->endpointState[index].transferLength - khciState->endpointState[index].transferDone; + + if ((USB_CONTROL_ENDPOINT == endpoint) && isSetup) + { + khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.data0 = 1U; + khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_IN].stateUnion.stateBitField.data0 = 1U; + } + else + { + khciState->endpointState[index].stateUnion.stateBitField.data0 ^= 1U; + } + khciState->endpointState[index].stateUnion.stateBitField.bdtOdd ^= 1U; + if ((!khciState->endpointState[index].transferLength) || (!remainingLength) || + (khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize > length)) + { + message.length = khciState->endpointState[index].transferDone; + if (isSetup) + { + message.buffer = bdtBuffer; + } + else + { + message.buffer = khciState->endpointState[index].transferBuffer; + } + khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U; + } + else + { + /* Receive remaining data and terminate the token done interrupt service. */ + USB_DeviceKhciRecv(khciState, (endpoint) | (USB_OUT << 0x07U), + khciState->endpointState[index].transferBuffer, remainingLength); + return; + } + } + } + + message.isSetup = isSetup; + message.code = (endpoint) | (uint8_t)(((uint32_t)direction << 0x07U)); + + /* Notify the up layer the KHCI status changed. */ + USB_DeviceNotificationTrigger(khciState->deviceHandle, &message); + + khciState->registerBase->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; +} + +/*! + * @brief Handle the USB bus reset interrupt. + * + * The function is used to handle the USB bus reset interrupt. + * + * @param khciState Pointer of the device KHCI state structure. + * + */ +static void USB_DeviceKhciInterruptReset(usb_device_khci_state_struct_t *khciState) +{ + usb_device_callback_message_struct_t message; + + /* Set KHCI reset flag */ + khciState->isResetting = 1U; + + /* Clear the reset interrupt */ + khciState->registerBase->ISTAT = (kUSB_KhciInterruptReset); +#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + /* Clear the suspend interrupt */ + khciState->registerBase->ISTAT = (kUSB_KhciInterruptSleep); + khciState->registerBase->USBCTRL &= ~USB_USBCTRL_SUSP_MASK; +#endif + + message.buffer = (uint8_t *)NULL; + message.code = kUSB_DeviceNotifyBusReset; + message.length = 0U; + message.isSetup = 0U; + /* Notify up layer the USB bus reset signal detected. */ + USB_DeviceNotificationTrigger(khciState->deviceHandle, &message); +} + +/* The USB suspend and resume signals need to be detected and handled when the low power or remote wakeup function + * enabled. */ +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + +/*! + * @brief Handle the suspend interrupt. + * + * The function is used to handle the suspend interrupt when the suspend signal detected. + * + * @param khciState Pointer of the device KHCI state structure. + * + */ +static void USB_DeviceKhciInterruptSleep(usb_device_khci_state_struct_t *khciState) +{ + usb_device_callback_message_struct_t message; + + /* Enable the resume interrupt */ + khciState->registerBase->INTEN |= kUSB_KhciInterruptResume; + khciState->registerBase->USBTRC0 |= USB_USBTRC0_USBRESMEN_MASK; + khciState->registerBase->USBCTRL |= USB_USBCTRL_SUSP_MASK; + /* Disable the suspend interrupt */ + khciState->registerBase->INTEN &= ~((uint32_t)kUSB_KhciInterruptSleep); + + /* Clear the suspend interrupt */ + khciState->registerBase->ISTAT = (kUSB_KhciInterruptSleep); + /* Clear the resume interrupt */ + khciState->registerBase->ISTAT = (kUSB_KhciInterruptResume); + + message.buffer = (uint8_t *)NULL; + message.code = kUSB_DeviceNotifySuspend; + message.length = 0U; + message.isSetup = 0U; + + /* Notify up layer the USB suspend signal detected. */ + USB_DeviceNotificationTrigger(khciState->deviceHandle, &message); +} + +/*! + * @brief Handle the resume interrupt. + * + * The function is used to handle the resume interrupt when the resume signal detected. + * + * @param khciState Pointer of the device KHCI state structure. + * + */ +static void USB_DeviceKhciInterruptResume(usb_device_khci_state_struct_t *khciState) +{ + usb_device_callback_message_struct_t message; + + khciState->registerBase->USBCTRL &= ~USB_USBCTRL_SUSP_MASK; + /* Enable the suspend interrupt */ + khciState->registerBase->INTEN |= kUSB_KhciInterruptSleep; + /* Disable the resume interrupt */ + khciState->registerBase->INTEN &= ~((uint32_t)kUSB_KhciInterruptResume); + khciState->registerBase->USBTRC0 &= ~USB_USBTRC0_USBRESMEN_MASK; + + /* Clear the resume interrupt */ + khciState->registerBase->ISTAT = (kUSB_KhciInterruptResume); + /* Clear the suspend interrupt */ + khciState->registerBase->ISTAT = (kUSB_KhciInterruptSleep); + + message.buffer = (uint8_t *)NULL; + message.code = kUSB_DeviceNotifyResume; + message.length = 0U; + message.isSetup = 0U; + + /* Notify up layer the USB resume signal detected. */ + USB_DeviceNotificationTrigger(khciState->deviceHandle, &message); +} +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ + +#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED) && (FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED > 0U)) +/*! + * @brief Handle the VBUS rising interrupt. + * + * The function is used to handle the VBUS rising interrupt when the VBUS rising signal detected. + * + * @param khciState Pointer of the device KHCI state structure. + * + */ +static void USB_DeviceKhciInterruptVbusRising(usb_device_khci_state_struct_t *khciState) +{ + usb_device_callback_message_struct_t message; + + /* Disable the VBUS rising interrupt */ + khciState->registerBase->MISCCTRL &= ~USB_MISCCTRL_VREDG_EN_MASK; + /* Enable the VBUS rising interrupt */ + khciState->registerBase->MISCCTRL |= USB_MISCCTRL_VREDG_EN_MASK; + + message.buffer = (uint8_t *)NULL; + message.code = kUSB_DeviceNotifyAttach; + message.length = 0U; + message.isSetup = 0U; + + /* Notify up layer the USB VBUS rising signal detected. */ + USB_DeviceNotificationTrigger(khciState->deviceHandle, &message); +} + +/*! + * @brief Handle the VBUS falling interrupt. + * + * The function is used to handle the VBUS falling interrupt when the VBUS falling signal detected. + * + * @param khciState Pointer of the device KHCI state structure. + * + */ +static void USB_DeviceKhciInterruptVbusFalling(usb_device_khci_state_struct_t *khciState) +{ + usb_device_callback_message_struct_t message; + + /* Disable the VBUS rising interrupt */ + khciState->registerBase->MISCCTRL &= ~USB_MISCCTRL_VFEDG_EN_MASK; + /* Enable the VBUS rising interrupt */ + khciState->registerBase->MISCCTRL |= USB_MISCCTRL_VFEDG_EN_MASK; + + message.buffer = (uint8_t *)NULL; + message.code = kUSB_DeviceNotifyDetach; + message.length = 0U; + message.isSetup = 0U; + + /* Notify up layer the USB VBUS falling signal detected. */ + USB_DeviceNotificationTrigger(khciState->deviceHandle, &message); +} +#endif /* USB_DEVICE_CONFIG_DETACH_ENABLE || FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED */ + +#if 0U +/*! + * @brief Handle the sof interrupt. + * + * The function is used to handle the sof interrupt. + * + * @param khciState Pointer of the device KHCI state structure. + * + */ +void USB_DeviceKhciInterruptSof(usb_device_khci_state_struct_t *khciState) +{ + khciState->registerBase->ISTAT = (kUSB_KhciInterruptSofToken); + + khciState->registerBase->ISTAT = (kUSB_KhciInterruptResume); +} +#endif + +/*! + * @brief Handle endpoint stalled interrupt. + * + * The function is used to handle endpoint stalled interrupt. + * + * @param khciState Pointer of the device KHCI state structure. + * + */ +static void USB_DeviceKhciInterruptStall(usb_device_khci_state_struct_t *khciState) +{ + /* Clear the endpoint stalled interrupt flag */ + while (khciState->registerBase->ISTAT & (kUSB_KhciInterruptStall)) + { + khciState->registerBase->ISTAT = (kUSB_KhciInterruptStall); + } + + /* Un-stall the control in and out pipe when the control in or out pipe stalled. */ + if ((khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_IN].stateUnion.stateBitField.stalled) || + (khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.stalled)) + { + USB_DeviceKhciEndpointUnstall( + khciState, (USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))); + USB_DeviceKhciEndpointUnstall( + khciState, (USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))); + } +} + +#if defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U) +static void USB_DeviceKhciInterruptError(usb_device_khci_state_struct_t *khciState) +{ + usb_device_callback_message_struct_t message; + + khciState->registerBase->ISTAT = (kUSB_KhciInterruptError); + + message.buffer = (uint8_t *)NULL; + message.code = kUSB_DeviceNotifyError; + message.length = 0U; + message.isSetup = 0U; + + /* Notify up layer the USB error detected. */ + USB_DeviceNotificationTrigger(khciState->deviceHandle, &message); +} +#endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */ + +/*! + * @brief Initialize the USB device KHCI instance. + * + * This function initializes the USB device KHCI module specified by the controllerId. + * + * @param controllerId The controller id of the USB IP. Please refer to enumeration type usb_controller_index_t. + * @param handle Pointer of the device handle, used to identify the device object is belonged to. + * @param khciHandle It is out parameter, is used to return pointer of the device KHCI handle to the caller. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceKhciInit(uint8_t controllerId, + usb_device_handle handle, + usb_device_controller_handle *khciHandle) +{ + usb_device_khci_state_struct_t *khciState; + uint32_t khci_base[] = USB_BASE_ADDRS; +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) + usb_device_dcd_state_struct_t *dcdState; + uint32_t dcd_base[] = USBDCD_BASE_ADDRS; +#endif + + if (((controllerId - kUSB_ControllerKhci0) >= (uint8_t)USB_DEVICE_CONFIG_KHCI) || + ((controllerId - kUSB_ControllerKhci0) >= (sizeof(khci_base) / sizeof(uint32_t)))) + { + return kStatus_USB_ControllerNotFound; + } + khciState = &s_UsbDeviceKhciState[controllerId - kUSB_ControllerKhci0]; + + khciState->controllerId = controllerId; + + khciState->registerBase = (USB_Type *)khci_base[controllerId - kUSB_ControllerKhci0]; + + khciState->dmaAlignBuffer = (uint8_t *)&s_UsbDeviceKhciDmaAlignBuffer[controllerId - kUSB_ControllerKhci0][0]; + + /* Clear all interrupt flags. */ + khciState->registerBase->ISTAT = 0xFFU; + +#if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG)) + khciState->otgStatus = 0U; +#else + /* Disable the device functionality. */ + USB_DeviceKhciControl(khciState, kUSB_DeviceControlStop, NULL); +#endif + + khciState->bdt = s_UsbDeviceKhciBdtBuffer[controllerId - kUSB_ControllerKhci0]; + + /* Set BDT buffer address */ + khciState->registerBase->BDTPAGE1 = (uint8_t)((((uint32_t)khciState->bdt) >> 8U) & 0xFFU); + khciState->registerBase->BDTPAGE2 = (uint8_t)((((uint32_t)khciState->bdt) >> 16U) & 0xFFU); + khciState->registerBase->BDTPAGE3 = (uint8_t)((((uint32_t)khciState->bdt) >> 24U) & 0xFFU); + +#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED) && (FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED > 0U)) + khciState->registerBase->MISCCTRL |= USB_MISCCTRL_VREDG_EN_MASK | USB_MISCCTRL_VFEDG_EN_MASK; +#endif + +#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \ + defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \ + defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U) + khciState->registerBase->CLK_RECOVER_CTRL |= USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK; + khciState->registerBase->KEEP_ALIVE_CTRL = + USB_KEEP_ALIVE_CTRL_KEEP_ALIVE_EN_MASK | USB_KEEP_ALIVE_CTRL_OWN_OVERRD_EN_MASK | + USB_KEEP_ALIVE_CTRL_WAKE_INT_EN_MASK | FSL_FEATURE_USB_KHCI_KEEP_ALIVE_MODE_CONTROL; + /* wake on out and setup transaction */ + khciState->registerBase->KEEP_ALIVE_WKCTRL = 0x1U; +#if defined(FSL_FEATURE_SOC_MCGLITE_COUNT) && (FSL_FEATURE_SOC_MCGLITE_COUNT > 0U) + MCG->MC |= MCG_MC_HIRCLPEN_MASK; +#endif + +#endif +#if defined(FSL_FEATURE_USB_KHCI_HAS_STALL_LOW) && (FSL_FEATURE_USB_KHCI_HAS_STALL_LOW > 0U) + khciState->registerBase->MISCCTRL |= USB_MISCCTRL_STL_ADJ_EN_MASK; +#endif + + /* Set KHCI device state to default value. */ + USB_DeviceKhciSetDefaultState(khciState); + + *khciHandle = khciState; + khciState->deviceHandle = (usb_device_struct_t *)handle; +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) + dcdState = &s_UsbDeviceDcdState[controllerId - kUSB_ControllerKhci0]; + + dcdState->controllerId = controllerId; + + dcdState->dcdRegisterBase = (USBDCD_Type *)dcd_base[controllerId - kUSB_ControllerKhci0]; + + dcdState->deviceHandle = (usb_device_struct_t *)handle; +#endif + + return kStatus_USB_Success; +} + +/*! + * @brief De-initialize the USB device KHCI instance. + * + * This function de-initializes the USB device KHCI module. + * + * @param khciHandle Pointer of the device KHCI handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceKhciDeinit(usb_device_controller_handle khciHandle) +{ + usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle; + + if (!khciHandle) + { + return kStatus_USB_InvalidHandle; + } + /* Clear all interrupt flags. */ + khciState->registerBase->ISTAT = 0xFFU; + /* Disable all interrupts. */ + khciState->registerBase->INTEN &= ~(0xFFU); + /* Clear device address. */ + khciState->registerBase->ADDR = (0U); + + /* Clear USB_CTL register */ + khciState->registerBase->CTL = 0x00U; + khciState->registerBase->USBCTRL |= USB_USBCTRL_PDE_MASK | USB_USBCTRL_SUSP_MASK; + + return kStatus_USB_Success; +} + +/*! + * @brief Send data through a specified endpoint. + * + * This function sends data through a specified endpoint. + * + * @param khciHandle Pointer of the device KHCI handle. + * @param endpointAddress Endpoint index. + * @param buffer The memory address to hold the data need to be sent. + * @param length The data length need to be sent. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value just means if the sending request is successful or not; the transfer done is notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceKhciSend(usb_device_controller_handle khciHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length) +{ + usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle; + uint32_t index = ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) << 1U) | USB_IN; + usb_status_t error = kStatus_USB_Error; + + /* Save the transfer information */ + if (0U == khciState->endpointState[index].stateUnion.stateBitField.transferring) + { + khciState->endpointState[index].transferDone = 0U; + khciState->endpointState[index].transferBuffer = buffer; + khciState->endpointState[index].transferLength = length; + khciState->endpointState[index].stateUnion.stateBitField.dmaAlign = 1U; + } + + /* Data length needs to less than max packet size in each call. */ + if (length > khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize) + { + length = khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize; + } + + /* Send data when the device is not resetting. */ + if (0U == khciState->isResetting) + { + error = USB_DeviceKhciEndpointTransfer(khciState, endpointAddress & USB_ENDPOINT_NUMBER_MASK, USB_IN, + (uint8_t *)((uint32_t)khciState->endpointState[index].transferBuffer + + (uint32_t)khciState->endpointState[index].transferDone), + length); + } + + /* Prime a transfer to receive next setup packet if the dat length is zero in a control in endpoint. */ + if ((0U == khciState->endpointState[index].transferDone) && (0U == length) && + (USB_CONTROL_ENDPOINT == (endpointAddress & USB_ENDPOINT_NUMBER_MASK))) + { + USB_DeviceKhciPrimeNextSetup(khciState); + } + return error; +} + +/*! + * @brief Receive data through a specified endpoint. + * + * This function Receives data through a specified endpoint. + * + * @param khciHandle Pointer of the device KHCI handle. + * @param endpointAddress Endpoint index. + * @param buffer The memory address to save the received data. + * @param length The data length want to be received. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value just means if the receiving request is successful or not; the transfer done is notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceKhciRecv(usb_device_controller_handle khciHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length) +{ + usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle; + uint32_t index = ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) << 1U) | USB_OUT; + usb_status_t error = kStatus_USB_Error; + + if ((0U == length) && (USB_CONTROL_ENDPOINT == (endpointAddress & USB_ENDPOINT_NUMBER_MASK))) + { + khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U; + USB_DeviceKhciPrimeNextSetup(khciState); + } + else + { + /* Save the transfer information */ + if (0U == khciState->endpointState[index].stateUnion.stateBitField.transferring) + { + khciState->endpointState[index].transferDone = 0U; + khciState->endpointState[index].transferBuffer = buffer; + khciState->endpointState[index].transferLength = length; + } + khciState->endpointState[index].stateUnion.stateBitField.dmaAlign = 1U; + + /* Data length needs to less than max packet size in each call. */ + if (length > khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize) + { + length = khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize; + } + + buffer = (uint8_t *)((uint32_t)buffer + (uint32_t)khciState->endpointState[index].transferDone); + + if ((khciState->dmaAlignBuffer) && (0U == khciState->isDmaAlignBufferInusing) && + (USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH >= length) && + ((length & 0x03U) || (((uint32_t)buffer) & 0x03U))) + { + khciState->endpointState[index].stateUnion.stateBitField.dmaAlign = 0U; + buffer = khciState->dmaAlignBuffer; + khciState->isDmaAlignBufferInusing = 1U; + } + + /* Receive data when the device is not resetting. */ + if (0U == khciState->isResetting) + { + error = USB_DeviceKhciEndpointTransfer(khciState, endpointAddress & USB_ENDPOINT_NUMBER_MASK, USB_OUT, + buffer, length); + } + } + return error; +} + +/*! + * @brief Cancel the pending transfer in a specified endpoint. + * + * The function is used to cancel the pending transfer in a specified endpoint. + * + * @param khciHandle Pointer of the device KHCI handle. + * @param ep Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceKhciCancel(usb_device_controller_handle khciHandle, uint8_t ep) +{ + usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle; + usb_device_callback_message_struct_t message; + uint8_t index = ((ep & USB_ENDPOINT_NUMBER_MASK) << 1U) | ((ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT); + + /* Cancel the transfer and notify the up layer when the endpoint is busy. */ + if (khciState->endpointState[index].stateUnion.stateBitField.transferring) + { + message.length = USB_UNINITIALIZED_VAL_32; + message.buffer = khciState->endpointState[index].transferBuffer; + message.code = ep; + message.isSetup = 0U; + khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U; + USB_DeviceNotificationTrigger(khciState->deviceHandle, &message); + } + return kStatus_USB_Success; +} + +/*! + * @brief Control the status of the selected item. + * + * The function is used to control the status of the selected item. + * + * @param khciHandle Pointer of the device KHCI handle. + * @param type The selected item. Please refer to enumeration type usb_device_control_type_t. + * @param param The param type is determined by the selected item. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceKhciControl(usb_device_controller_handle khciHandle, usb_device_control_type_t type, void *param) +{ + usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle; + uint16_t *temp16; + uint8_t *temp8; +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) + usb_device_dcd_state_struct_t *dcdState; + dcdState = &s_UsbDeviceDcdState[khciState->controllerId - kUSB_ControllerKhci0]; + usb_device_dcd_charging_time_t *deviceDcdTimingConfig = (usb_device_dcd_charging_time_t *)param; +#endif +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + usb_device_struct_t *deviceHandle; + uint64_t startTick; +#endif + usb_status_t error = kStatus_USB_Error; + + if (!khciHandle) + { + return kStatus_USB_InvalidHandle; + } + +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + deviceHandle = (usb_device_struct_t *)khciState->deviceHandle; +#endif + + switch (type) + { + case kUSB_DeviceControlRun: + khciState->registerBase->USBCTRL = 0U; +#if defined(FSL_FEATURE_USB_KHCI_OTG_ENABLED) && (FSL_FEATURE_USB_KHCI_OTG_ENABLED > 0U) + if (khciState->registerBase->OTGCTL & USB_OTGCTL_OTGEN_MASK) + { + khciState->registerBase->OTGCTL |= USB_OTGCTL_DPHIGH_MASK; + } +#endif /* FSL_FEATURE_USB_KHCI_OTG_ENABLED */ + khciState->registerBase->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK; + khciState->registerBase->CTL |= USB_CTL_USBENSOFEN_MASK; + + error = kStatus_USB_Success; + break; + case kUSB_DeviceControlStop: +#if defined(FSL_FEATURE_USB_KHCI_OTG_ENABLED) && (FSL_FEATURE_USB_KHCI_OTG_ENABLED > 0U) + if (khciState->registerBase->OTGCTL & USB_OTGCTL_OTGEN_MASK) + { + khciState->registerBase->OTGCTL &= ~USB_OTGCTL_DPHIGH_MASK; + } +#endif /* FSL_FEATURE_USB_KHCI_OTG_ENABLED */ + khciState->registerBase->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK; + error = kStatus_USB_Success; + break; + case kUSB_DeviceControlEndpointInit: + if (param) + { + error = USB_DeviceKhciEndpointInit(khciState, (usb_device_endpoint_init_struct_t *)param); + } + break; + case kUSB_DeviceControlEndpointDeinit: + if (param) + { + temp8 = (uint8_t *)param; + error = USB_DeviceKhciEndpointDeinit(khciState, *temp8); + } + break; + case kUSB_DeviceControlEndpointStall: + if (param) + { + temp8 = (uint8_t *)param; + error = USB_DeviceKhciEndpointStall(khciState, *temp8); + } + break; + case kUSB_DeviceControlEndpointUnstall: + if (param) + { + temp8 = (uint8_t *)param; + error = USB_DeviceKhciEndpointUnstall(khciState, *temp8); + } + break; + case kUSB_DeviceControlGetDeviceStatus: + if (param) + { + temp16 = (uint16_t *)param; + *temp16 = (USB_DEVICE_CONFIG_SELF_POWER << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_SELF_POWERED_SHIFT)) +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + | ((uint16_t)(((uint32_t)deviceHandle->remotewakeup) + << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_REMOTE_WARKUP_SHIFT))) +#endif + ; + error = kStatus_USB_Success; + } + break; + case kUSB_DeviceControlGetEndpointStatus: + if (param) + { + usb_device_endpoint_status_struct_t *endpointStatus = (usb_device_endpoint_status_struct_t *)param; + + if (((endpointStatus->endpointAddress) & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS) + { + endpointStatus->endpointStatus = + (uint16_t)( + khciState + ->endpointState[(((endpointStatus->endpointAddress) & USB_ENDPOINT_NUMBER_MASK) << 1U) | + (((endpointStatus->endpointAddress) & + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)] + .stateUnion.stateBitField.stalled == 1U) ? + kUSB_DeviceEndpointStateStalled : + kUSB_DeviceEndpointStateIdle; + error = kStatus_USB_Success; + } + } + break; + case kUSB_DeviceControlSetDeviceAddress: + if (param) + { + temp8 = (uint8_t *)param; + khciState->registerBase->ADDR = (*temp8); + error = kStatus_USB_Success; + } + break; + case kUSB_DeviceControlGetSynchFrame: + break; +#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +#if defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U) + case kUSB_DeviceControlResume: + khciState->registerBase->CTL |= USB_CTL_RESUME_MASK; + startTick = deviceHandle->hwTick; + while ((deviceHandle->hwTick - startTick) < 10) + { + __ASM("nop"); + } + khciState->registerBase->CTL &= ~USB_CTL_RESUME_MASK; + error = kStatus_USB_Success; + break; +#endif /* USB_DEVICE_CONFIG_REMOTE_WAKEUP */ + case kUSB_DeviceControlSuspend: + error = kStatus_USB_Success; + break; +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ + case kUSB_DeviceControlSetDefaultStatus: + for (uint8_t count = 0U; count < USB_DEVICE_CONFIG_ENDPOINTS; count++) + { + USB_DeviceKhciEndpointDeinit(khciState, (count | (USB_IN << 0x07U))); + USB_DeviceKhciEndpointDeinit(khciState, (count | (USB_OUT << 0x07U))); + } + USB_DeviceKhciSetDefaultState(khciState); + error = kStatus_USB_Success; + break; + case kUSB_DeviceControlGetSpeed: + if (param) + { + temp8 = (uint8_t *)param; + *temp8 = USB_SPEED_FULL; + error = kStatus_USB_Success; + } + break; +#if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG)) + case kUSB_DeviceControlGetOtgStatus: + *((uint8_t *)param) = khciState->otgStatus; + break; + case kUSB_DeviceControlSetOtgStatus: + khciState->otgStatus = *((uint8_t *)param); + break; +#endif + case kUSB_DeviceControlSetTestMode: + break; +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) + case kUSB_DeviceControlDcdInitModule: + dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + dcdState->dcdRegisterBase->TIMER0 = USBDCD_TIMER0_TSEQ_INIT(deviceDcdTimingConfig->dcdSeqInitTime); + dcdState->dcdRegisterBase->TIMER1 = USBDCD_TIMER1_TDCD_DBNC(deviceDcdTimingConfig->dcdDbncTime); + dcdState->dcdRegisterBase->TIMER1 |= USBDCD_TIMER1_TVDPSRC_ON(deviceDcdTimingConfig->dcdDpSrcOnTime); + dcdState->dcdRegisterBase->TIMER2_BC12 = + USBDCD_TIMER2_BC12_TWAIT_AFTER_PRD(deviceDcdTimingConfig->dcdTimeWaitAfterPrD); + dcdState->dcdRegisterBase->TIMER2_BC12 |= + USBDCD_TIMER2_BC12_TVDMSRC_ON(deviceDcdTimingConfig->dcdTimeDMSrcOn); + dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_IE_MASK; + dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_BC12_MASK; + dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_START_MASK; + break; + case kUSB_DeviceControlDcdDeinitModule: + dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + break; +#endif + + default: + break; + } + + return error; +} + +/*! + * @brief Handle the KHCI device interrupt. + * + * The function is used to handle the KHCI device interrupt. + * + * @param deviceHandle The device handle got from USB_DeviceInit. + * + */ +void USB_DeviceKhciIsrFunction(void *deviceHandle) +{ + usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle; + usb_device_khci_state_struct_t *khciState; + uint8_t status; + + if (NULL == deviceHandle) + { + return; + } + + khciState = (usb_device_khci_state_struct_t *)(handle->controllerHandle); + + status = khciState->registerBase->ISTAT; +#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \ + defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && \ + defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U) + /* Clear EEP_ALIVE_CTRL_WAKE_INT interrupt state */ + if (khciState->registerBase->KEEP_ALIVE_CTRL & USB_KEEP_ALIVE_CTRL_WAKE_INT_STS_MASK) + { + khciState->registerBase->KEEP_ALIVE_CTRL |= USB_KEEP_ALIVE_CTRL_WAKE_INT_STS_MASK; + } + /* Clear SOFTOK interrupt state */ + if (khciState->registerBase->ISTAT & USB_ISTAT_SOFTOK_MASK) + { + khciState->registerBase->ISTAT = USB_ISTAT_SOFTOK_MASK; + } +#endif +#if defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U) + /* Error interrupt */ + if (status & kUSB_KhciInterruptError) + { + USB_DeviceKhciInterruptError(khciState); + } +#endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */ + /* Token done interrupt */ + if (status & kUSB_KhciInterruptTokenDone) + { + USB_DeviceKhciInterruptTokenDone(khciState); + } + + /* Reset interrupt */ + if (status & kUSB_KhciInterruptReset) + { + USB_DeviceKhciInterruptReset(khciState); + } + +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + /* Suspend interrupt */ + if (status & kUSB_KhciInterruptSleep) + { + USB_DeviceKhciInterruptSleep(khciState); + } + + /* Resume interrupt */ + if (status & kUSB_KhciInterruptResume) + { + USB_DeviceKhciInterruptResume(khciState); + } + + if (khciState->registerBase->USBTRC0 & USB_USBTRC0_USB_RESUME_INT_MASK) + { + USB_DeviceKhciInterruptResume(khciState); + } +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ + + /* Endpoint stalled interrupt */ + if (status & kUSB_KhciInterruptStall) + { + USB_DeviceKhciInterruptStall(khciState); + } + +#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED) && (FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED > 0U)) + if (khciState->registerBase->USBTRC0 & USB_USBTRC0_VREDG_DET_MASK) + { + USB_DeviceKhciInterruptVbusRising(khciState); + } + + if (khciState->registerBase->USBTRC0 & USB_USBTRC0_VFEDG_DET_MASK) + { + USB_DeviceKhciInterruptVbusFalling(khciState); + } +#endif /* USB_DEVICE_CONFIG_DETACH_ENABLE && FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED */ + +#if 0U + /* Sof token interrupt */ + if (status & kUSB_KhciInterruptSofToken) + { + USB_DeviceKhciInterruptSof(khciState); + } +#endif + +#if ((defined FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && \ + (FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED > 0U)) + status = khciState->registerBase->CLK_RECOVER_INT_STATUS; + if (status) + { + /* USB RECOVER interrupt is happened */ + if (USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_MASK & status) + { + /* Indicates that the USB clock recovery algorithm has detected that the frequency trim adjustment needed + * for the IRC48M output clock is outside the available TRIM_FINE adjustment range for the IRC48M + * module. + */ + } + khciState->registerBase->CLK_RECOVER_INT_STATUS = status; + } +#endif +} + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) +/*! + * @brief Handle the device DCD module interrupt. + * + * The function is used to handle the device DCD module interrupt. + * + * @param deviceHandle The device handle got from USB_DeviceInit. + * + */ +void USB_DeviceDcdIsrFunction(void *deviceHandle) +{ + usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle; + usb_device_khci_state_struct_t *khciState; + usb_device_dcd_state_struct_t *dcdState; + uint32_t status; + uint32_t chargerType; + usb_device_callback_message_struct_t message; + + if (NULL == deviceHandle) + { + return; + } + + khciState = (usb_device_khci_state_struct_t *)(handle->controllerHandle); + + dcdState = &s_UsbDeviceDcdState[khciState->controllerId - kUSB_ControllerKhci0]; + + /* Read the STATUS register in the interrupt routine. */ + status = dcdState->dcdRegisterBase->STATUS; + + /* Clear the interrupt flag bit. */ + dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_IACK_MASK; + + message.buffer = (uint8_t *)NULL; + message.length = 0U; + message.isSetup = 0U; + + if (status & USBDCD_STATUS_ERR_MASK) + { + if (status & USBDCD_STATUS_TO_MASK) + { + dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + message.code = kUSB_DeviceNotifyDcdTimeOut; + USB_DeviceNotificationTrigger(dcdState->deviceHandle, &message); + } + else + { + dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + message.code = kUSB_DeviceNotifyDcdUnknownPortType; + USB_DeviceNotificationTrigger(dcdState->deviceHandle, &message); + } + } + else + { + switch (status & USBDCD_STATUS_SEQ_STAT_MASK) + { + case USBDCD_STATUS_SEQ_STAT(kUSB_DcdChargingPortDetectionCompleted): + chargerType = status & USBDCD_STATUS_SEQ_RES_MASK; + if (chargerType == USBDCD_STATUS_SEQ_RES(kUSB_DcdDetectionStandardHost)) + { + dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + message.code = kUSB_DeviceNotifySDPDetected; + USB_DeviceNotificationTrigger(dcdState->deviceHandle, &message); + } + else if (chargerType == USBDCD_STATUS_SEQ_RES(kUSB_DcdDetectionChargingPort)) + { + message.code = kUSB_DeviceNotifyChargingPortDetected; + USB_DeviceNotificationTrigger(dcdState->deviceHandle, &message); + } + break; + case USBDCD_STATUS_SEQ_STAT(kUSB_DcdChargerTypeDetectionCompleted): + chargerType = status & USBDCD_STATUS_SEQ_RES_MASK; + if (chargerType == USBDCD_STATUS_SEQ_RES(kUSB_DcdDetectionChargingPort)) + { + dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + message.code = kUSB_DeviceNotifyChargingHostDetected; + USB_DeviceNotificationTrigger(dcdState->deviceHandle, &message); + } + else if (chargerType == USBDCD_STATUS_SEQ_RES(kUSB_DcdDetectionDedicatedCharger)) + { + dcdState->dcdRegisterBase->CONTROL |= USBDCD_CONTROL_SR_MASK; + message.code = kUSB_DeviceNotifyDedicatedChargerDetected; + USB_DeviceNotificationTrigger(dcdState->deviceHandle, &message); + } + break; + + default: + break; + } + } +} +#endif +#endif /* USB_DEVICE_CONFIG_KHCI */ diff --git a/usb/device/source/khci/usb_device_khci.h b/usb/device/source/khci/usb_device_khci.h new file mode 100644 index 0000000..d0843a1 --- /dev/null +++ b/usb/device/source/khci/usb_device_khci.h @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_KHCI_H__ +#define __USB_DEVICE_KHCI_H__ + +/*! + * @addtogroup usb_device_controller_khci_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief The maximum value of ISO maximum packet size for FS in USB specification 2.0 */ +#define USB_DEVICE_MAX_FS_ISO_MAX_PACKET_SIZE (1023U) + +/*! @brief The maximum value of non-ISO maximum packet size for FS in USB specification 2.0 */ +#define USB_DEVICE_MAX_FS_NONE_ISO_MAX_PACKET_SIZE (64U) + +#define USB_KHCI_BDT_DEVICE_OUT_TOKEN (0x01U) +#define USB_KHCI_BDT_DEVICE_IN_TOKEN (0x09U) +#define USB_KHCI_BDT_DEVICE_SETUP_TOKEN (0x0DU) + +#define USB_KHCI_BDT_OWN (0x80U) +#define USB_KHCI_BDT_DATA01(x) ((((uint32_t)(x)) & 0x01U) << 0x06U) +#define USB_KHCI_BDT_BC(x) ((((uint32_t)(x)) & 0x3FFU) << 0x10U) +#define UBS_KHCI_BDT_KEEP (0x20U) +#define UBS_KHCI_BDT_NINC (0x10U) +#define USB_KHCI_BDT_DTS (0x08U) +#define USB_KHCI_BDT_STALL (0x04U) + +typedef enum _usb_khci_interrupt_type +{ + kUSB_KhciInterruptReset = 0x01U, + kUSB_KhciInterruptError = 0x02U, + kUSB_KhciInterruptSofToken = 0x04U, + kUSB_KhciInterruptTokenDone = 0x08U, + kUSB_KhciInterruptSleep = 0x10U, + kUSB_KhciInterruptResume = 0x20U, + kUSB_KhciInterruptAttach = 0x40U, + kUSB_KhciInterruptStall = 0x80U, +} usb_khci_interrupt_type_t; + +/*! @brief Set BDT buffer address */ +#define USB_KHCI_BDT_SET_ADDRESS(bdt_base, ep, direction, odd, address) \ + *((volatile uint32_t *)((bdt_base & 0xfffffe00U) | (((uint32_t)ep & 0x0fU) << 5U) | \ + (((uint32_t)direction & 1U) << 4U) | (((uint32_t)odd & 1U) << 3U)) + \ + 1U) = address + +/*! @brief Set BDT control fields*/ +#define USB_KHCI_BDT_SET_CONTROL(bdt_base, ep, direction, odd, control) \ + *(volatile uint32_t *)((bdt_base & 0xfffffe00U) | (((uint32_t)ep & 0x0fU) << 5U) | \ + (((uint32_t)direction & 1U) << 4U) | (((uint32_t)odd & 1U) << 3U)) = control + +/*! @brief Get BDT buffer address*/ +#define USB_KHCI_BDT_GET_ADDRESS(bdt_base, ep, direction, odd) \ + (*((volatile uint32_t *)((bdt_base & 0xfffffe00U) | (((uint32_t)ep & 0x0fU) << 5U) | \ + (((uint32_t)direction & 1U) << 4U) | (((uint32_t)odd & 1U) << 3U)) + \ + 1U)) + +/*! @brief Get BDT control fields*/ +#define USB_KHCI_BDT_GET_CONTROL(bdt_base, ep, direction, odd) \ + (*(volatile uint32_t *)((bdt_base & 0xfffffe00U) | (((uint32_t)ep & 0x0fU) << 5U) | \ + (((uint32_t)direction & 1U) << 4U) | (((uint32_t)odd & 1U) << 3U))) + +/*! @brief Endpoint state structure */ +typedef struct _usb_device_khci_endpoint_state_struct +{ + uint8_t *transferBuffer; /*!< Address of buffer containing the data to be transmitted */ + uint32_t transferLength; /*!< Length of data to transmit. */ + uint32_t transferDone; /*!< The data length has been transferred*/ + union + { + uint32_t state; /*!< The state of the endpoint */ + struct + { + uint32_t maxPacketSize : 10U; /*!< The maximum packet size of the endpoint */ + uint32_t stalled : 1U; /*!< The endpoint is stalled or not */ + uint32_t data0 : 1U; /*!< The data toggle of the transaction */ + uint32_t bdtOdd : 1U; /*!< The BDT toggle of the endpoint */ + uint32_t dmaAlign : 1U; /*!< Whether the transferBuffer is DMA aligned or not */ + uint32_t transferring : 1U; /*!< The endpoint is transferring */ + uint32_t zlt : 1U; /*!< zlt flag */ + } stateBitField; + } stateUnion; +} usb_device_khci_endpoint_state_struct_t; + +/*! @brief KHCI state structure */ +typedef struct _usb_device_khci_state_struct +{ + usb_device_struct_t *deviceHandle; /*!< Device handle used to identify the device object belongs to */ + uint8_t *bdt; /*!< BDT buffer address */ + USB_Type *registerBase; /*!< The base address of the register */ + uint8_t setupPacketBuffer[USB_SETUP_PACKET_SIZE * 2]; /*!< The setup request buffer */ + uint8_t *dmaAlignBuffer; /*!< This buffer is used to fix the transferBuffer or transferLength does + not align to 4-bytes when the function USB_DeviceKhciRecv is called. + The macro USB_DEVICE_CONFIG_KHCI_DMA_ALIGN is used to enable or disable this feature. + If the feature is enabled, when the transferBuffer or transferLength does not align to + 4-bytes, + the transferLength is not more than USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH, and + the flag isDmaAlignBufferInusing is zero, the dmaAlignBuffer is used to receive data + and the flag isDmaAlignBufferInusing is set to 1. + When the transfer is done, the received data, kept in dmaAlignBuffer, is copied + to the transferBuffer, and the flag isDmaAlignBufferInusing is cleared. + */ + usb_device_khci_endpoint_state_struct_t + endpointState[USB_DEVICE_CONFIG_ENDPOINTS * 2]; /*!< Endpoint state structures */ + uint8_t isDmaAlignBufferInusing; /*!< The dmaAlignBuffer is used or not */ + uint8_t isResetting; /*!< Is doing device reset or not */ + uint8_t controllerId; /*!< Controller ID */ + uint8_t setupBufferIndex; /*!< A valid setup buffer flag */ +#if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG)) + uint8_t otgStatus; +#endif +} usb_device_khci_state_struct_t; + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + (defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) +typedef struct _usb_device_dcd_state_struct +{ + usb_device_struct_t *deviceHandle; /*!< Device handle used to identify the device object belongs to */ + USBDCD_Type *dcdRegisterBase; /*!< The base address of the dcd module */ + uint8_t controllerId; /*!< Controller ID */ +} usb_device_dcd_state_struct_t; +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name USB device KHCI functions + * @{ + */ + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @brief Initializes the USB device KHCI instance. + * + * This function initializes the USB device KHCI module specified by the controllerId. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration type usb_controller_index_t. + * @param[in] handle Pointer of the device handle used to identify the device object belongs to. + * @param[out] khciHandle An out parameter used to return the pointer of the device KHCI handle to the caller. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceKhciInit(uint8_t controllerId, + usb_device_handle handle, + usb_device_controller_handle *khciHandle); + +/*! + * @brief Deinitializes the USB device KHCI instance. + * + * This function deinitializes the USB device KHCI module. + * + * @param[in] khciHandle Pointer of the device KHCI handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceKhciDeinit(usb_device_controller_handle khciHandle); + +/*! + * @brief Sends data through a specified endpoint. + * + * This function sends data through a specified endpoint. + * + * @param[in] khciHandle Pointer of the device KHCI handle. + * @param[in] endpointAddress Endpoint index. + * @param[in] buffer The memory address to hold the data need to be sent. + * @param[in] length The data length need to be sent. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value indicates whether the sending request is successful or not. The transfer completion is + * notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for a specific endpoint. + * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the + * endpoint + * callback). + */ +usb_status_t USB_DeviceKhciSend(usb_device_controller_handle khciHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! + * @brief Receives data through a specified endpoint. + * + * This function receives data through a specified endpoint. + * + * @param[in] khciHandle Pointer of the device KHCI handle. + * @param[in] endpointAddress Endpoint index. + * @param[in] buffer The memory address to save the received data. + * @param[in] length The data length to be received. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value indicates whether the receiving request is successful or not. The transfer completion is + * notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for a specific endpoint. + * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the + * endpoint + * callback). + */ +usb_status_t USB_DeviceKhciRecv(usb_device_controller_handle khciHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! + * @brief Cancels the pending transfer in a specified endpoint. + * + * The function is used to cancel the pending transfer in a specified endpoint. + * + * @param[in] khciHandle Pointer of the device KHCI handle. + * @param[in] ep Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceKhciCancel(usb_device_controller_handle khciHandle, uint8_t ep); + +/*! + * @brief Controls the status of the selected item. + * + * The function is used to control the status of the selected item. + * + * @param[in] khciHandle Pointer of the device KHCI handle. + * @param[in] type The selected item. See enumeration type usb_device_control_type_t. + * @param[in,out] param The parameter type is determined by the selected item. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceKhciControl(usb_device_controller_handle khciHandle, + usb_device_control_type_t type, + void *param); + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* __USB_DEVICE_KHCI_H__ */ diff --git a/usb/device/source/lpcip3511/usb_device_lpcip3511.c b/usb/device/source/lpcip3511/usb_device_lpcip3511.c new file mode 100644 index 0000000..dfca8a1 --- /dev/null +++ b/usb/device/source/lpcip3511/usb_device_lpcip3511.c @@ -0,0 +1,1883 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device.h" +#include "fsl_device_registers.h" + +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +#include "usb_device_dci.h" +#include "usb_device_lpcip3511.h" + +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + +#define USB_LPC3511IP_INTSTAT_DEV_INT_MASK USBHSD_INTSTAT_DEV_INT_MASK +#define USB_LPC3511IP_INTSTAT_FRAME_INT_MASK USBHSD_INTSTAT_FRAME_INT_MASK + +#define USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AO_MASK USBHSD_DEVCMDSTAT_INTONNAK_AO_MASK +#define USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AI_MASK USBHSD_DEVCMDSTAT_INTONNAK_AI_MASK + +#define USB_LPC3511IP_DEVCMDSTAT_LPM_REWP_MASK USBHSD_DEVCMDSTAT_LPM_REWP_MASK +#define USB_LPC3511IP_DEVCMDSTAT_LPM_REWP_SHIFT USBHSD_DEVCMDSTAT_LPM_REWP_SHIFT + +#define USB_LPC3511IP_DEVCMDSTAT_Speed_MASK USBHSD_DEVCMDSTAT_Speed_MASK + + +#define USB_LPC3511IP_DEVCMDSTAT_DCON_MASK USBHSD_DEVCMDSTAT_DCON_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DEV_EN_MASK USBHSD_DEVCMDSTAT_DEV_EN_MASK +#define USB_LPC3511IP_DEVCMDSTAT_LPM_SUP_MASK USBHSD_DEVCMDSTAT_LPM_SUP_MASK +#define USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK USBHSD_DEVCMDSTAT_FORCE_NEEDCLK_MASK +#define USB_LPC3511IP_DEVCMDSTAT_LPM_SUS_MASK USBHSD_DEVCMDSTAT_LPM_SUS_MASK + +#define USB_LPC3511IP_USB_LPM_HIRD_SW USBHSD_LPM_HIRD_SW + +#define USB_LPC3511IP_DEVCMDSTAT_DEV_ADDR_MASK USBHSD_DEVCMDSTAT_DEV_ADDR_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DSUS_MASK USBHSD_DEVCMDSTAT_DSUS_MASK +#define USB_LPC3511IP_INFO_ERR_CODE_MASK USBHSD_INFO_ERR_CODE_MASK +#define USB_LPC3511IP_DEVCMDSTAT_SETUP_MASK USBHSD_DEVCMDSTAT_SETUP_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DRES_C_MASK USBHSD_DEVCMDSTAT_DRES_C_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DSUS_C_MASK USBHSD_DEVCMDSTAT_DSUS_C_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DCON_C_MASK USBHSD_DEVCMDSTAT_DCON_C_MASK +#else +#define USB_LPC3511IP_INTSTAT_DEV_INT_MASK USB_INTSTAT_DEV_INT_MASK +#define USB_LPC3511IP_INTSTAT_FRAME_INT_MASK USB_INTSTAT_FRAME_INT_MASK + +#define USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AO_MASK USB_DEVCMDSTAT_INTONNAK_AO_MASK +#define USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AI_MASK USB_DEVCMDSTAT_INTONNAK_AI_MASK + +#define USB_LPC3511IP_DEVCMDSTAT_LPM_REWP_MASK USB_DEVCMDSTAT_LPM_REWP_MASK +#define USB_LPC3511IP_DEVCMDSTAT_LPM_REWP_SHIFT USB_DEVCMDSTAT_LPM_REWP_SHIFT + + +#define USB_LPC3511IP_DEVCMDSTAT_DCON_MASK USB_DEVCMDSTAT_DCON_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DEV_EN_MASK USB_DEVCMDSTAT_DEV_EN_MASK +#define USB_LPC3511IP_DEVCMDSTAT_LPM_SUP_MASK USB_DEVCMDSTAT_LPM_SUP_MASK +#define USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK USB_DEVCMDSTAT_FORCE_NEEDCLK_MASK +#define USB_LPC3511IP_DEVCMDSTAT_LPM_SUP_MASK USB_DEVCMDSTAT_LPM_SUP_MASK +#define USB_LPC3511IP_DEVCMDSTAT_LPM_SUS_MASK USB_DEVCMDSTAT_LPM_SUS_MASK + +#define USB_LPC3511IP_USB_LPM_HIRD_SW USB_LPM_HIRD_SW + +#define USB_LPC3511IP_DEVCMDSTAT_DEV_ADDR_MASK USB_DEVCMDSTAT_DEV_ADDR_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DSUS_MASK USB_DEVCMDSTAT_DSUS_MASK +#define USB_LPC3511IP_INFO_ERR_CODE_MASK USB_INFO_ERR_CODE_MASK +#define USB_LPC3511IP_DEVCMDSTAT_SETUP_MASK USB_DEVCMDSTAT_SETUP_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DRES_C_MASK USB_DEVCMDSTAT_DRES_C_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DSUS_C_MASK USB_DEVCMDSTAT_DSUS_C_MASK +#define USB_LPC3511IP_DEVCMDSTAT_DCON_C_MASK USB_DEVCMDSTAT_DCON_C_MASK + +#endif + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* on Aruba IP3511 (USB0 FS), there are 8 physical EPs, on IP3511 HS (USB1 FS), there are 10 physical EPs. */ +#define USB_LPC3511IP_MAX_PHY_ENDPOINT_MASK (0xFFFFu) + +/*! @brief endpoint command status, buffer address offset */ +#define USB_LPC3511IPHS_ENDPOINT_BUFFER_ADDRESS_OFFSET_MASK (0x000007FFu) +#define USB_LPC3511IPHS_ENDPOINT_BUFFER_NBYTES_SHIFT (11) +#define USB_LPC3511IPHS_ENDPOINT_BUFFER_NBYTES_MASK (0x03FFF800u) +#define USB_LPC3511IPFS_ENDPOINT_BUFFER_ADDRESS_OFFSET_MASK (0x0000FFFFu) +#define USB_LPC3511IPFS_ENDPOINT_BUFFER_NBYTES_SHIFT (16) +#define USB_LPC3511IPFS_ENDPOINT_BUFFER_NBYTES_MASK (0x03FF0000u) + +#define USB_LPC3511IP_ENDPOINT_ENDPOINT_TYPE_MASK (0x01U << 26) +#define USB_LPC3511IP_ENDPOINT_RFTV_MASK (0x01U << 27) +#define USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK (0x01U << 28) +#define USB_LPC3511IP_ENDPOINT_STALL_MASK (0x01U << 29) +#define USB_LPC3511IP_ENDPOINT_STALL_SHIFT (29) +#define USB_LPC3511IP_ENDPOINT_DISABLE_MASK (0x01U << 30) +#define USB_LPC3511IP_ENDPOINT_ACTIVE_MASK (0x01U << 31) +#define USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT (26) + +#define USB_LPC3511IP_DEVCMDSTAT_INTERRUPT_WC_MASK (0x0F000000u) + +#define USB_LPC3511IP_ENDPOINT_SET_ENDPOINT_AND(lpcState, index, odd, value) \ + *((volatile uint32_t *)(((uint32_t)(lpcState->epCommandStatusList)) | ((uint32_t)(index) << 3) | \ + (((uint32_t)(odd)&1U) << 2U))) &= (value) + +/*! @brief Set endpoint command/status value */ +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) +#define USB_LPC3511IP_ENDPOINT_SET_ENDPOINT(lpcState, index, odd, value, NBytes, address) \ + \ + *((volatile uint32_t *)(((uint32_t)(lpcState->epCommandStatusList)) | ((uint32_t)(index) << 3) | \ + (((uint32_t)(odd & 1U)) << 2U))) = \ + ((lpc3511IpState->controllerSpeed) ? \ + \ + ((uint32_t)(value) | ((uint32_t)(NBytes) << USB_LPC3511IPHS_ENDPOINT_BUFFER_NBYTES_SHIFT) | \ + (((uint32_t)(address) >> 6) & USB_LPC3511IPHS_ENDPOINT_BUFFER_ADDRESS_OFFSET_MASK)) : \ + \ + ((uint32_t)(value) | ((uint32_t)(NBytes) << USB_LPC3511IPFS_ENDPOINT_BUFFER_NBYTES_SHIFT) | \ + (((uint32_t)(address) >> 6) & USB_LPC3511IPFS_ENDPOINT_BUFFER_ADDRESS_OFFSET_MASK))) +#else +#define USB_LPC3511IP_ENDPOINT_SET_ENDPOINT(lpcState, index, odd, value, NBytes, address) \ + \ + *((volatile uint32_t *)(((uint32_t)(lpcState->epCommandStatusList)) | ((uint32_t)(index) << 3) | \ + (((uint32_t)(odd & 1U)) << 2U))) = \ + ((uint32_t)(value) | ((uint32_t)(NBytes) << USB_LPC3511IPFS_ENDPOINT_BUFFER_NBYTES_SHIFT) | \ + (((uint32_t)(address) >> 6) & USB_LPC3511IPFS_ENDPOINT_BUFFER_ADDRESS_OFFSET_MASK)) +#endif + +#define USB_LPC3511IP_ENDPOINT_DES_INDEX(endpoint) \ + (((((uint32_t)endpoint) & 0x0F) << 1) + \ + ((((uint32_t)endpoint) & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ? (1) : (0))) + +#define USB_LPC3511IP_GET_MULTIPLE_OF_64(n) ((n + 63U) & 0xFFFFFFC0U) + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +extern usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg); +static usb_status_t USB_DeviceLpc3511IpTransaction(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + usb_device_lpc3511ip_endpoint_state_struct_t *epState, + uint8_t endpointIndex); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* define the reserved buffer for endpoint max packet copy */ +#if defined(USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) && (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint32_t + s_EpReservedBuffer[USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY][USB_DATA_ALIGN_SIZE_MULTIPLE( + (USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE >> 2))]; +#endif +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint8_t + s_ControlTransferData[USB_DEVICE_CONFIG_LPCIP3511FS + + USB_DEVICE_CONFIG_LPCIP3511HS][USB_DATA_ALIGN_SIZE_MULTIPLE(64U)]; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint8_t + s_SetupData[USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS][USB_DATA_ALIGN_SIZE_MULTIPLE(8U)]; +USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint8_t + s_ZeroTransactionData[USB_DEVICE_CONFIG_LPCIP3511FS + + USB_DEVICE_CONFIG_LPCIP3511HS][USB_DATA_ALIGN_SIZE_MULTIPLE(4)]; +static usb_device_lpc3511ip_state_struct_t + s_UsbDeviceLpc3511IpState[USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS]; + +/* LPC3511IP controller driver instances and endpoint command/status list, EPLISTSTART's value is the buffer pointer. */ +#if ((USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS) == 1U) +USB_CONTROLLER_DATA USB_RAM_ADDRESS_ALIGNMENT(256) static uint32_t + s_EpCommandStatusList1[((USB_DEVICE_IP3511_ENDPOINTS_NUM)) * 4]; +#define LPC_CONTROLLER_ENDPOINT_LIST_ARRAY \ + { \ + &s_EpCommandStatusList1[0] \ + } + +#elif((USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS) == 2U) +USB_CONTROLLER_DATA USB_RAM_ADDRESS_ALIGNMENT(256) static uint32_t + s_EpCommandStatusList1[((USB_DEVICE_IP3511_ENDPOINTS_NUM ) * 4]; +USB_CONTROLLER_DATA USB_RAM_ADDRESS_ALIGNMENT(256) static uint32_t + s_EpCommandStatusList2[((USB_DEVICE_IP3511_ENDPOINTS_NUM ) * 4]; +#define LPC_CONTROLLER_ENDPOINT_LIST_ARRAY \ + { \ + &s_EpCommandStatusList1[0], &s_EpCommandStatusList2[0] \ + } + +#else +#error "increase the instance count." +#endif + +#if (defined USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) +#if (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY == (USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS)) +#define USB_DEVICE_IP3511_ALL_IP_SUPPORT_RESERVED_BUFFER 1u +#elif((USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY == USB_DEVICE_CONFIG_LPCIP3511FS) && (!USB_DEVICE_CONFIG_LPCIP3511HS)) +#define USB_DEVICE_IP3511_ALL_IP_SUPPORT_RESERVED_BUFFER 1u +#elif((USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY == USB_DEVICE_CONFIG_LPCIP3511HS) && (!USB_DEVICE_CONFIG_LPCIP3511FS)) +#define USB_DEVICE_IP3511_ALL_IP_SUPPORT_RESERVED_BUFFER 1u +#else +#define USB_DEVICE_IP3511_ALL_IP_SUPPORT_RESERVED_BUFFER 0u +#endif + +#else +#define USB_DEVICE_IP3511_ALL_IP_SUPPORT_RESERVED_BUFFER 0u + +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if (defined USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) && (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) + +static inline uint8_t USB_DeviceLpcIp3511MaxPacketNeedCopy(usb_device_lpc3511ip_state_struct_t *lpc3511IpState) +{ +#if (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY == (USB_DEVICE_CONFIG_LPCIP3511HS + USB_DEVICE_CONFIG_LPCIP3511FS)) + return 1u; +#elif(USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY == USB_DEVICE_CONFIG_LPCIP3511HS) + return (lpc3511IpState->controllerSpeed); +#elif(USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY == USB_DEVICE_CONFIG_LPCIP3511FS) +#if (defined USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS) + if (lpc3511IpState->controllerSpeed) + { + return 0u; + } + else + { + return 1u; + } +#else + return 1u; +#endif +#endif +} + +static uint8_t *USB_DeviceLpcIp3511MallocMaxPacketBuffer(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + uint32_t multile64) +{ + uint32_t bitsIndex; + uint8_t numIndex; + USB_OSA_SR_ALLOC(); + + multile64 = ((multile64 + 63) / 64); + bitsIndex = 0; + USB_OSA_ENTER_CRITICAL(); + do + { + numIndex = 0; + for (; numIndex < multile64; ++numIndex) + { + if (bitsIndex >= USB_DEVICE_IP3511_BITS_FOR_RESERVED_BUFFER) + { + USB_OSA_EXIT_CRITICAL(); + return NULL; /* fail */ + } + if (lpc3511IpState->epReservedBufferBits[(bitsIndex / 8)] & + (uint8_t)(0x01u << (bitsIndex & 0x00000007u))) /* has allocated */ + { + bitsIndex++; + break; + } + bitsIndex++; + } + } while (numIndex < multile64); + + if (numIndex >= multile64) + { + /* set the bits */ + for (numIndex = 0; numIndex < multile64; ++numIndex) + { + lpc3511IpState->epReservedBufferBits[((bitsIndex - multile64 + numIndex) / 8)] |= + (uint8_t)(0x01u << ((bitsIndex - multile64 + numIndex) & 0x00000007u)); + } + USB_OSA_EXIT_CRITICAL(); + return lpc3511IpState->epReservedBuffer + ((bitsIndex - multile64) * 64); + } + else + { + USB_OSA_EXIT_CRITICAL(); + return NULL; + } +} + +static void USB_DeviceLpcIp3511ReleaseMaxPacketBuffer(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + uint8_t *buffer, + uint32_t bufferSize) +{ + uint32_t bitsIndex; + uint8_t bitsNum; + USB_OSA_SR_ALLOC(); + + if ((buffer < lpc3511IpState->epReservedBuffer) || + (buffer >= (lpc3511IpState->epReservedBuffer + USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE))) + { + return; + } + bitsIndex = (buffer - lpc3511IpState->epReservedBuffer) / 64; + + USB_OSA_ENTER_CRITICAL(); + for (bitsNum = 0; bitsNum < ((bufferSize + 63) / 64); ++bitsNum) + { + lpc3511IpState->epReservedBufferBits[((bitsIndex + bitsNum) / 8)] &= + (uint8_t)(~(0x01u << ((bitsIndex + bitsNum) & 0x00000007u))); /* clear the bit */ + } + USB_OSA_EXIT_CRITICAL(); +} +#endif + +static usb_device_lpc3511ip_endpoint_state_struct_t *USB_DeviceLpc3511IpGetEndpointStateStruct( + usb_device_lpc3511ip_state_struct_t *lpc3511IpState, uint8_t endpointIndex) +{ + if (endpointIndex <= (USB_DEVICE_IP3511_ENDPOINTS_NUM * 2)) + { + return &(lpc3511IpState->endpointState[endpointIndex]); + } + + return NULL; +} + +/*! + * @brief Write the command/status entry to start a transfer. + * + * The function is used to start a transfer by writing the command/status entry. + * + * @param lpc3511IpState Pointer of the controller state structure. + * @param endpoint Endpoint number. + * @param direction The direction of the endpoint, 0U - USB_OUT, 1U - USB_IN. + * @param buffer The memory address to save the received data, or the memory address to hold the data need to + * be sent. + * @param length The length of the data. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceLpc3511IpEndpointPrime(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + usb_device_lpc3511ip_endpoint_state_struct_t *epState, + uint8_t endpointIndex, + uint8_t *buffer, + uint32_t length) +{ + uint8_t odd; + + USB_OSA_SR_ALLOC(); + + /* Enter critical */ + USB_OSA_ENTER_CRITICAL(); + + /* Flag the endpoint is busy. */ + epState->stateUnion.stateBitField.transferring = 1U; + + /* update the endpoint status */ + epState->transferPrimedLength += length; +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + if ((endpointIndex >> 1U) != USB_ENDPOINT_CONTROL) + { + odd = epState->stateUnion.stateBitField.producerOdd; + epState->stateUnion.stateBitField.doubleBufferBusy++; + epState->stateUnion.stateBitField.producerOdd ^= 1; + } + else +#endif + { + odd = 0U; + } + epState->epBufferStatusUnion[odd].epBufferStatusField.transactionLength = length; + + /* when receive the zero length packet, the controller will set 4 bytes buffer as 0x00 */ + if (buffer == NULL) + { + buffer = lpc3511IpState->zeroTransactionData; + } + + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT( + lpc3511IpState, endpointIndex, odd, + (epState->stateUnion.stateBitField.epControlDefault << USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT) | + USB_LPC3511IP_ENDPOINT_ACTIVE_MASK, + length, (uint32_t)buffer); + if (epState->stateUnion.stateBitField.epControlDefault & + ((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT)) + { + epState->stateUnion.stateBitField.epControlDefault &= + (~((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT)); + } + /* Exit critical */ + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; +} + +#if 0 +/*! + * @brief Prime a next setup transfer. + * + * The function is used to prime a buffer in control out pipe to wait for receiving the host's setup packet. + * + * @param lpc3511IpState Pointer of the controller state structure. + * + */ +static void USB_DeviceLpc3511IpPrimeNextSetup(usb_device_lpc3511ip_state_struct_t *lpc3511IpState) +{ + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT(lpc3511IpState, 0, 1, 0, 8, lpc3511IpState->setupData); +} +#endif + +/*! + * @brief reset ip3511. + * + * @param lpc3511IpState Pointer of the controller state structure. + * + */ +static void USB_DeviceLpc3511IpSetDefaultState(usb_device_lpc3511ip_state_struct_t *lpc3511IpState) +{ + uint32_t index = 0; + uint8_t usbAddress; + + /* zero the command/status list buffer and disable all endpoints */ + for (index = 0; index < 4; ++index) + { + lpc3511IpState->epCommandStatusList[index] = 0x00000000U; + } + for (index = 4; index < USB_DEVICE_IP3511_ENDPOINTS_NUM * 4; ++index) + { + lpc3511IpState->epCommandStatusList[index] = USB_LPC3511IP_ENDPOINT_DISABLE_MASK; + } + + /* set address as 0 */ + usbAddress = 0U; + USB_DeviceLpc3511IpControl(lpc3511IpState, kUSB_DeviceControlSetDeviceAddress, &usbAddress); + + lpc3511IpState->registerBase->EPLISTSTART = (uint32_t)lpc3511IpState->epCommandStatusList; +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + if (lpc3511IpState->controllerSpeed) + { + if ((USB_DATABUFSTART_DA_BUF_MASK & (uint32_t)lpc3511IpState->setupData) != + lpc3511IpState->registerBase->DATABUFSTART) + { + /* please use the dedicated ram */ + } + } + else +#endif + { + /* all data buffer is in the same 4M range with this setup data buffer */ + ((USB_Type *)(lpc3511IpState->registerBase))->DATABUFSTART = (uint32_t)lpc3511IpState->setupData; + } + /* reset registers */ + lpc3511IpState->registerBase->EPINUSE = 0x0; + lpc3511IpState->registerBase->EPSKIP = 0x0; +/* enable all double-buffer */ +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + lpc3511IpState->registerBase->EPBUFCFG = USB_LPC3511IP_MAX_PHY_ENDPOINT_MASK; +#else + lpc3511IpState->registerBase->EPBUFCFG = 0x00000000u; +#endif + /* clear interrupts */ + lpc3511IpState->registerBase->INTSTAT = + (USB_LPC3511IP_INTSTAT_DEV_INT_MASK | USB_LPC3511IP_INTSTAT_FRAME_INT_MASK | USB_LPC3511IP_MAX_PHY_ENDPOINT_MASK); + /* enable interrupts */ + lpc3511IpState->registerBase->INTEN = USB_LPC3511IP_INTSTAT_DEV_INT_MASK | USB_LPC3511IP_MAX_PHY_ENDPOINT_MASK; + + /* Clear reset flag */ + lpc3511IpState->isResetting = 0U; +} + +/* Config and Enable endpoint */ +static usb_status_t USB_DeviceLpc3511IpEndpointInit(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + usb_device_endpoint_init_struct_t *epInit) +{ + uint8_t endpointIndex = USB_LPC3511IP_ENDPOINT_DES_INDEX(epInit->endpointAddress); + usb_device_lpc3511ip_endpoint_state_struct_t *epState = + USB_DeviceLpc3511IpGetEndpointStateStruct(lpc3511IpState, endpointIndex); + uint16_t maxPacketSize = epInit->maxPacketSize; + + /* clear the endpoint status bits */ + epState->stateUnion.state = 0x00000000u; + lpc3511IpState->registerBase->EPINUSE &= (~(0x01u << endpointIndex)); + /* Save the max packet size of the endpoint */ + epState->stateUnion.stateBitField.maxPacketSize = maxPacketSize; + /* Set the ZLT field */ + epState->stateUnion.stateBitField.zlt = epInit->zlt; + epState->stateUnion.stateBitField.endpointType = epInit->transferType; + + /* get the endpoint default control value */ + if (USB_ENDPOINT_ISOCHRONOUS == epInit->transferType) + { + epState->stateUnion.stateBitField.epControlDefault = + (USB_LPC3511IP_ENDPOINT_ENDPOINT_TYPE_MASK >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT); + } + else + { + epState->stateUnion.stateBitField.epControlDefault = 0x00U; + } + /* set the command/status value */ + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT( + lpc3511IpState, endpointIndex, 0, + (epState->stateUnion.stateBitField.epControlDefault << USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT), 0, 0); + if ((epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK) == USB_CONTROL_ENDPOINT) + { + if (!(epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK)) + { + /* Prime setup packet when the endpoint is control out endpoint. */ + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT(lpc3511IpState, 0, 1, 0, 0, (uint32_t)lpc3511IpState->setupData); + } + } + else + { + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT( + lpc3511IpState, endpointIndex, 1, + (epState->stateUnion.stateBitField.epControlDefault << USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT), 0, 0); + } + if ((endpointIndex >> 1) != USB_CONTROL_ENDPOINT) + { + /* toggle reset for the toggle */ + epState->stateUnion.stateBitField.epControlDefault |= + ((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT); + } + + epState->epPacketBuffer = NULL; + if ((endpointIndex >> 1U) == USB_CONTROL_ENDPOINT) /* control endpoint */ + { + epState->epPacketBuffer = lpc3511IpState->controlData; + } +#if (defined USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) && (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) + else + { + if (USB_DeviceLpcIp3511MaxPacketNeedCopy(lpc3511IpState)) + { +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + uint8_t *maxPacketBuffer = USB_DeviceLpcIp3511MallocMaxPacketBuffer( + lpc3511IpState, USB_LPC3511IP_GET_MULTIPLE_OF_64(maxPacketSize) * 2); +#else + uint8_t *maxPacketBuffer = USB_DeviceLpcIp3511MallocMaxPacketBuffer(lpc3511IpState, maxPacketSize); +#endif + if (maxPacketBuffer == NULL) + { + return kStatus_USB_AllocFail; + } + epState->epPacketBuffer = maxPacketBuffer; + } + } +#endif + + return kStatus_USB_Success; +} + +/*! + * @brief De-initialize a specified endpoint. + * + * The function is used to de-initialize a specified endpoint. + * Current transfer of the endpoint will be canceled and the specified endpoint will be disabled. + * + * @param lpc3511IpState Pointer of the controller state structure. + * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceLpc3511IpEndpointDeinit(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, uint8_t ep) +{ + uint8_t endpointIndex = USB_LPC3511IP_ENDPOINT_DES_INDEX(ep); + usb_device_lpc3511ip_endpoint_state_struct_t *epState = + USB_DeviceLpc3511IpGetEndpointStateStruct(lpc3511IpState, endpointIndex); + + /* Cancel the transfer of the endpoint */ + USB_DeviceLpc3511IpCancel(lpc3511IpState, ep); + +#if (defined USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) && (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY) + if (USB_DeviceLpcIp3511MaxPacketNeedCopy(lpc3511IpState)) + { + if ((endpointIndex >> 1U) != USB_CONTROL_ENDPOINT) /* control endpoint */ + { +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + USB_DeviceLpcIp3511ReleaseMaxPacketBuffer( + lpc3511IpState, epState->epPacketBuffer, + USB_LPC3511IP_GET_MULTIPLE_OF_64(epState->stateUnion.stateBitField.maxPacketSize) * 2); +#else + USB_DeviceLpcIp3511ReleaseMaxPacketBuffer(lpc3511IpState, epState->epPacketBuffer, + epState->stateUnion.stateBitField.maxPacketSize); +#endif + } + epState->epPacketBuffer = NULL; + } +#endif + + /* reset the double buffer */ + lpc3511IpState->registerBase->EPINUSE &= ~(0x01U << endpointIndex); + /* Disable the endpoint */ + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT(lpc3511IpState, endpointIndex, 0, USB_LPC3511IP_ENDPOINT_DISABLE_MASK, 0, 0); + /* Clear the max packet size */ + epState->stateUnion.stateBitField.maxPacketSize = 0U; + + return kStatus_USB_Success; +} + +/*! + * @brief Stall a specified endpoint. + * + * The function is used to stall a specified endpoint. + * Current transfer of the endpoint will be canceled and the specified endpoint will be stalled. + * + * @param lpc3511IpState Pointer of the controller state structure. + * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceLpc3511IpEndpointStall(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, uint8_t ep) +{ + uint8_t endpointIndex = USB_LPC3511IP_ENDPOINT_DES_INDEX(ep); + usb_device_lpc3511ip_endpoint_state_struct_t *epState = + USB_DeviceLpc3511IpGetEndpointStateStruct(lpc3511IpState, endpointIndex); + + /* Set endpoint stall flag. */ + epState->stateUnion.stateBitField.stalled = 1U; + /* lpc3511IpState->registerBase->EPINUSE &= (~(0x01u << endpointIndex)); */ + /* stall the endpoint */ + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT(lpc3511IpState, endpointIndex, 0, USB_LPC3511IP_ENDPOINT_STALL_MASK, 0, 0); + if ((ep & USB_ENDPOINT_NUMBER_MASK) != USB_CONTROL_ENDPOINT) + { + /* toggle reset for the toggle */ + epState->stateUnion.stateBitField.epControlDefault |= + ((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT); + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT(lpc3511IpState, endpointIndex, 1, USB_LPC3511IP_ENDPOINT_STALL_MASK, 0, 0); + } +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + if ((lpc3511IpState->controllerSpeed) && (USB_ENDPOINT_INTERRUPT == epState->stateUnion.stateBitField.endpointType)) + { + lpc3511IpState->registerBase->DEVCMDSTAT |= (USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AO_MASK | USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AI_MASK); + epState->stateUnion.stateBitField.epControlDefault &= + (~((USB_LPC3511IP_ENDPOINT_ENDPOINT_TYPE_MASK | USB_LPC3511IP_ENDPOINT_RFTV_MASK) >> + USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT)); + } +#endif + + /* cancel the transfer in the endpoint */ + USB_DeviceLpc3511IpCancel(lpc3511IpState, ep); + return kStatus_USB_Success; +} + +/*! + * @brief Un-stall a specified endpoint. + * + * The function is used to un-stall a specified endpoint. + * Current transfer of the endpoint will be canceled and the specified endpoint will be un-stalled. + * + * @param lpc3511IpState Pointer of the controller state structure. + * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceLpc3511IpEndpointUnstall(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, uint8_t ep) +{ + uint8_t endpointIndex = USB_LPC3511IP_ENDPOINT_DES_INDEX(ep); + usb_device_lpc3511ip_endpoint_state_struct_t *epState = + USB_DeviceLpc3511IpGetEndpointStateStruct(lpc3511IpState, endpointIndex); + + /* Clear the endpoint stall state, the hardware resets the endpoint + * toggle to one for both directions when a setup token is received */ + epState->stateUnion.stateBitField.stalled = 0U; + + /* unstall the endpoint for double buffers */ + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT_AND(lpc3511IpState, endpointIndex, 0, (~USB_LPC3511IP_ENDPOINT_STALL_MASK)); + if ((ep & USB_ENDPOINT_NUMBER_MASK) != USB_CONTROL_ENDPOINT) + { + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT_AND(lpc3511IpState, endpointIndex, 1, (~USB_LPC3511IP_ENDPOINT_STALL_MASK)); + + /* toggle reset for the toggle */ + epState->stateUnion.stateBitField.epControlDefault |= + ((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT); +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + if ((lpc3511IpState->controllerSpeed) && + (USB_ENDPOINT_INTERRUPT == epState->stateUnion.stateBitField.endpointType)) + { + epState->stateUnion.stateBitField.epControlDefault &= + (~((USB_LPC3511IP_ENDPOINT_ENDPOINT_TYPE_MASK | USB_LPC3511IP_ENDPOINT_RFTV_MASK) >> + USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT)); + } +#endif + } + + if (epState->stateUnion.stateBitField.stallPrimed) + { + epState->stateUnion.stateBitField.stallPrimed = 0u; + USB_DeviceLpc3511IpTransaction(lpc3511IpState, epState, endpointIndex); + } + /* cancel the transfer in the endpoint */ + USB_DeviceLpc3511IpCancel(lpc3511IpState, ep); + return kStatus_USB_Success; +} + +#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +/*! + * @brief Un-stall a specified endpoint. + * + * The function is used to un-stall a specified endpoint. + * Current transfer of the endpoint will be canceled and the specified endpoint will be un-stalled. + * + * @param lpc3511IpState Pointer of the controller state structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceLpc3511IpInterruptSuspend(usb_device_lpc3511ip_state_struct_t *lpc3511IpState) +{ + usb_device_callback_message_struct_t message; + + message.buffer = (uint8_t *)NULL; + message.code = kUSB_DeviceNotifySuspend; + message.length = 0U; + message.isSetup = 0U; + + /* Notify up layer the USB suspend signal detected. */ + USB_DeviceNotificationTrigger(lpc3511IpState->deviceHandle, &message); + + return kStatus_USB_Success; +} + +/*! + * @brief Un-stall a specified endpoint. + * + * The function is used to un-stall a specified endpoint. + * Current transfer of the endpoint will be canceled and the specified endpoint will be un-stalled. + * + * @param lpc3511IpState Pointer of the controller state structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceLpc3511IpInterruptResume(usb_device_lpc3511ip_state_struct_t *lpc3511IpState) +{ + usb_device_callback_message_struct_t message; + + message.buffer = (uint8_t *)NULL; + message.code = kUSB_DeviceNotifyResume; + message.length = 0U; + message.isSetup = 0U; + + /* Notify up layer the USB suspend signal detected. */ + USB_DeviceNotificationTrigger(lpc3511IpState->deviceHandle, &message); + + return kStatus_USB_Success; +} +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) +/*! + * @brief Un-stall a specified endpoint. + * + * The function is used to un-stall a specified endpoint. + * Current transfer of the endpoint will be canceled and the specified endpoint will be un-stalled. + * + * @param lpc3511IpState Pointer of the controller state structure. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceLpc3511IpInterruptLPMSleep(usb_device_lpc3511ip_state_struct_t *lpc3511IpState) +{ + usb_device_callback_message_struct_t message; + uint8_t remotewakeup; + + message.buffer = (uint8_t *)NULL; + message.code = kUSB_DeviceNotifyLPMSleep; + message.length = 0U; + message.isSetup = 0U; + + remotewakeup = + (lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_LPM_REWP_MASK) >> USB_LPC3511IP_DEVCMDSTAT_LPM_REWP_SHIFT; + USB_DeviceSetStatus(lpc3511IpState->deviceHandle, kUSB_DeviceStatusRemoteWakeup, &remotewakeup); + + /* Notify up layer the USB suspend signal detected. */ + USB_DeviceNotificationTrigger(lpc3511IpState->deviceHandle, &message); + + return kStatus_USB_Success; +} + +#endif +#endif + +static uint32_t USB_DeviceLpc3511IpTokenUpdate(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + usb_device_lpc3511ip_endpoint_state_struct_t *epState, + uint8_t endpointIndex, + uint8_t changedOdd) +{ + uint32_t length; + uint32_t index; + uint8_t *destBuffer; + uint8_t *sourceBuffer; + uint8_t odd; + +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + if (changedOdd) + { + odd = epState->stateUnion.stateBitField.consumerOdd; + epState->stateUnion.stateBitField.consumerOdd ^= 1; + epState->stateUnion.stateBitField.doubleBufferBusy--; + } + else +#endif + { + odd = 0U; + } + +/* for OUT packet, compute the actual packet size. */ +#if ((defined(FSL_FEATURE_USB_VERSION) && (FSL_FEATURE_USB_VERSION >= 200U)) || \ + (defined(FSL_FEATURE_USBHSD_VERSION) && (FSL_FEATURE_USBHSD_VERSION >= 300U))) +#else + if ((endpointIndex & 0x01U) == 0x00u) /* OUT */ +#endif + { + /* get the transaction length */ + length = *(((uint32_t *)lpc3511IpState->registerBase->EPLISTSTART) + endpointIndex * 2 + odd); + +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + if (lpc3511IpState->controllerSpeed) + { + length = + (length & USB_LPC3511IPHS_ENDPOINT_BUFFER_NBYTES_MASK) >> USB_LPC3511IPHS_ENDPOINT_BUFFER_NBYTES_SHIFT; + } + else +#endif + { + length = + (length & USB_LPC3511IPFS_ENDPOINT_BUFFER_NBYTES_MASK) >> USB_LPC3511IPFS_ENDPOINT_BUFFER_NBYTES_SHIFT; + } + length = epState->epBufferStatusUnion[odd].epBufferStatusField.transactionLength - length; + } +#if ((defined(FSL_FEATURE_USB_VERSION) && (FSL_FEATURE_USB_VERSION >= 200U)) || \ + (defined(FSL_FEATURE_USBHSD_VERSION) && (FSL_FEATURE_USBHSD_VERSION >= 300U))) +#else + else /* for IN packet, if there is no error, the packet lenght is the primed length. */ + { + /* don't judge the actual packet size */ + length = epState->epBufferStatusUnion[odd].epBufferStatusField.transactionLength; + } +#endif + +#if ((defined(USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY)) && (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY > 0U)) +#if USB_DEVICE_IP3511_ALL_IP_SUPPORT_RESERVED_BUFFER + if ((epState->epBufferStatusUnion[odd].epBufferStatusField.epPacketCopyed) && (length > 0U) && + ((endpointIndex & 0x01u) == 0U)) +#else + if (USB_DeviceLpcIp3511MaxPacketNeedCopy(lpc3511IpState) && + (epState->epBufferStatusUnion[odd].epBufferStatusField.epPacketCopyed) && (length > 0U) && + ((endpointIndex & 0x01u) == 0U)) +#endif +#else + /* control data buffer align is used */ + if (((endpointIndex >> 1U) == USB_CONTROL_ENDPOINT) && + (epState->epBufferStatusUnion[odd].epBufferStatusField.epPacketCopyed) && (length > 0U) && + ((endpointIndex & 0x01u) == 0U)) +#endif + { + destBuffer = &(epState->transferBuffer[epState->transferDone]); +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + sourceBuffer = epState->epPacketBuffer + + odd * USB_LPC3511IP_GET_MULTIPLE_OF_64(epState->stateUnion.stateBitField.maxPacketSize); +#else + sourceBuffer = epState->epPacketBuffer; +#endif + + /* align with 4 bytes */ + if (!(((uint32_t)(destBuffer)) & 0x00000003U)) + { + for (index = 0; index < (length >> 2U); ++index) + { + ((uint32_t *)(destBuffer))[index] = ((uint32_t *)(sourceBuffer))[index]; + } + for (index = index * 4; index < length; ++index) + { + destBuffer[index] = sourceBuffer[index]; + } + } + else + { + for (index = 0; index < length; ++index) + { + destBuffer[index] = sourceBuffer[index]; + } + } + } + /* update the transferred length */ + epState->transferDone += length; + + return length; +} + +static void USB_DeviceLpc3511IpInterruptToken(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + uint8_t endpointIndex, + uint8_t isSetup, + uint32_t errorStatus) +{ + usb_device_callback_message_struct_t message; + uint32_t length; + uint32_t remainLength; + usb_setup_struct_t *setupPacket; + usb_device_lpc3511ip_endpoint_state_struct_t *epState = + USB_DeviceLpc3511IpGetEndpointStateStruct(lpc3511IpState, endpointIndex); +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + + if ((epState->stateUnion.stateBitField.epControlDefault & + ((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT)) && + (USB_ENDPOINT_INTERRUPT == epState->stateUnion.stateBitField.endpointType) && + (lpc3511IpState->controllerSpeed) && + (lpc3511IpState->epCommandStatusList[endpointIndex * 2 + epState->stateUnion.stateBitField.consumerOdd] & + USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK)) + { + if (!(lpc3511IpState->registerBase->EPTOGGLE & (0x01u << endpointIndex))) + { + uint32_t index; + length = 0; + for (index = 0; index < (USB_DEVICE_IP3511_ENDPOINTS_NUM)*4; ++index) + { + if ((lpc3511IpState->epCommandStatusList[index] & USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) && + (USB_ENDPOINT_INTERRUPT == + lpc3511IpState->endpointState[index / 2].stateUnion.stateBitField.endpointType)) + { + length++; + } + } + + if (length <= 1) + { + lpc3511IpState->registerBase->DEVCMDSTAT &= + ~(USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AO_MASK | USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AI_MASK); + } + epState->stateUnion.stateBitField.epControlDefault &= + (~((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT)); +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + /* high-speed */ + epState->stateUnion.stateBitField.epControlDefault |= + ((USB_LPC3511IP_ENDPOINT_RFTV_MASK | USB_LPC3511IP_ENDPOINT_ENDPOINT_TYPE_MASK) >> + USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT); + USB_DeviceLpc3511IpTransaction(lpc3511IpState, epState, endpointIndex); +#endif + } + return; + } +#endif + + if ((!isSetup) && (0U == epState->stateUnion.stateBitField.transferring)) + { + return; + } + if (isSetup) + { + message.length = 8U; + message.buffer = (lpc3511IpState->setupData); + /* clear the primed control transactions */ + if (epState->stateUnion.stateBitField.transferring) + { + epState->stateUnion.stateBitField.transferring = 0U; + if (lpc3511IpState->epCommandStatusList[0] & USB_LPC3511IP_ENDPOINT_ACTIVE_MASK) + { + USB_DeviceLpc3511IpCancel(lpc3511IpState, USB_CONTROL_ENDPOINT); + } + } + if (lpc3511IpState->endpointState[1].stateUnion.stateBitField.transferring) + { + lpc3511IpState->endpointState[1].stateUnion.stateBitField.transferring = 0U; + if (lpc3511IpState->epCommandStatusList[2] & USB_LPC3511IP_ENDPOINT_ACTIVE_MASK) + { + USB_DeviceLpc3511IpCancel(lpc3511IpState, (0x80u | USB_CONTROL_ENDPOINT)); + } + } + + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT_AND( + lpc3511IpState, 0, 0, (~(USB_LPC3511IP_ENDPOINT_STALL_MASK | USB_LPC3511IP_ENDPOINT_ACTIVE_MASK))); + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT_AND( + lpc3511IpState, 1, 0, (~(USB_LPC3511IP_ENDPOINT_STALL_MASK | USB_LPC3511IP_ENDPOINT_ACTIVE_MASK))); + + lpc3511IpState->registerBase->INTSTAT = 0x03u; /* clear interrupt */ + /* W1 to clear the setup flag */ + lpc3511IpState->registerBase->DEVCMDSTAT |= USB_LPC3511IP_DEVCMDSTAT_SETUP_MASK; + } + else + { + length = 0; +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + if (lpc3511IpState->epCommandStatusList[endpointIndex * 2 + epState->stateUnion.stateBitField.consumerOdd] & + USB_LPC3511IP_ENDPOINT_ACTIVE_MASK) + { + return; + } +#else + if (lpc3511IpState->epCommandStatusList[endpointIndex * 2] & USB_LPC3511IP_ENDPOINT_ACTIVE_MASK) + { + return; + } +#endif + +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + if ((endpointIndex >> 1U) != USB_CONTROL_ENDPOINT) + { + length += USB_DeviceLpc3511IpTokenUpdate(lpc3511IpState, epState, endpointIndex, 1U); + + if ((epState->stateUnion.stateBitField.doubleBufferBusy > 0) && + (!(lpc3511IpState + ->epCommandStatusList[endpointIndex * 2 + epState->stateUnion.stateBitField.consumerOdd] & + USB_LPC3511IP_ENDPOINT_ACTIVE_MASK))) + { + length += USB_DeviceLpc3511IpTokenUpdate(lpc3511IpState, epState, endpointIndex, 1U); + } + } + else +#endif + { + length = USB_DeviceLpc3511IpTokenUpdate(lpc3511IpState, epState, endpointIndex, 0U); + } + + /* update remaining length */ + remainLength = epState->transferLength - epState->transferDone; + + /* Whether the transfer is completed or not. + * The transfer is completed when one of the following conditions meet: + * 1. The remaining length is zero. + * 2. The length of current tansaction is not the multiple of max packet size. + */ + if ((length > 0U) && (!(length % epState->stateUnion.stateBitField.maxPacketSize)) && (remainLength > 0U)) + { + (void)USB_DeviceLpc3511IpTransaction(lpc3511IpState, epState, endpointIndex); + return; + } + else + { + epState->stateUnion.stateBitField.transferring = 0U; + message.length = epState->transferDone; + message.buffer = epState->transferBuffer; + + /* process ZLT + * 1. IN endpoint; + * 2. transfer length is the multiple of max packet size. + */ + if ((endpointIndex & 0x01U) && (length) && (!(length % epState->stateUnion.stateBitField.maxPacketSize))) + { + if ((endpointIndex >> 1U) == USB_CONTROL_ENDPOINT) + { + setupPacket = (usb_setup_struct_t *)(&(lpc3511IpState->setupData[0])); + /* + * Send ZLT transaction if setup transfer and the required length is longer than actual length + */ + if (USB_SHORT_FROM_LITTLE_ENDIAN(setupPacket->wLength) > epState->transferLength) + { + (void)USB_DeviceLpc3511IpEndpointPrime(lpc3511IpState, epState, 1U, NULL, 0U); + return; + } + } + else if ((epState->stateUnion.stateBitField.zlt)) + { + (void)USB_DeviceLpc3511IpEndpointPrime(lpc3511IpState, epState, endpointIndex, NULL, 0U); + return; + } + else + { + } + } + } + } + + message.isSetup = isSetup; + message.code = ((uint8_t)(endpointIndex >> 1) | (uint8_t)(((uint32_t)(endpointIndex & 0x01U) << 0x07U))); + + /* Notify the up layer the controller status changed. */ + USB_DeviceNotificationTrigger(lpc3511IpState->deviceHandle, &message); +} + +/*! + * @brief Handle the USB bus reset interrupt. + * + * The function is used to handle the USB bus reset interrupt. + * + * @param lpc3511IpState Pointer of the controller state structure. + * + */ +static void USB_DeviceLpc3511IpInterruptReset(usb_device_lpc3511ip_state_struct_t *lpc3511IpState) +{ + usb_device_callback_message_struct_t message; + + /* Set reset flag */ + lpc3511IpState->isResetting = 1U; + +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + if (lpc3511IpState->controllerSpeed) + { + if (((lpc3511IpState->registerBase->DEVCMDSTAT & USBHSD_DEVCMDSTAT_Speed_MASK) >> + USBHSD_DEVCMDSTAT_Speed_SHIFT) == 0x02U) + { + lpc3511IpState->deviceSpeed = USB_SPEED_HIGH; + } + else if (((lpc3511IpState->registerBase->DEVCMDSTAT & USBHSD_DEVCMDSTAT_Speed_MASK) >> + USBHSD_DEVCMDSTAT_Speed_SHIFT) == 0x01U) + { + lpc3511IpState->deviceSpeed = USB_SPEED_FULL; + } + else + { + } + } + else +#endif + { + lpc3511IpState->deviceSpeed = USB_SPEED_FULL; + } + + message.buffer = (uint8_t *)NULL; + message.code = kUSB_DeviceNotifyBusReset; + message.length = 0U; + message.isSetup = 0U; + /* Notify up layer the USB bus reset signal detected. */ + USB_DeviceNotificationTrigger(lpc3511IpState->deviceHandle, &message); +} + +#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE)) +/*! + * @brief Handle detach interrupt. + * + * The function is used to handle the detach interrupt. + * + * @param lpc3511IpState Pointer of the controller state structure. + * + */ +static void USB_DeviceLpc3511IpInterruptDetach(usb_device_lpc3511ip_state_struct_t *lpc3511IpState) +{ + usb_device_callback_message_struct_t message; + + message.buffer = (uint8_t *)NULL; + message.code = kUSB_DeviceNotifyDetach; + message.length = 0U; + message.isSetup = 0U; + + /* Notify up layer the USB VBUS falling signal detected. */ + USB_DeviceNotificationTrigger(lpc3511IpState->deviceHandle, &message); +} +#endif + +usb_status_t USB_DeviceLpc3511IpInit(uint8_t controllerId, + usb_device_handle handle, + usb_device_controller_handle *controllerHandle) +{ + usb_device_lpc3511ip_state_struct_t *lpc3511IpState = NULL; +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) + uint32_t ip3511FsBases[] = USB_BASE_ADDRS; +#endif + uint32_t *endpointListArray[] = LPC_CONTROLLER_ENDPOINT_LIST_ARRAY; + +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + uint32_t ip3511HsBases[] = USBHSD_BASE_ADDRS; + if ((controllerId >= kUSB_ControllerLpcIp3511Hs0) && (controllerId <= kUSB_ControllerLpcIp3511Hs1)) + { + if ((uint32_t)(controllerId - kUSB_ControllerLpcIp3511Hs0) >= (sizeof(ip3511HsBases) / sizeof(uint32_t))) + { + return kStatus_USB_ControllerNotFound; + } + lpc3511IpState = + &s_UsbDeviceLpc3511IpState[controllerId - kUSB_ControllerLpcIp3511Hs0 + USB_DEVICE_CONFIG_LPCIP3511FS]; + lpc3511IpState->controlData = + s_ControlTransferData[controllerId - kUSB_ControllerLpcIp3511Hs0 + USB_DEVICE_CONFIG_LPCIP3511FS]; + lpc3511IpState->setupData = + s_SetupData[controllerId - kUSB_ControllerLpcIp3511Hs0 + USB_DEVICE_CONFIG_LPCIP3511FS]; + lpc3511IpState->zeroTransactionData = + s_ZeroTransactionData[controllerId - kUSB_ControllerLpcIp3511Hs0 + USB_DEVICE_CONFIG_LPCIP3511FS]; + /* set the endpoint list */ + lpc3511IpState->epCommandStatusList = + endpointListArray[controllerId - kUSB_ControllerLpcIp3511Hs0 + USB_DEVICE_CONFIG_LPCIP3511FS]; + /* get the ip base address */ + lpc3511IpState->registerBase = (USB_LPC3511IP_Type *)ip3511HsBases[controllerId - kUSB_ControllerLpcIp3511Hs0]; + } + else +#endif +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) + { + /* get the controller instance */ + if ((controllerId < kUSB_ControllerLpcIp3511Fs0) || + ((controllerId - kUSB_ControllerLpcIp3511Fs0) >= (uint8_t)USB_DEVICE_CONFIG_LPCIP3511FS) || + ((uint32_t)(controllerId - kUSB_ControllerLpcIp3511Fs0) >= (sizeof(ip3511FsBases) / sizeof(uint32_t)))) + { + return kStatus_USB_ControllerNotFound; + } + lpc3511IpState = &s_UsbDeviceLpc3511IpState[controllerId - kUSB_ControllerLpcIp3511Fs0]; + lpc3511IpState->controlData = s_ControlTransferData[controllerId - kUSB_ControllerLpcIp3511Fs0]; + lpc3511IpState->setupData = s_SetupData[controllerId - kUSB_ControllerLpcIp3511Fs0]; + lpc3511IpState->zeroTransactionData = s_ZeroTransactionData[controllerId - kUSB_ControllerLpcIp3511Fs0]; + /* set the endpoint list */ + lpc3511IpState->epCommandStatusList = endpointListArray[controllerId - kUSB_ControllerLpcIp3511Fs0]; + /* get the ip base address */ + lpc3511IpState->registerBase = (USB_LPC3511IP_Type *)ip3511FsBases[controllerId - kUSB_ControllerLpcIp3511Fs0]; + } +#else + { + return kStatus_USB_ControllerNotFound; + } +#endif + + lpc3511IpState->controllerId = controllerId; +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + if ((lpc3511IpState->controllerId >= kUSB_ControllerLpcIp3511Hs0) && + (lpc3511IpState->controllerId <= kUSB_ControllerLpcIp3511Hs1)) + { + lpc3511IpState->controllerSpeed = 1U; + } + else + { + lpc3511IpState->controllerSpeed = 0U; + } +#endif + +#if ((defined(USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY)) && (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY > 0U)) + /* this controller need max packet buffer copy */ + if (USB_DeviceLpcIp3511MaxPacketNeedCopy(lpc3511IpState)) + { +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + if ((controllerId >= kUSB_ControllerLpcIp3511Hs0) && (controllerId <= kUSB_ControllerLpcIp3511Hs1)) + { +#if (USB_DEVICE_IP3511_ALL_IP_SUPPORT_RESERVED_BUFFER) + /* for allocating the max packet buffer */ + lpc3511IpState->epReservedBuffer = (uint8_t *) + s_EpReservedBuffer[controllerId - kUSB_ControllerLpcIp3511Hs0 + USB_DEVICE_CONFIG_LPCIP3511FS]; +#else + lpc3511IpState->epReservedBuffer = + (uint8_t *)s_EpReservedBuffer[controllerId - kUSB_ControllerLpcIp3511Hs0]; +#endif + } + else +#endif + { + lpc3511IpState->epReservedBuffer = + (uint8_t *)s_EpReservedBuffer[controllerId - kUSB_ControllerLpcIp3511Fs0]; + } + } + for (controllerId = 0; controllerId < ((USB_DEVICE_IP3511_BITS_FOR_RESERVED_BUFFER + 7) / 8); ++controllerId) + { + lpc3511IpState->epReservedBufferBits[controllerId] = 0u; + } +#endif + + /* disable the controller */ + lpc3511IpState->registerBase->DEVCMDSTAT &= + (~(USB_LPC3511IP_DEVCMDSTAT_DCON_MASK | USB_LPC3511IP_DEVCMDSTAT_DEV_EN_MASK | USB_LPC3511IP_DEVCMDSTAT_LPM_SUP_MASK)); + /* reset and enalbe the controller */ + USB_DeviceLpc3511IpSetDefaultState(lpc3511IpState); + /* enable USB */ + lpc3511IpState->registerBase->DEVCMDSTAT |= (USB_LPC3511IP_DEVCMDSTAT_DEV_EN_MASK +#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +#else + | USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK +#endif + ); +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) + lpc3511IpState->registerBase->DEVCMDSTAT |= USB_LPC3511IP_DEVCMDSTAT_LPM_SUP_MASK; + lpc3511IpState->registerBase->LPM |= USB_LPC3511IP_USB_LPM_HIRD_SW(4); + lpc3511IpState->registerBase->DEVCMDSTAT &= ~(USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK); +#endif + lpc3511IpState->deviceHandle = handle; + *controllerHandle = lpc3511IpState; + + return kStatus_USB_Success; +} + +usb_status_t USB_DeviceLpc3511IpDeinit(usb_device_controller_handle controllerHandle) +{ + usb_device_lpc3511ip_state_struct_t *lpc3511IpState = (usb_device_lpc3511ip_state_struct_t *)controllerHandle; + uint32_t usbAddress; + + if (controllerHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + /* Clear all interrupt flags. */ + lpc3511IpState->registerBase->INTSTAT = + (USB_LPC3511IP_INTSTAT_DEV_INT_MASK | USB_LPC3511IP_INTSTAT_FRAME_INT_MASK | USB_LPC3511IP_MAX_PHY_ENDPOINT_MASK); + /* Disable all interrupts. */ + lpc3511IpState->registerBase->INTEN = 0U; + /* Clear device address. */ + usbAddress = 0U; + USB_DeviceLpc3511IpControl(lpc3511IpState, kUSB_DeviceControlSetDeviceAddress, &usbAddress); +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) + lpc3511IpState->registerBase->DEVCMDSTAT &= ~USB_LPC3511IP_DEVCMDSTAT_LPM_SUP_MASK; +#endif + /* disable the controller */ + lpc3511IpState->registerBase->DEVCMDSTAT &= (~(USB_LPC3511IP_DEVCMDSTAT_DCON_MASK | USB_LPC3511IP_DEVCMDSTAT_DEV_EN_MASK)); + + return kStatus_USB_Success; +} + +static usb_status_t USB_DeviceLpc3511IpGetActualBufferAndPrime(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + usb_device_lpc3511ip_endpoint_state_struct_t *epState, + uint8_t endpointIndex, + uint8_t changedOdd) +{ + uint32_t index; + uint8_t *destBuffer; + uint8_t *actualBuffer; + uint32_t length; + uint8_t odd; + +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + if (changedOdd) + { + odd = epState->stateUnion.stateBitField.producerOdd; + } + else +#endif + { + odd = 0; + } + actualBuffer = epState->transferBuffer + epState->transferPrimedLength; + length = epState->transferLength - epState->transferPrimedLength; + /* Data length needs to less than max packet size. */ + if (length > epState->stateUnion.stateBitField.maxPacketSize) + { + length = epState->stateUnion.stateBitField.maxPacketSize; + } + + epState->epBufferStatusUnion[odd].epBufferStatusField.epPacketCopyed = 0; + + index = (endpointIndex & 0x01u); /* index mean IN endpoint here */ + if (length > 0U) + { +#if ((defined(USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY)) && (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY > 0U)) +/* if all the enabled IP support the reserved buffer, then don't need the judgement. */ +#if (!USB_DEVICE_IP3511_ALL_IP_SUPPORT_RESERVED_BUFFER) +#define USB_DEVICE_IP3511_NEED_CHECK_BUFFER (1u) + /* lengt > 0 && ((buffer not align with 64) || (buffer is not in the deticated ram))) */ + if (USB_DeviceLpcIp3511MaxPacketNeedCopy(lpc3511IpState)) +#endif +#else +#define USB_DEVICE_IP3511_NEED_CHECK_BUFFER (1u) + /* align the buffer for control transfer */ + if (((endpointIndex >> 1U) == USB_CONTROL_ENDPOINT)) +#endif + { + /* not 64 bytes align || not in the dedicated ram || ( OUT && not mutiple of 4 ) */ + if ((((uint32_t)actualBuffer & 0x0000003FU) != 0U) || + (((uint32_t)actualBuffer & 0xFFC00000U) != (lpc3511IpState->registerBase->DATABUFSTART & 0xFFC00000U)) +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + || ((lpc3511IpState->controllerSpeed) && (!index) && + (length != epState->stateUnion.stateBitField.maxPacketSize))) +#else + ) +#endif + { + epState->epBufferStatusUnion[odd].epBufferStatusField.epPacketCopyed = 1U; +/* usb copy buffer for this packet */ +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + destBuffer = + (uint8_t *)(epState->epPacketBuffer + (odd * USB_LPC3511IP_GET_MULTIPLE_OF_64( + epState->stateUnion.stateBitField.maxPacketSize))); +#else + destBuffer = (uint8_t *)(epState->epPacketBuffer); +#endif + if (index) /* USB_IN */ + { + /* align with 4 bytes */ + if (!(((uint32_t)actualBuffer) & 0x00000003U)) + { + for (index = 0; index < ((length + 0x03U) >> 2U); ++index) + { + ((uint32_t *)(destBuffer))[index] = ((uint32_t *)actualBuffer)[index]; + } + } + else + { + for (index = 0; index < length; ++index) + { + destBuffer[index] = actualBuffer[index]; + } + } + } + else + { +#if ((defined(FSL_FEATURE_USB_VERSION) && (FSL_FEATURE_USB_VERSION >= 200U)) || \ + (defined(FSL_FEATURE_USBHSD_VERSION) && (FSL_FEATURE_USBHSD_VERSION >= 300U))) +#else + length = epState->stateUnion.stateBitField.maxPacketSize; +#endif + } + actualBuffer = destBuffer; + } + } +#if (defined USB_DEVICE_IP3511_NEED_CHECK_BUFFER) && (USB_DEVICE_IP3511_NEED_CHECK_BUFFER) + else /* cannot do memory copy */ + { + /* not 64 bytes align || not in the dedicated ram || ( OUT && HS && not mutiple of 4 ) */ + if ((((uint32_t)actualBuffer & 0x0000003FU) != 0U) || + (((uint32_t)actualBuffer & 0xFFC00000U) != (lpc3511IpState->registerBase->DATABUFSTART & 0xFFC00000U)) +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + || ((lpc3511IpState->controllerSpeed) && (!index) && ((length & 0x00000003u) != 0u))) +#else + ) +#endif + { + return kStatus_USB_Error; + } + } +#endif + } + + /* Send/Receive data when the device is not resetting. */ + if (0U == lpc3511IpState->isResetting) + { + return USB_DeviceLpc3511IpEndpointPrime(lpc3511IpState, epState, endpointIndex, actualBuffer, length); + } + else + { + return kStatus_USB_Error; + } +} +static usb_status_t USB_DeviceLpc3511IpTransaction(usb_device_lpc3511ip_state_struct_t *lpc3511IpState, + usb_device_lpc3511ip_endpoint_state_struct_t *epState, + uint8_t endpointIndex) +{ + usb_status_t status = kStatus_USB_Error; + USB_OSA_SR_ALLOC(); + +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + /* high-speed */ + if ((epState->stateUnion.stateBitField.epControlDefault & + ((USB_LPC3511IP_ENDPOINT_TOGGLE_RESET_MASK) >> USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT)) && + (USB_ENDPOINT_INTERRUPT == epState->stateUnion.stateBitField.endpointType) && (lpc3511IpState->controllerSpeed)) + { + /* users can use NVIC to disable/enable the USB interrupt to improve the system performance */ + USB_OSA_ENTER_CRITICAL(); + + lpc3511IpState->registerBase->DEVCMDSTAT |= (USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AO_MASK | USB_LPC3511IP_DEVCMDSTAT_INTONNAK_AI_MASK); + +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT( + lpc3511IpState, endpointIndex, epState->stateUnion.stateBitField.producerOdd, + (epState->stateUnion.stateBitField.epControlDefault << USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT) | (epState->stateUnion.stateBitField.stalled << USB_LPC3511IP_ENDPOINT_STALL_SHIFT), + 0U, (uint32_t)lpc3511IpState->zeroTransactionData); +#else + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT( + lpc3511IpState, endpointIndex, 0, + (epState->stateUnion.stateBitField.epControlDefault << USB_LPC3511IP_ENDPOINT_CONFIGURE_BITS_SHIFT) | (epState->stateUnion.stateBitField.stalled << USB_LPC3511IP_ENDPOINT_STALL_SHIFT), + 0U, (uint32_t)lpc3511IpState->zeroTransactionData); +#endif + /* users can use NVIC to disable/enable the USB interrupt to improve the system performance */ + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } +#endif + + /* Enter critical */ + USB_OSA_ENTER_CRITICAL(); + if (epState->stateUnion.stateBitField.stalled) + { + if ((endpointIndex >> 1U) != USB_ENDPOINT_CONTROL) + { + epState->stateUnion.stateBitField.stallPrimed = 1u; + status = kStatus_USB_Success; + } + status = kStatus_USB_Error; + USB_OSA_EXIT_CRITICAL(); + return status; + } + USB_OSA_EXIT_CRITICAL(); + + /* 1. transfer size is 0; 2. All are primed */ + if ((epState->transferLength <= epState->transferPrimedLength) && (epState->transferLength != 0)) + { + return kStatus_USB_Success; + } + +#if (defined USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) && (USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE) + if ((endpointIndex >> 1U) != USB_CONTROL_ENDPOINT) + { + /* disable endpoint interrupts, users can use NVIC to disable/enable the USB interrupt to improve the system performance */ + USB_OSA_ENTER_CRITICAL(); + /* lpc3511IpState->registerBase->INTEN &= (uint32_t)(~(USB_LPC3511IP_MAX_PHY_ENDPOINT_MASK)); */ + + do + { + status = USB_DeviceLpc3511IpGetActualBufferAndPrime(lpc3511IpState, epState, endpointIndex, 1U); + if (status != kStatus_USB_Success) + { + break; + } + } while ((epState->transferLength > epState->transferPrimedLength) && + (epState->stateUnion.stateBitField.doubleBufferBusy < 2)); + + /* enable endpoint interrupt again, users can use NVIC to disable/enable the USB interrupt to improve the system performance */ + USB_OSA_EXIT_CRITICAL(); + } + else +#endif + { + status = USB_DeviceLpc3511IpGetActualBufferAndPrime(lpc3511IpState, epState, endpointIndex, 0U); + } + return status; +} + +usb_status_t USB_DeviceLpc3511IpSend(usb_device_controller_handle controllerHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length) +{ + usb_device_lpc3511ip_state_struct_t *lpc3511IpState = (usb_device_lpc3511ip_state_struct_t *)controllerHandle; + uint8_t endpointIndex = USB_LPC3511IP_ENDPOINT_DES_INDEX(endpointAddress); + usb_device_lpc3511ip_endpoint_state_struct_t *epState = + USB_DeviceLpc3511IpGetEndpointStateStruct(lpc3511IpState, endpointIndex); + + if (1U == epState->stateUnion.stateBitField.transferring) + { + return kStatus_USB_Error; + } + + /* Save the transfer information */ + epState->transferDone = 0U; + epState->transferBuffer = buffer; + epState->transferLength = length; + epState->transferPrimedLength = 0U; + + return USB_DeviceLpc3511IpTransaction(lpc3511IpState, epState, endpointIndex); + +/* prime the control setup transfer if it is control in endpoint and data length is zero + * For IP3511 there is no need to prime, the buffer is always in the command/status list +*/ +#if 0 + if ((0U == length) && (USB_CONTROL_ENDPOINT == (endpointAddress & USB_ENDPOINT_NUMBER_MASK))) + { + USB_DeviceLpc3511IpPrimeNextSetup(lpc3511IpState); + } +#endif +} + +usb_status_t USB_DeviceLpc3511IpRecv(usb_device_controller_handle controllerHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length) +{ + return USB_DeviceLpc3511IpSend(controllerHandle, endpointAddress, buffer, length); +} + +usb_status_t USB_DeviceLpc3511IpCancel(usb_device_controller_handle controllerHandle, uint8_t ep) +{ + /* users can use NVIC to disable/enable the USB interrupt to improve the system performance */ + USB_OSA_SR_ALLOC(); + + usb_device_lpc3511ip_state_struct_t *lpc3511IpState = (usb_device_lpc3511ip_state_struct_t *)controllerHandle; + usb_device_callback_message_struct_t message; + uint8_t endpointIndex = USB_LPC3511IP_ENDPOINT_DES_INDEX(ep); + usb_device_lpc3511ip_endpoint_state_struct_t *epState = + USB_DeviceLpc3511IpGetEndpointStateStruct(lpc3511IpState, endpointIndex); + + /* Cancel the transfer and notify the up layer when the endpoint is busy. */ + if (epState->stateUnion.stateBitField.transferring) + { + /* disable endpoint interrupts, users can use NVIC to disable/enable the USB interrupt to improve the system performance */ + USB_OSA_ENTER_CRITICAL(); + + do + { + if (epState->stateUnion.stateBitField.doubleBufferBusy == 2) + { + epState->stateUnion.stateBitField.doubleBufferBusy = 1; + } + else + { + epState->stateUnion.stateBitField.doubleBufferBusy = 0; + } + /* cancel the transfer in the endpoint command/status */ + lpc3511IpState->registerBase->EPSKIP |= (0x01U << endpointIndex); + while (lpc3511IpState->registerBase->EPSKIP & (0x01U << endpointIndex)) + { + } + if (epState->stateUnion.stateBitField.doubleBufferBusy) + { + epState->stateUnion.stateBitField.producerOdd = + ((lpc3511IpState->registerBase->EPINUSE & ((uint32_t)(0x01 << endpointIndex))) >> endpointIndex); + epState->stateUnion.stateBitField.producerOdd ^= 1; + lpc3511IpState->registerBase->EPINUSE |= + (uint32_t)(epState->stateUnion.stateBitField.producerOdd << endpointIndex); + } + } while (epState->stateUnion.stateBitField.doubleBufferBusy); + + /* clear interrupt status, enable endpoint interrupt again */ + lpc3511IpState->registerBase->INTSTAT = (0x01U << endpointIndex); + + /* users can use NVIC to disable/enable the USB interrupt to improve the system performance */ + USB_OSA_EXIT_CRITICAL(); + + message.length = USB_UNINITIALIZED_VAL_32; + message.buffer = epState->transferBuffer; + message.code = ep; + message.isSetup = 0U; + epState->stateUnion.stateBitField.transferring = 0U; + epState->stateUnion.stateBitField.producerOdd = + ((lpc3511IpState->registerBase->EPINUSE & ((uint32_t)(0x01 << endpointIndex))) >> endpointIndex); + epState->stateUnion.stateBitField.consumerOdd = + ((lpc3511IpState->registerBase->EPINUSE & ((uint32_t)(0x01 << endpointIndex))) >> endpointIndex); + USB_DeviceNotificationTrigger(lpc3511IpState->deviceHandle, &message); + } + return kStatus_USB_Success; +} + +usb_status_t USB_DeviceLpc3511IpControl(usb_device_controller_handle controllerHandle, + usb_device_control_type_t type, + void *param) +{ + usb_device_lpc3511ip_state_struct_t *lpc3511IpState = (usb_device_lpc3511ip_state_struct_t *)controllerHandle; + usb_status_t error = kStatus_USB_Error; + uint32_t tmp32Value; + uint8_t tmp8Value; +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + usb_device_struct_t *deviceHandle; +#endif + usb_device_lpc3511ip_endpoint_state_struct_t *epState; + + if (controllerHandle == NULL) + { + return kStatus_USB_InvalidHandle; + } + +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + deviceHandle = (usb_device_struct_t *)lpc3511IpState->deviceHandle; +#endif + + switch (type) + { + case kUSB_DeviceControlRun: + lpc3511IpState->registerBase->DEVCMDSTAT |= (USB_LPC3511IP_DEVCMDSTAT_DCON_MASK); + break; + + case kUSB_DeviceControlStop: + lpc3511IpState->registerBase->DEVCMDSTAT &= (~USB_LPC3511IP_DEVCMDSTAT_DCON_MASK); + break; + + case kUSB_DeviceControlEndpointInit: + if (param) + { + error = USB_DeviceLpc3511IpEndpointInit(lpc3511IpState, (usb_device_endpoint_init_struct_t *)param); + } + break; + + case kUSB_DeviceControlEndpointDeinit: + if (param) + { + tmp8Value = *((uint8_t *)param); + error = USB_DeviceLpc3511IpEndpointDeinit(lpc3511IpState, tmp8Value); + } + break; + + case kUSB_DeviceControlEndpointStall: + if (param) + { + tmp8Value = *((uint8_t *)param); + error = USB_DeviceLpc3511IpEndpointStall(lpc3511IpState, tmp8Value); + } + break; + + case kUSB_DeviceControlEndpointUnstall: + if (param) + { + tmp8Value = *((uint8_t *)param); + error = USB_DeviceLpc3511IpEndpointUnstall(lpc3511IpState, tmp8Value); + } + break; + + case kUSB_DeviceControlGetDeviceStatus: + if (param) + { + *((uint16_t *)param) = + (USB_DEVICE_CONFIG_SELF_POWER << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_SELF_POWERED_SHIFT)) +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + | ((uint16_t)(((uint32_t)deviceHandle->remotewakeup) + << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_REMOTE_WARKUP_SHIFT))) +#endif + ; + error = kStatus_USB_Success; + } + break; + + case kUSB_DeviceControlGetEndpointStatus: + if (param) + { + usb_device_endpoint_status_struct_t *endpointStatus = (usb_device_endpoint_status_struct_t *)param; + + if (((endpointStatus->endpointAddress) & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_IP3511_ENDPOINTS_NUM) + { + epState = USB_DeviceLpc3511IpGetEndpointStateStruct( + lpc3511IpState, USB_LPC3511IP_ENDPOINT_DES_INDEX(endpointStatus->endpointAddress)); + endpointStatus->endpointStatus = (uint16_t)(epState->stateUnion.stateBitField.stalled == 1U) ? + kUSB_DeviceEndpointStateStalled : + kUSB_DeviceEndpointStateIdle; + error = kStatus_USB_Success; + } + } + break; + + case kUSB_DeviceControlSetDeviceAddress: + if (param) + { + tmp8Value = *((uint8_t *)param); + tmp32Value = lpc3511IpState->registerBase->DEVCMDSTAT; + tmp32Value &= (~USB_LPC3511IP_DEVCMDSTAT_DEV_ADDR_MASK); + tmp32Value |= (tmp8Value & USB_LPC3511IP_DEVCMDSTAT_DEV_ADDR_MASK); + lpc3511IpState->registerBase->DEVCMDSTAT = tmp32Value; + error = kStatus_USB_Success; + } + break; + + case kUSB_DeviceControlGetSynchFrame: + break; + +#if defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U) + case kUSB_DeviceControlResume: + /* todo: turn on USB clock and enable the USB clock source */ + lpc3511IpState->registerBase->DEVCMDSTAT |= USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK; + lpc3511IpState->registerBase->DEVCMDSTAT &= ~USB_LPC3511IP_DEVCMDSTAT_DSUS_MASK; + while (lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_DSUS_MASK) + { + } + /* the W1C bits */ + lpc3511IpState->registerBase->DEVCMDSTAT &= + ~(USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK | USB_LPC3511IP_DEVCMDSTAT_INTERRUPT_WC_MASK); + error = kStatus_USB_Success; + break; +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) + case kUSB_DeviceControlSleepResume: + /* todo: turn on USB clock and enable the USB clock source */ + lpc3511IpState->registerBase->DEVCMDSTAT |= USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK; + lpc3511IpState->registerBase->DEVCMDSTAT &= ~USB_LPC3511IP_DEVCMDSTAT_LPM_SUS_MASK; + while (lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_LPM_SUS_MASK) + { + __NOP(); + } + /* the W1C bits */ + lpc3511IpState->registerBase->DEVCMDSTAT &= + ~(USB_LPC3511IP_DEVCMDSTAT_FORCE_NEEDCLK_MASK | USB_LPC3511IP_DEVCMDSTAT_INTERRUPT_WC_MASK); + error = kStatus_USB_Success; + break; +#endif + case kUSB_DeviceControlGetRemoteWakeUp: + *((uint8_t *)param) = !!(lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_LPM_REWP_MASK); + break; +#endif /* USB_DEVICE_CONFIG_REMOTE_WAKEUP */ + + case kUSB_DeviceControlSetDefaultStatus: + for (tmp32Value = 0U; tmp32Value < USB_DEVICE_IP3511_ENDPOINTS_NUM; tmp32Value++) + { + USB_DeviceLpc3511IpEndpointDeinit(lpc3511IpState, (tmp32Value | (USB_IN << 0x07U))); + USB_DeviceLpc3511IpEndpointDeinit(lpc3511IpState, (tmp32Value | (USB_OUT << 0x07U))); + } + USB_DeviceLpc3511IpSetDefaultState(lpc3511IpState); + error = kStatus_USB_Success; + break; + + case kUSB_DeviceControlGetSpeed: + if (param) + { + *((uint8_t *)param) = lpc3511IpState->deviceSpeed; + error = kStatus_USB_Success; + } + break; + case kUSB_DeviceControlGetOtgStatus: + break; + case kUSB_DeviceControlSetOtgStatus: + break; +#if (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U)) + case kUSB_DeviceControlSetTestMode: + if (param) + { + tmp8Value = *((uint8_t *)param); +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + lpc3511IpState->registerBase->DEVCMDSTAT |= + ((uint32_t)(tmp8Value) << USBHSD_DEVCMDSTAT_PHY_TEST_MODE_SHIFT); +#endif + error = kStatus_USB_Success; + } + break; +#endif + default: + break; + } + + return error; +} + +void USB_DeviceLpcIp3511IsrFunction(void *deviceHandle) +{ + usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle; + usb_device_lpc3511ip_state_struct_t *lpc3511IpState; + uint32_t interruptStatus; + uint32_t usbErrorCode; + uint32_t devState; + + if (NULL == deviceHandle) + { + return; + } + + lpc3511IpState = (usb_device_lpc3511ip_state_struct_t *)(handle->controllerHandle); + /* get and clear interrupt status */ + interruptStatus = lpc3511IpState->registerBase->INTSTAT; + lpc3511IpState->registerBase->INTSTAT = interruptStatus; + interruptStatus &= lpc3511IpState->registerBase->INTEN; + + usbErrorCode = (lpc3511IpState->registerBase->INFO & USB_LPC3511IP_INFO_ERR_CODE_MASK); + + /* device status change interrupt */ + if (interruptStatus & USB_LPC3511IP_INTSTAT_DEV_INT_MASK) + { + /* get and clear device state change status */ + devState = lpc3511IpState->registerBase->DEVCMDSTAT; + devState &= ~(USB_LPC3511IP_DEVCMDSTAT_SETUP_MASK); + lpc3511IpState->registerBase->DEVCMDSTAT = (devState | USB_LPC3511IP_DEVCMDSTAT_INTERRUPT_WC_MASK); + + /* reset change */ + if (devState & USB_LPC3511IP_DEVCMDSTAT_DRES_C_MASK) + { + USB_DeviceLpc3511IpInterruptReset(lpc3511IpState); + } + +#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE)) + /* dis-connect change */ + if (devState & USB_LPC3511IP_DEVCMDSTAT_DCON_C_MASK) + { + USB_DeviceLpc3511IpInterruptDetach(lpc3511IpState); + } +#endif + +/* Suspend/Resume */ +#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE)) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + if (devState & USB_LPC3511IP_DEVCMDSTAT_DSUS_C_MASK) + { + if (lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_DSUS_MASK) + { + USB_DeviceLpc3511IpInterruptSuspend(lpc3511IpState); + } +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) + else if (lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_LPM_SUS_MASK) + { + USB_DeviceLpc3511IpInterruptLPMSleep(lpc3511IpState); + } +#endif + else + { + USB_DeviceLpc3511IpInterruptResume(lpc3511IpState); + } + } + +#endif + +#if 0U /* some soc don't support this bit, need check according to the feature macro */ + /* OTG Status change */ + if (lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_OTG_C_MASK) + { + } +#endif + } + + /* endpoint transfers interrupt */ + if (interruptStatus & USB_LPC3511IP_MAX_PHY_ENDPOINT_MASK) + { + devState = 0; /* devState means index here */ + if (interruptStatus & 0x01u) /* control OUT */ + { + if (lpc3511IpState->registerBase->DEVCMDSTAT & USB_LPC3511IP_DEVCMDSTAT_SETUP_MASK) + { + devState = 2; + if ((lpc3511IpState->endpointState[0].stateUnion.stateBitField.stalled == 1U) || + (lpc3511IpState->endpointState[1].stateUnion.stateBitField.stalled == 1U)) + { + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT_AND( + lpc3511IpState, 0, 0, + (~(USB_LPC3511IP_ENDPOINT_STALL_MASK | USB_LPC3511IP_ENDPOINT_ACTIVE_MASK))); + USB_LPC3511IP_ENDPOINT_SET_ENDPOINT_AND( + lpc3511IpState, 1, 0, + (~(USB_LPC3511IP_ENDPOINT_STALL_MASK | USB_LPC3511IP_ENDPOINT_ACTIVE_MASK))); + lpc3511IpState->endpointState[0].stateUnion.stateBitField.stalled = 0U; + lpc3511IpState->endpointState[1].stateUnion.stateBitField.stalled = 0U; + } + + /* todo: setup token interrupt */ + USB_DeviceLpc3511IpInterruptToken(lpc3511IpState, 0U, 1, usbErrorCode); + } + } + + for (; devState < (USB_DEVICE_IP3511_ENDPOINTS_NUM * 2); ++devState) + { + /* check the endpoint interrupt */ + if (interruptStatus & (0x01U << devState)) + { + USB_DeviceLpc3511IpInterruptToken(lpc3511IpState, devState, 0, usbErrorCode); + } + } + } + +#if 0U + if (interruptStatus & USB_LPC3511IP_INTSTAT_FRAME_INT_MASK) + { + } +#endif +} + +#endif diff --git a/usb/device/source/lpcip3511/usb_device_lpcip3511.h b/usb/device/source/lpcip3511/usb_device_lpcip3511.h new file mode 100644 index 0000000..4e2e8df --- /dev/null +++ b/usb/device/source/lpcip3511/usb_device_lpcip3511.h @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_LPC3511IP_H__ +#define __USB_DEVICE_LPC3511IP_H__ + +#include "fsl_device_registers.h" + +/*! + * @addtogroup usb_device_controller_lpcip3511_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief The reserved buffer size, the buffer is for the memory copy if the application transfer buffer is + ((not 64 bytes alignment) || (not in the same 64K ram) || (HS && OUT && not multiple of 4)) */ +#define USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE (5 * 1024) +/*! @brief Use one bit to represent one reserved 64 bytes to allocate the buffer by uint of 64 bytes. */ +#define USB_DEVICE_IP3511_BITS_FOR_RESERVED_BUFFER ((USB_DEVICE_IP3511_ENDPOINT_RESERVED_BUFFER_SIZE + 63) / 64) +/*! @brief How many IPs support the reserved buffer */ +#define USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY (USB_DEVICE_CONFIG_LPCIP3511FS + USB_DEVICE_CONFIG_LPCIP3511HS) +/*! @brief Prime all the double endpoint buffer at the same time, if the transfer length is larger than max packet size. + */ +#define USB_DEVICE_IP3511_DOUBLE_BUFFER_ENABLE (1u) +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) +#define USB_LPC3511IP_Type USBHSD_Type +#define USB_DEVICE_IP3511_ENDPOINTS_NUM FSL_FEATURE_USBHSD_EP_NUM +#else +#define USB_LPC3511IP_Type USB_Type +#define USB_DEVICE_IP3511_ENDPOINTS_NUM FSL_FEATURE_USB_EP_NUM +#endif + +/*! @brief Endpoint state structure */ +typedef struct _usb_device_lpc3511ip_endpoint_state_struct +{ + uint8_t *transferBuffer; /*!< Address of buffer containing the data to be transmitted */ + uint32_t transferLength; /*!< Length of data to transmit. */ + uint32_t transferDone; /*!< The data length has been transferred*/ + uint32_t transferPrimedLength; /*!< it may larger than transferLength, because the primed length may larger than the + transaction length. */ + uint8_t *epPacketBuffer; /*!< The max packet buffer for copying*/ + union + { + uint32_t state; /*!< The state of the endpoint */ + struct + { + uint32_t maxPacketSize : 11U; /*!< The maximum packet size of the endpoint */ + uint32_t stalled : 1U; /*!< The endpoint is stalled or not */ + uint32_t transferring : 1U; /*!< The endpoint is transferring */ + uint32_t zlt : 1U; /*!< zlt flag */ + uint32_t stallPrimed : 1U; + uint32_t epPacketCopyed : 1U; /*!< whether use the copy buffer */ + uint32_t epControlDefault : 5u; /*!< The EP command/status 26~30 bits */ + uint32_t doubleBufferBusy : 2U; /*!< How many buffers are primed, for control endpoint it is not used */ + uint32_t producerOdd : 1U; /*!< When priming one transaction, prime to this endpoint buffer */ + uint32_t consumerOdd : 1U; /*!< When transaction is done, read result from this endpoint buffer */ + uint32_t endpointType : 2U; + uint32_t reserved1 : 5U; + } stateBitField; + } stateUnion; + union + { + uint16_t epBufferStatus; + /* If double buff is disable, only epBufferStatusUnion[0] is used; + For control endpoint, only epBufferStatusUnion[0] is used. */ + struct + { + uint16_t transactionLength : 11U; + uint16_t epPacketCopyed : 1U; + } epBufferStatusField; + } epBufferStatusUnion[2]; +} usb_device_lpc3511ip_endpoint_state_struct_t; + +/*! @brief LPC USB controller (IP3511) state structure */ +typedef struct _usb_device_lpc3511ip_state_struct +{ + /*!< control data buffer, must align with 64 */ + uint8_t *controlData; + /*!< 8 bytes' setup data, must align with 64 */ + uint8_t *setupData; + /*!< 4 bytes for zero length transaction, must align with 64 */ + uint8_t *zeroTransactionData; + /* Endpoint state structures */ + usb_device_lpc3511ip_endpoint_state_struct_t endpointState[(USB_DEVICE_IP3511_ENDPOINTS_NUM * 2)]; + usb_device_handle deviceHandle; /*!< (4 bytes) Device handle used to identify the device object belongs to */ + USB_LPC3511IP_Type *registerBase; /*!< (4 bytes) ip base address */ + volatile uint32_t *epCommandStatusList; /* endpoint list */ + uint8_t controllerId; /*!< Controller ID */ + uint8_t isResetting; /*!< Is doing device reset or not */ + uint8_t deviceSpeed; /*!< some controller support the HS */ +#if ((defined(USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY)) && (USB_DEVICE_IP3511_RESERVED_BUFFER_FOR_COPY > 0U)) + uint8_t *epReservedBuffer; + uint8_t epReservedBufferBits[(USB_DEVICE_IP3511_BITS_FOR_RESERVED_BUFFER + 7) / 8]; +#endif +#if ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U)) + uint8_t controllerSpeed; +#endif +} usb_device_lpc3511ip_state_struct_t; + +/*! + * @name USB device controller (IP3511) functions + * @{ + */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initializes the USB device controller instance. + * + * This function initializes the USB device controller module specified by the controllerId. + * + * @param[in] controllerId The controller ID of the USB IP. See the enumeration type usb_controller_index_t. + * @param[in] handle Pointer of the device handle used to identify the device object belongs to. + * @param[out] controllerHandle An out parameter used to return the pointer of the device controller handle to the + * caller. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceLpc3511IpInit(uint8_t controllerId, + usb_device_handle handle, + usb_device_controller_handle *controllerHandle); + +/*! + * @brief Deinitializes the USB device controller instance. + * + * This function deinitializes the USB device controller module. + * + * @param[in] controllerHandle Pointer of the device controller handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceLpc3511IpDeinit(usb_device_controller_handle controllerHandle); + +/*! + * @brief Sends data through a specified endpoint. + * + * This function sends data through a specified endpoint. + * + * @param[in] controllerHandle Pointer of the device controller handle. + * @param[in] endpointAddress Endpoint index. + * @param[in] buffer The memory address to hold the data need to be sent. + * @param[in] length The data length need to be sent. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value indicates whether the sending request is successful or not. The transfer completion is + * notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for a specific endpoint. + * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the + * endpoint + * callback). + */ +usb_status_t USB_DeviceLpc3511IpSend(usb_device_controller_handle controllerHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! + * @brief Receives data through a specified endpoint. + * + * This function receives data through a specified endpoint. + * + * @param[in] controllerHandle Pointer of the device controller handle. + * @param[in] endpointAddress Endpoint index. + * @param[in] buffer The memory address to save the received data. + * @param[in] length The data length to be received. + * + * @return A USB error code or kStatus_USB_Success. + * + * @note The return value indicates whether the receiving request is successful or not. The transfer completion is + * notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for a specific endpoint. + * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the + * endpoint + * callback). + */ +usb_status_t USB_DeviceLpc3511IpRecv(usb_device_controller_handle controllerHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! + * @brief Cancels the pending transfer in a specified endpoint. + * + * The function is used to cancel the pending transfer in a specified endpoint. + * + * @param[in] controllerHandle ointer of the device controller handle. + * @param[in] ep Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceLpc3511IpCancel(usb_device_controller_handle controllerHandle, uint8_t ep); + +/*! + * @brief Controls the status of the selected item. + * + * The function is used to control the status of the selected item. + * + * @param[in] controllerHandle Pointer of the device controller handle. + * @param[in] type The selected item. Please refer to enumeration type usb_device_control_type_t. + * @param[in,out] param The parameter type is determined by the selected item. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceLpc3511IpControl(usb_device_controller_handle controllerHandle, + usb_device_control_type_t type, + void *param); + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* __USB_DEVICE_LPC3511IP_H__ */ diff --git a/usb/device/source/usb_device_ch9.c b/usb/device/source/usb_device_ch9.c new file mode 100644 index 0000000..fc09e3e --- /dev/null +++ b/usb/device/source/usb_device_ch9.c @@ -0,0 +1,952 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb_device_config.h" +#include "usb.h" + +#include "usb_device.h" +#include "usb_device_dci.h" +#include "usb_device_class.h" +#include "usb_device_ch9.h" +#if ((defined(USB_DEVICE_CONFIG_NUM)) && (USB_DEVICE_CONFIG_NUM > 0U)) +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief Standard request callback function typedef. + * + * This function is used to handle the standard request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @return A USB error code or kStatus_USB_Success. + */ +typedef usb_status_t (*usb_standard_request_callback_t)(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +static usb_status_t USB_DeviceCh9GetStatus(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); +static usb_status_t USB_DeviceCh9SetClearFeature(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); + +static usb_status_t USB_DeviceCh9SetAddress(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); +static usb_status_t USB_DeviceCh9GetDescriptor(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); +static usb_status_t USB_DeviceCh9GetConfiguration(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); +static usb_status_t USB_DeviceCh9SetConfiguration(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); +static usb_status_t USB_DeviceCh9GetInterface(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); +static usb_status_t USB_DeviceCh9SetInterface(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); +static usb_status_t USB_DeviceCh9SynchFrame(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* The function list to handle the standard request. */ +static const usb_standard_request_callback_t s_UsbDeviceStandardRequest[] = { + USB_DeviceCh9GetStatus, + USB_DeviceCh9SetClearFeature, + (usb_standard_request_callback_t)NULL, + USB_DeviceCh9SetClearFeature, + (usb_standard_request_callback_t)NULL, + USB_DeviceCh9SetAddress, + USB_DeviceCh9GetDescriptor, + (usb_standard_request_callback_t)NULL, + USB_DeviceCh9GetConfiguration, + USB_DeviceCh9SetConfiguration, + USB_DeviceCh9GetInterface, + USB_DeviceCh9SetInterface, + USB_DeviceCh9SynchFrame, +}; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Handle get status request. + * + * This function is used to handle get status request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state, + * or, the request is unsupported. + */ +static usb_status_t USB_DeviceCh9GetStatus(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t state; + + USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if ((kUSB_DeviceStateAddress != state) && (kUSB_DeviceStateConfigured != state)) + { + return error; + } + + if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE) + { +#if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG)) + if (setup->wIndex == USB_REQUEST_STANDARD_GET_STATUS_OTG_STATUS_SELECTOR) + { + error = + USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusOtg, &classHandle->standardTranscationBuffer); + classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer); + /* The device status length must be USB_DEVICE_STATUS_SIZE. */ + *length = 1; + } + else /* Get the device status */ + { +#endif + error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDevice, + &classHandle->standardTranscationBuffer); + classHandle->standardTranscationBuffer = + classHandle->standardTranscationBuffer & USB_GET_STATUS_DEVICE_MASK; + classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer); + /* The device status length must be USB_DEVICE_STATUS_SIZE. */ + *length = USB_DEVICE_STATUS_SIZE; +#if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG)) + } +#endif + } + else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_INTERFACE) + { + /* Get the interface status */ + error = kStatus_USB_Success; + classHandle->standardTranscationBuffer = 0U; + /* The interface status length must be USB_INTERFACE_STATUS_SIZE. */ + *length = USB_INTERFACE_STATUS_SIZE; + } + else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT) + { + /* Get the endpoint status */ + usb_device_endpoint_status_struct_t endpointStatus; + endpointStatus.endpointAddress = (uint8_t)setup->wIndex; + endpointStatus.endpointStatus = kUSB_DeviceEndpointStateIdle; + error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusEndpoint, &endpointStatus); + classHandle->standardTranscationBuffer = endpointStatus.endpointStatus & USB_GET_STATUS_ENDPOINT_MASK; + classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer); + /* The endpoint status length must be USB_INTERFACE_STATUS_SIZE. */ + *length = USB_ENDPOINT_STATUS_SIZE; + } + else + { + } + *buffer = (uint8_t *)&classHandle->standardTranscationBuffer; + + return error; +} + +/*! + * @brief Handle set or clear device feature request. + * + * This function is used to handle set or clear device feature request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state, + * or, the request is unsupported. + */ +static usb_status_t USB_DeviceCh9SetClearFeature(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t state; + uint8_t isSet = 0U; + + USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if ((kUSB_DeviceStateAddress != state) && (kUSB_DeviceStateConfigured != state)) + { + return error; + } + + /* Identify the request is set or clear the feature. */ + if (USB_REQUEST_STANDARD_SET_FEATURE == setup->bRequest) + { + isSet = 1U; + } + + if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE) + { + /* Set or Clear the device feature. */ + if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_REMOTE_WAKEUP == setup->wValue) + { +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusRemoteWakeup, &isSet); +#endif + /* Set or Clear the device remote wakeup feature. */ + error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventSetRemoteWakeup, &isSet); + } +#if ((defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \ + (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) && \ + (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U)) + else if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_TEST_MODE == setup->wValue) + { + state = kUSB_DeviceStateTestMode; + error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + } +#endif +#if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG)) + else if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_B_HNP_ENABLE == setup->wValue) + { + error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventSetBHNPEnable, &isSet); + } +#endif + else + { + } + } + else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT) + { + /* Set or Clear the endpoint feature. */ + if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT == setup->wValue) + { + if (USB_CONTROL_ENDPOINT == (setup->wIndex & USB_ENDPOINT_NUMBER_MASK)) + { + /* Set or Clear the control endpoint status(halt or not). */ + if (isSet) + { + USB_DeviceStallEndpoint(classHandle->handle, (uint8_t)setup->wIndex); + } + else + { + USB_DeviceUnstallEndpoint(classHandle->handle, (uint8_t)setup->wIndex); + } + } + + /* Set or Clear the endpoint status feature. */ + if (isSet) + { + error = USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetEndpointHalt, &setup->wIndex); + } + else + { + error = + USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventClearEndpointHalt, &setup->wIndex); + } + } + else + { + } + } + else + { + } + + return error; +} + +/*! + * @brief Handle set address request. + * + * This function is used to handle set address request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state. + */ +static usb_status_t USB_DeviceCh9SetAddress(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t state; + + USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if ((kUSB_DeviceStateAddressing != state) && (kUSB_DeviceStateAddress != state) && + (kUSB_DeviceStateDefault != state) && (kUSB_DeviceStateConfigured != state)) + { + return error; + } + + if (kUSB_DeviceStateAddressing != state) + { + /* If the device address is not setting, pass the address and the device state will change to + * kUSB_DeviceStateAddressing internally. */ + state = setup->wValue & 0xFFU; + error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusAddress, &state); + } + else + { + /* If the device address is setting, set device address and the address will be write into the controller + * internally. */ + error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusAddress, NULL); + /* And then change the device state to kUSB_DeviceStateAddress. */ + if (kStatus_USB_Success == error) + { + state = kUSB_DeviceStateAddress; + error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + } + } + + return error; +} + +/*! + * @brief Handle get descriptor request. + * + * This function is used to handle get descriptor request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state, + * or, the request is unsupported. + */ +static usb_status_t USB_DeviceCh9GetDescriptor(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + usb_device_get_descriptor_common_union_t commonDescriptor; + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t state; + uint8_t descriptorType = (uint8_t)((setup->wValue & 0xFF00U) >> 8U); + uint8_t descriptorIndex = (uint8_t)((setup->wValue & 0x00FFU)); + + USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if ((kUSB_DeviceStateAddress != state) && (kUSB_DeviceStateConfigured != state) && + (kUSB_DeviceStateDefault != state)) + { + return error; + } + commonDescriptor.commonDescriptor.length = setup->wLength; + if (USB_DESCRIPTOR_TYPE_DEVICE == descriptorType) + { + /* Get the device descriptor */ + error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetDeviceDescriptor, + &commonDescriptor.deviceDescriptor); + } + else if (USB_DESCRIPTOR_TYPE_CONFIGURE == descriptorType) + { + /* Get the configuration descriptor */ + commonDescriptor.configurationDescriptor.configuration = descriptorIndex; + error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetConfigurationDescriptor, + &commonDescriptor.configurationDescriptor); + } + else if (USB_DESCRIPTOR_TYPE_STRING == descriptorType) + { + /* Get the string descriptor */ + commonDescriptor.stringDescriptor.stringIndex = descriptorIndex; + commonDescriptor.stringDescriptor.languageId = setup->wIndex; + error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetStringDescriptor, + &commonDescriptor.stringDescriptor); + } +#if (defined(USB_DEVICE_CONFIG_HID) && (USB_DEVICE_CONFIG_HID > 0U)) + else if (USB_DESCRIPTOR_TYPE_HID == descriptorType) + { + /* Get the hid descriptor */ + commonDescriptor.hidDescriptor.interfaceNumber = setup->wIndex; + error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetHidDescriptor, + &commonDescriptor.hidDescriptor); + } + else if (USB_DESCRIPTOR_TYPE_HID_REPORT == descriptorType) + { + /* Get the hid report descriptor */ + commonDescriptor.hidReportDescriptor.interfaceNumber = setup->wIndex; + error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetHidReportDescriptor, + &commonDescriptor.hidReportDescriptor); + } + else if (USB_DESCRIPTOR_TYPE_HID_PHYSICAL == descriptorType) + { + /* Get the hid physical descriptor */ + commonDescriptor.hidPhysicalDescriptor.index = descriptorIndex; + commonDescriptor.hidPhysicalDescriptor.interfaceNumber = setup->wIndex; + error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetHidPhysicalDescriptor, + &commonDescriptor.hidPhysicalDescriptor); + } +#endif +#if (defined(USB_DEVICE_CONFIG_CV_TEST) && (USB_DEVICE_CONFIG_CV_TEST > 0U)) + else if (USB_DESCRIPTOR_TYPE_DEVICE_QUALITIER == descriptorType) + { + /* Get the device descriptor */ + error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetDeviceQualifierDescriptor, + &commonDescriptor.deviceDescriptor); + } +#endif +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) + else if (USB_DESCRIPTOR_TYPE_BOS == descriptorType) + { + /* Get the configuration descriptor */ + commonDescriptor.configurationDescriptor.configuration = descriptorIndex; + error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetBOSDescriptor, + &commonDescriptor.configurationDescriptor); + } +#endif + else + { + } + *buffer = commonDescriptor.commonDescriptor.buffer; + *length = commonDescriptor.commonDescriptor.length; + return error; +} + +/*! + * @brief Handle get current configuration request. + * + * This function is used to handle get current configuration request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state, + * or, the request is unsupported. + */ +static usb_status_t USB_DeviceCh9GetConfiguration(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + uint8_t state; + + USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if ((kUSB_DeviceStateAddress != state) && ((kUSB_DeviceStateConfigured != state))) + { + return kStatus_USB_InvalidRequest; + } + + *length = USB_CONFIGURE_SIZE; + *buffer = (uint8_t *)&classHandle->standardTranscationBuffer; + return USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetConfiguration, + &classHandle->standardTranscationBuffer); +} + +/*! + * @brief Handle set current configuration request. + * + * This function is used to handle set current configuration request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state, + * or, the request is unsupported. + */ +static usb_status_t USB_DeviceCh9SetConfiguration(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + uint8_t state; + + USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if ((kUSB_DeviceStateAddress != state) && (kUSB_DeviceStateConfigured != state)) + { + return kStatus_USB_InvalidRequest; + } + + /* The device state is changed to kUSB_DeviceStateConfigured */ + state = kUSB_DeviceStateConfigured; + USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + if (!setup->wValue) + { + /* If the new configuration is zero, the device state is changed to kUSB_DeviceStateAddress */ + state = kUSB_DeviceStateAddress; + USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + } + + /* Notify the class layer the configuration is changed */ + USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetConfiguration, &setup->wValue); + /* Notify the application the configuration is changed */ + return USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventSetConfiguration, &setup->wValue); +} + +/*! + * @brief Handle get the alternate setting of a interface request. + * + * This function is used to handle get the alternate setting of a interface request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state, + * or, the request is unsupported. + */ +static usb_status_t USB_DeviceCh9GetInterface(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t state; + + USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if (state != kUSB_DeviceStateConfigured) + { + return error; + } + *length = USB_INTERFACE_SIZE; + *buffer = (uint8_t *)&classHandle->standardTranscationBuffer; + classHandle->standardTranscationBuffer = (uint16_t)(((uint32_t)setup->wIndex & 0xFFU) << 8U); + /* The Bit[15~8] is used to save the interface index, and the alternate setting will be saved in Bit[7~0] by + * application. */ + error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventGetInterface, + &classHandle->standardTranscationBuffer); + classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer); + return error; +} + +/*! + * @brief Handle set the alternate setting of a interface request. + * + * This function is used to handle set the alternate setting of a interface request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state, + * or, the request is unsupported. + */ +static usb_status_t USB_DeviceCh9SetInterface(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + uint8_t state; + + USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if (state != kUSB_DeviceStateConfigured) + { + return kStatus_USB_InvalidRequest; + } + classHandle->standardTranscationBuffer = ((setup->wIndex & 0xFFU) << 8U) | (setup->wValue & 0xFFU); + /* Notify the class driver the alternate setting of the interface is changed. */ + /* The Bit[15~8] is used to save the interface index, and the alternate setting is saved in Bit[7~0]. */ + USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetInterface, + &classHandle->standardTranscationBuffer); + /* Notify the application the alternate setting of the interface is changed. */ + /* The Bit[15~8] is used to save the interface index, and the alternate setting will is saved in Bit[7~0]. */ + return USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventSetInterface, + &classHandle->standardTranscationBuffer); +} + +/*! + * @brief Handle get sync frame request. + * + * This function is used to handle get sync frame request. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @retval kStatus_USB_Success The request is handled successfully. + * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state, + * or, the request is unsupported. + */ +static usb_status_t USB_DeviceCh9SynchFrame(usb_device_common_class_struct_t *classHandle, + usb_setup_struct_t *setup, + uint8_t **buffer, + uint32_t *length) +{ + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t state; + + USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); + + if (state != kUSB_DeviceStateConfigured) + { + return error; + } + + classHandle->standardTranscationBuffer = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wIndex); + /* Get the sync frame value */ + error = + USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusSynchFrame, &classHandle->standardTranscationBuffer); + *buffer = (uint8_t *)&classHandle->standardTranscationBuffer; + *length = sizeof(classHandle->standardTranscationBuffer); + + return error; +} + +/*! + * @brief Send the response to the host. + * + * This function is used to send the response to the host. + * + * There are two cases this function will be called. + * Case one when a setup packet is received in control endpoint callback function: + * 1. If there is not data phase in the setup transfer, the function will prime an IN transfer with the data + * length is zero for status phase. + * 2. If there is an IN data phase, the function will prime an OUT transfer with the actual length to need to + * send for data phase. And then prime an IN transfer with the data length is zero for status phase. + * 3. If there is an OUT data phase, the function will prime an IN transfer with the actual length to want to + * receive for data phase. + * + * Case two when is not a setup packet received in control endpoint callback function: + * 1. The function will prime an IN transfer with data length is zero for status phase. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param setup The pointer of the setup packet. + * @param error The error code returned from the standard request function. + * @param stage The stage of the control transfer. + * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. + * @param length It is an out parameter, the data length. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceControlCallbackFeedback(usb_device_handle handle, + usb_setup_struct_t *setup, + usb_status_t error, + usb_device_control_read_write_sequence_t stage, + uint8_t **buffer, + uint32_t *length) +{ + usb_status_t errorCode = kStatus_USB_Error; + uint8_t direction = USB_IN; + + if (kStatus_USB_InvalidRequest == error) + { + /* Stall the control pipe when the request is unsupported. */ + if ((!((setup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_STANDARD)) && + ((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT) && (setup->wLength) && + (kUSB_DeviceControlPipeSetupStage == stage)) + { + direction = USB_OUT; + } + errorCode = USB_DeviceStallEndpoint( + handle, + (USB_CONTROL_ENDPOINT) | (uint8_t)((uint32_t)direction << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)); + } + else + { + if (*length > setup->wLength) + { + *length = setup->wLength; + } + errorCode = USB_DeviceSendRequest(handle, (USB_CONTROL_ENDPOINT), *buffer, *length); + + if ((kStatus_USB_Success == errorCode) && + (USB_REQUEST_TYPE_DIR_IN == (setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK))) + { + errorCode = USB_DeviceRecvRequest(handle, (USB_CONTROL_ENDPOINT), (uint8_t *)NULL, 0U); + } + } + return errorCode; +} + +/*! + * @brief Control endpoint callback function. + * + * This callback function is used to notify uplayer the transfser result of a transfer. + * This callback pointer is passed when a specified endpoint initialized by calling API USB_DeviceInitEndpoint. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The result of a transfer, includes transfer buffer, transfer length and whether is in setup + * phase for control pipe. + * @param callbackParam The parameter for this callback. It is same with + * usb_device_endpoint_callback_struct_t::callbackParam. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceControlCallback(usb_device_handle handle, + usb_device_endpoint_callback_message_struct_t *message, + void *callbackParam) +{ + usb_setup_struct_t *deviceSetup; + usb_device_common_class_struct_t *classHandle; + uint8_t *buffer = (uint8_t *)NULL; + uint32_t length = 0U; + usb_status_t error = kStatus_USB_InvalidRequest; + uint8_t state; + + if ((0xFFFFFFFFU == message->length) || (NULL == callbackParam)) + { + return error; + } + + classHandle = (usb_device_common_class_struct_t *)callbackParam; + deviceSetup = (usb_setup_struct_t *)&classHandle->setupBuffer[0]; + USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state); + + if (message->isSetup) + { + if ((USB_SETUP_PACKET_SIZE != message->length) || (NULL == message->buffer)) + { + /* If a invalid setup is received, the control pipes should be de-init and init again. + * Due to the IP can not meet this require, it is reserved for feature. + */ + /* + USB_DeviceDeinitEndpoint(handle, + USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)); + USB_DeviceDeinitEndpoint(handle, + USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)); + USB_DeviceControlPipeInit(handle, callbackParam); + */ + return error; + } + /* Receive a setup request */ + usb_setup_struct_t *setup = (usb_setup_struct_t *)(message->buffer); + + /* Copy the setup packet to the application buffer */ + deviceSetup->wValue = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wValue); + deviceSetup->wIndex = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wIndex); + deviceSetup->wLength = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wLength); + deviceSetup->bRequest = setup->bRequest; + deviceSetup->bmRequestType = setup->bmRequestType; + + if ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_STANDARD) + { + /* Handle the standard request, only handle the request in request array. */ + if(deviceSetup->bRequest < (sizeof(s_UsbDeviceStandardRequest)/4)) + { + if (s_UsbDeviceStandardRequest[deviceSetup->bRequest] != (usb_standard_request_callback_t)NULL) + { + error = s_UsbDeviceStandardRequest[deviceSetup->bRequest](classHandle, deviceSetup, &buffer, &length); + } + } + } + else + { + if ((deviceSetup->wLength) && + ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT)) + { + /* Class or vendor request with the OUT data phase. */ + if ((deviceSetup->wLength) && + ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_CLASS) == USB_REQUEST_TYPE_TYPE_CLASS)) + { + /* Get data buffer to receive the data from the host. */ + usb_device_control_request_struct_t controlRequest; + controlRequest.buffer = (uint8_t *)NULL; + controlRequest.isSetup = 1U; + controlRequest.setup = deviceSetup; + controlRequest.length = deviceSetup->wLength; + error = USB_DeviceClassEvent(handle, kUSB_DeviceClassEventClassRequest, &controlRequest); + length = controlRequest.length; + buffer = controlRequest.buffer; + } + else if ((deviceSetup->wLength) && + ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_VENDOR) == USB_REQUEST_TYPE_TYPE_VENDOR)) + { + /* Get data buffer to receive the data from the host. */ + usb_device_control_request_struct_t controlRequest; + controlRequest.buffer = (uint8_t *)NULL; + controlRequest.isSetup = 1U; + controlRequest.setup = deviceSetup; + controlRequest.length = deviceSetup->wLength; + error = USB_DeviceClassCallback(handle, kUSB_DeviceEventVendorRequest, &controlRequest); + length = controlRequest.length; + buffer = controlRequest.buffer; + } + else + { + } + if (kStatus_USB_Success == error) + { + /* Prime an OUT transfer */ + error = USB_DeviceRecvRequest(handle, USB_CONTROL_ENDPOINT, buffer, deviceSetup->wLength); + return error; + } + } + else + { + /* Class or vendor request with the IN data phase. */ + if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_CLASS) == USB_REQUEST_TYPE_TYPE_CLASS)) + { + /* Get data buffer to response the host. */ + usb_device_control_request_struct_t controlRequest; + controlRequest.buffer = (uint8_t *)NULL; + controlRequest.isSetup = 1U; + controlRequest.setup = deviceSetup; + controlRequest.length = deviceSetup->wLength; + error = USB_DeviceClassEvent(handle, kUSB_DeviceClassEventClassRequest, &controlRequest); + length = controlRequest.length; + buffer = controlRequest.buffer; + } + else if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_VENDOR) == USB_REQUEST_TYPE_TYPE_VENDOR)) + { + /* Get data buffer to response the host. */ + usb_device_control_request_struct_t controlRequest; + controlRequest.buffer = (uint8_t *)NULL; + controlRequest.isSetup = 1U; + controlRequest.setup = deviceSetup; + controlRequest.length = deviceSetup->wLength; + error = USB_DeviceClassCallback(handle, kUSB_DeviceEventVendorRequest, &controlRequest); + length = controlRequest.length; + buffer = controlRequest.buffer; + } + else + { + } + } + } + /* Send the response to the host. */ + error = USB_DeviceControlCallbackFeedback(handle, deviceSetup, error, kUSB_DeviceControlPipeSetupStage, &buffer, + &length); + } + else if (kUSB_DeviceStateAddressing == state) + { + /* Set the device address to controller. */ + error = s_UsbDeviceStandardRequest[deviceSetup->bRequest](classHandle, deviceSetup, &buffer, &length); + } +#if ((defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) || \ + (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) && \ + (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U)) + else if (kUSB_DeviceStateTestMode == state) + { + uint8_t portTestControl = (uint8_t)(deviceSetup->wIndex >> 8); + /* Set the controller.into test mode. */ + error = USB_DeviceSetStatus(handle, kUSB_DeviceStatusTestMode, &portTestControl); + } +#endif + else if ((message->length) && (deviceSetup->wLength) && + ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT)) + { + if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_CLASS) == USB_REQUEST_TYPE_TYPE_CLASS)) + { + /* Data received in OUT phase, and notify the class driver. */ + usb_device_control_request_struct_t controlRequest; + controlRequest.buffer = message->buffer; + controlRequest.isSetup = 0U; + controlRequest.setup = deviceSetup; + controlRequest.length = message->length; + error = USB_DeviceClassEvent(handle, kUSB_DeviceClassEventClassRequest, &controlRequest); + } + else if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_VENDOR) == USB_REQUEST_TYPE_TYPE_VENDOR)) + { + /* Data received in OUT phase, and notify the application. */ + usb_device_control_request_struct_t controlRequest; + controlRequest.buffer = message->buffer; + controlRequest.isSetup = 0U; + controlRequest.setup = deviceSetup; + controlRequest.length = message->length; + error = USB_DeviceClassCallback(handle, kUSB_DeviceEventVendorRequest, &controlRequest); + } + else + { + } + /* Send the response to the host. */ + error = USB_DeviceControlCallbackFeedback(handle, deviceSetup, error, kUSB_DeviceControlPipeDataStage, &buffer, + &length); + } + else + { + } + return error; +} + +/*! + * @brief Control endpoint initialization function. + * + * This callback function is used to initialize the control pipes. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param param The up layer handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceControlPipeInit(usb_device_handle handle, void *param) +{ + usb_device_endpoint_init_struct_t epInitStruct; + usb_device_endpoint_callback_struct_t epCallback; + usb_status_t error; + + epCallback.callbackFn = USB_DeviceControlCallback; + epCallback.callbackParam = param; + + epInitStruct.zlt = 1U; + epInitStruct.transferType = USB_ENDPOINT_CONTROL; + epInitStruct.interval = 0; + epInitStruct.endpointAddress = USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT); + epInitStruct.maxPacketSize = USB_CONTROL_MAX_PACKET_SIZE; + /* Initialize the control IN pipe */ + error = USB_DeviceInitEndpoint(handle, &epInitStruct, &epCallback); + + if (kStatus_USB_Success != error) + { + return error; + } + epInitStruct.endpointAddress = USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT); + /* Initialize the control OUT pipe */ + error = USB_DeviceInitEndpoint(handle, &epInitStruct, &epCallback); + + if (kStatus_USB_Success != error) + { + USB_DeviceDeinitEndpoint(handle, + USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)); + return error; + } + + return kStatus_USB_Success; +} +#endif /* USB_DEVICE_CONFIG_NUM */ diff --git a/usb/device/source/usb_device_ch9.h b/usb/device/source/usb_device_ch9.h new file mode 100644 index 0000000..e26d357 --- /dev/null +++ b/usb/device/source/usb_device_ch9.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_CH9_H__ +#define __USB_DEVICE_CH9_H__ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! + * @addtogroup usb_device_ch9 + * @{ + */ +/*! @brief Defines USB device status size when the host request to get device status */ +#define USB_DEVICE_STATUS_SIZE (0x02U) + +/*! @brief Defines USB device interface status size when the host request to get interface status */ +#define USB_INTERFACE_STATUS_SIZE (0x02U) + +/*! @brief Defines USB device endpoint status size when the host request to get endpoint status */ +#define USB_ENDPOINT_STATUS_SIZE (0x02U) + +/*! @brief Defines USB device configuration size when the host request to get current configuration */ +#define USB_CONFIGURE_SIZE (0X01U) + +/*! @brief Defines USB device interface alternate setting size when the host request to get interface alternate setting + */ +#define USB_INTERFACE_SIZE (0X01U) + +/*! @brief Defines USB device status mask */ +#define USB_GET_STATUS_DEVICE_MASK (0x03U) + +/*! @brief Defines USB device interface status mask */ +#define USB_GET_STATUS_INTERFACE_MASK (0x03U) + +/*! @brief Defines USB device endpoint status mask */ +#define USB_GET_STATUS_ENDPOINT_MASK (0x03U) + +/*! @brief Control read and write sequence */ +typedef enum _usb_device_control_read_write_sequence +{ + kUSB_DeviceControlPipeSetupStage = 0U, /*!< Setup stage */ + kUSB_DeviceControlPipeDataStage, /*!< Data stage */ + kUSB_DeviceControlPipeStatusStage, /*!< status stage */ +} usb_device_control_read_write_sequence_t; + +#if defined(__cplusplus) +extern "C" { +#endif + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @brief Initializes the control pipes. + * + * The function is used to initialize the control pipes. This function should be called when event + * kUSB_DeviceEventBusReset is received. + * + * @param[in] handle The device handle. + * @param[in] param The event parameter. + * + * @return A USB error code or kStatus_USB_Success. + */ +extern usb_status_t USB_DeviceControlPipeInit(usb_device_handle handle, void *param); + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __USB_DEVICE_CH9_H__ */ diff --git a/usb/device/source/usb_device_dci.c b/usb/device/source/usb_device_dci.c new file mode 100644 index 0000000..d5f449d --- /dev/null +++ b/usb/device/source/usb_device_dci.c @@ -0,0 +1,1482 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb_device_config.h" +#include "usb.h" + +#include "usb_device.h" +#include "usb_device_dci.h" + +#include "fsl_device_registers.h" + +#if ((defined(USB_DEVICE_CONFIG_NUM)) && (USB_DEVICE_CONFIG_NUM > 0U)) + +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) +#include "usb_device_khci.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) +#include "usb_device_ehci.h" +#endif + +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +#include "usb_device_lpcip3511.h" +#endif + +#if ((defined(USB_DEVICE_CONFIG_DWC3)) && (USB_DEVICE_CONFIG_DWC3 > 0U)) +#include "usb_device_dwc3.h" +#endif + +#include "usb_device_ch9.h" +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) +#include "fsl_cache.h" +#endif +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "middleware.usb.device_stack" +#endif + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static usb_status_t USB_DeviceAllocateHandle(uint8_t controllerId, usb_device_struct_t **handle); +static usb_status_t USB_DeviceFreeHandle(usb_device_struct_t *handle); +static usb_status_t USB_DeviceGetControllerInterface( + uint8_t controllerId, const usb_device_controller_interface_struct_t **controllerInterface); +static usb_status_t USB_DeviceTransfer(usb_device_handle handle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); +static usb_status_t USB_DeviceControl(usb_device_handle handle, usb_device_control_type_t type, void *param); +static usb_status_t USB_DeviceResetNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +static usb_status_t USB_DeviceSuspendNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); +static usb_status_t USB_DeviceResumeNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) +static usb_status_t USB_DeviceSleepNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); + +#endif +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ +#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)) +static usb_status_t USB_DeviceDetachNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); +static usb_status_t USB_DeviceAttachNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message); +#endif +static usb_status_t USB_DeviceNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +USB_GLOBAL static usb_device_struct_t s_UsbDevice[USB_DEVICE_CONFIG_NUM]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Allocate a device handle. + * + * This function allocates a device handle. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param handle It is out parameter, is used to return pointer of the device handle to the caller. + * + * @retval kStatus_USB_Success Get a device handle successfully. + * @retval kStatus_USB_Busy Cannot allocate a device handle. + * @retval kStatus_USB_Error The device has been initialized. + */ +static usb_status_t USB_DeviceAllocateHandle(uint8_t controllerId, usb_device_struct_t **handle) +{ + uint32_t count; + USB_OSA_SR_ALLOC(); + + USB_OSA_ENTER_CRITICAL(); + /* Check the controller is initialized or not. */ + for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++) + { + if ((NULL != s_UsbDevice[count].controllerHandle) && (controllerId == s_UsbDevice[count].controllerId)) + { + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Error; + } + } + /* Get a free device handle. */ + for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++) + { + if (NULL == s_UsbDevice[count].controllerHandle) + { + s_UsbDevice[count].controllerId = controllerId; + *handle = &s_UsbDevice[count]; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; + } + } + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Busy; +} + +/*! + * @brief Free a device handle. + * + * This function frees a device handle. + * + * @param handle The device handle. + * + * @retval kStatus_USB_Success Free device handle successfully. + */ +static usb_status_t USB_DeviceFreeHandle(usb_device_struct_t *handle) +{ + USB_OSA_SR_ALLOC(); + + USB_OSA_ENTER_CRITICAL(); + handle->controllerHandle = NULL; + handle->controllerId = 0U; + USB_OSA_EXIT_CRITICAL(); + return kStatus_USB_Success; +} + +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) +/* KHCI device driver interface */ +static const usb_device_controller_interface_struct_t s_UsbDeviceKhciInterface = { + USB_DeviceKhciInit, USB_DeviceKhciDeinit, USB_DeviceKhciSend, + USB_DeviceKhciRecv, USB_DeviceKhciCancel, USB_DeviceKhciControl}; +#endif + +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) +/* EHCI device driver interface */ +static const usb_device_controller_interface_struct_t s_UsbDeviceEhciInterface = { + USB_DeviceEhciInit, USB_DeviceEhciDeinit, USB_DeviceEhciSend, + USB_DeviceEhciRecv, USB_DeviceEhciCancel, USB_DeviceEhciControl}; +#endif + +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +/* EHCI device driver interface */ +static const usb_device_controller_interface_struct_t s_UsbDeviceLpc3511IpInterface = { + USB_DeviceLpc3511IpInit, USB_DeviceLpc3511IpDeinit, USB_DeviceLpc3511IpSend, + USB_DeviceLpc3511IpRecv, USB_DeviceLpc3511IpCancel, USB_DeviceLpc3511IpControl}; +#endif + +#if ((defined(USB_DEVICE_CONFIG_DWC3)) && (USB_DEVICE_CONFIG_DWC3 > 0U)) +/* EHCI device driver interface */ +static const usb_device_controller_interface_struct_t s_UsbDeviceDwc3Interface = { + USB_DeviceDwc3Init, USB_DeviceDwc3Deinit, USB_DeviceDwc3Send, + USB_DeviceDwc3Recv, USB_DeviceDwc3Cancel, USB_DeviceDwc3Control}; +#endif + +/*! + * @brief Get the controller interface handle. + * + * This function is used to get the controller interface handle. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param controllerInterface It is out parameter, is used to return pointer of the device controller handle to the + * caller. + * + * @retval kStatus_USB_Success Get a device handle successfully. + * @retval kStatus_USB_ControllerNotFound The controller id is invalid. + */ +static usb_status_t USB_DeviceGetControllerInterface( + uint8_t controllerId, const usb_device_controller_interface_struct_t **controllerInterface) +{ + usb_status_t error = kStatus_USB_ControllerNotFound; + switch (controllerId) + { +#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U)) + /* Get the KHCI controller driver interface */ + case kUSB_ControllerKhci0: + case kUSB_ControllerKhci1: + *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceKhciInterface; + error = kStatus_USB_Success; + break; +#endif +#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U)) + /* Get the EHCI controller driver interface */ + case kUSB_ControllerEhci0: + case kUSB_ControllerEhci1: + error = kStatus_USB_Success; + *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceEhciInterface; + break; +#endif +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) + /* Get the EHCI controller driver interface */ + case kUSB_ControllerLpcIp3511Fs0: + case kUSB_ControllerLpcIp3511Fs1: + case kUSB_ControllerLpcIp3511Hs0: + case kUSB_ControllerLpcIp3511Hs1: + error = kStatus_USB_Success; + *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceLpc3511IpInterface; + break; +#endif +#if ((defined(USB_DEVICE_CONFIG_DWC3)) && (USB_DEVICE_CONFIG_DWC3 > 0U)) + /* Get the EHCI controller driver interface */ + case kUSB_ControllerDwc30: + case kUSB_ControllerDwc31: + error = kStatus_USB_Success; + *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceDwc3Interface; + break; +#endif + default: + break; + } + return error; +} + +/*! + * @brief Start a new transfer. + * + * This function is used to start a new transfer. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param endpointAddress Endpoint address. Bit7 is direction, 0U - USB_OUT, 1U - USB_IN. + * @param buffer The memory address to be transferred, or the memory address to hold the data need to be + * sent. + * @param length The length of the data. + * + * @retval kStatus_USB_Success Get a device handle successfully. + * @retval kStatus_USB_InvalidHandle The device handle is invalid. + * @retval kStatus_USB_ControllerNotFound The controller interface is not found. + * @retval kStatus_USB_Error The device is doing reset. + */ +static usb_status_t USB_DeviceTransfer(usb_device_handle handle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + usb_status_t error = kStatus_USB_Error; + uint8_t endpoint = endpointAddress & USB_ENDPOINT_NUMBER_MASK; + uint8_t direction = (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + USB_OSA_SR_ALLOC(); + + if (NULL == deviceHandle) + { + return kStatus_USB_InvalidHandle; + } + + if (NULL != deviceHandle->controllerInterface) + { + if (deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy) + { + return kStatus_USB_Busy; + } + USB_OSA_ENTER_CRITICAL(); + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 1U; + USB_OSA_EXIT_CRITICAL(); + if (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) + { +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) + if (length) + { + DCACHE_CleanByRange((uint32_t)buffer, length); + } +#endif + /* Call the controller send interface, the callbackFn is initialized in + USB_DeviceGetControllerInterface */ + error = deviceHandle->controllerInterface->deviceSend(deviceHandle->controllerHandle, endpointAddress, + buffer, length); + } + else + { +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U)) + if (length) + { + DCACHE_CleanInvalidateByRange((uint32_t)buffer, length); + } +#endif + /* Call the controller receive interface, the callbackFn is initialized in + USB_DeviceGetControllerInterface */ + error = deviceHandle->controllerInterface->deviceRecv(deviceHandle->controllerHandle, endpointAddress, + buffer, length); + } + if (kStatus_USB_Success != error) + { + USB_OSA_ENTER_CRITICAL(); + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U; + USB_OSA_EXIT_CRITICAL(); + } + } + else + { + error = kStatus_USB_ControllerNotFound; + } + return error; +} + +/*! + * @brief Control the status of the selected item. + * + * This function is used to control the status of the selected item.. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param type The control type, please refer to the enumeration usb_device_control_type_t. + * @param param The param type is determined by the selected item. + * + * @retval kStatus_USB_Success Get a device handle successfully. + * @retval kStatus_USB_InvalidHandle The device handle is invalid. + * @retval kStatus_USB_ControllerNotFound The controller interface is not found. + * @retval kStatus_USB_Error Unsupported type. + * Or, the param is NULL pointer. + */ +static usb_status_t USB_DeviceControl(usb_device_handle handle, usb_device_control_type_t type, void *param) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + usb_status_t error = kStatus_USB_Error; + + if (NULL == deviceHandle) + { + return kStatus_USB_InvalidHandle; + } + + if (NULL != deviceHandle->controllerInterface) + { + /* Call the controller control interface. the controllerInterface is initialized in + USB_DeviceGetControllerInterface */ + error = deviceHandle->controllerInterface->deviceControl(deviceHandle->controllerHandle, type, param); + } + else + { + error = kStatus_USB_ControllerNotFound; + } + return error; +} + +/*! + * @brief Handle the reset notification. + * + * This function is used to handle the reset notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @retval kStatus_USB_Success Get a device handle successfully. + */ +static usb_status_t USB_DeviceResetNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + USB_OSA_SR_ALLOC(); +#endif + + handle->isResetting = 1U; + +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + /* Clear remote wakeup feature */ + handle->remotewakeup = 0U; +#endif + +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + USB_OSA_ENTER_CRITICAL(); + handle->epCallbackDirectly = 1; + USB_OSA_EXIT_CRITICAL(); +#endif + /* Set the controller to default status. */ + USB_DeviceControl(handle, kUSB_DeviceControlSetDefaultStatus, NULL); +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + USB_OSA_ENTER_CRITICAL(); + handle->epCallbackDirectly = 0; + USB_OSA_EXIT_CRITICAL(); +#endif + + handle->state = kUSB_DeviceStateDefault; + handle->deviceAddress = 0U; + + for (uint32_t count = 0U; count < (USB_DEVICE_CONFIG_ENDPOINTS * 2U); count++) + { + handle->epCallback[count].callbackFn = (usb_device_endpoint_callback_t)NULL; + handle->epCallback[count].callbackParam = NULL; + handle->epCallback[count].isBusy = 0U; + } + + /* Call device callback to notify the application that the USB bus reset signal detected. + the deviceCallback is the second parameter of USB_DeviceInit */ + handle->deviceCallback(handle, kUSB_DeviceEventBusReset, NULL); + + handle->isResetting = 0U; + return kStatus_USB_Success; +} + +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) +/*! + * @brief Handle the suspend notification. + * + * This function is used to handle the suspend notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceSuspendNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the USB bus suspend signal detected. + the deviceCallback is the second parameter of USB_DeviceInit */ + return handle->deviceCallback(handle, kUSB_DeviceEventSuspend, NULL); +} + +/*! + * @brief Handle the resume notification. + * + * This function is used to handle the resume notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceResumeNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the USB bus resume signal detected. + the deviceCallback is the second parameter of USB_DeviceInit */ + return handle->deviceCallback(handle, kUSB_DeviceEventResume, NULL); +} +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) +/*! + * @brief Handle the suspend notification. + * + * This function is used to handle the suspend notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceSleepNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the USB bus suspend signal detected. + the deviceCallback is the second parameter of USB_DeviceInit */ + return handle->deviceCallback(handle, kUSB_DeviceEventSleeped, NULL); +} +#endif +/*! + * @brief Handle the remotewakeup notification. + * + * This function is used to handle the remotewakeup notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param flag The buffer pointer to store remotewakeup flag. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceGetRemoteWakeUp(usb_device_struct_t *handle, uint8_t **flag) +{ + /* Call device callback to notify the application that the USB bus suspend signal detected. */ + return USB_DeviceControl(handle, kUSB_DeviceControlGetRemoteWakeUp, flag); +} + +#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */ + +#if (defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U)) +usb_status_t USB_DeviceErrorNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the USB bus error signal detected. + the deviceCallback is the second parameter of USB_DeviceInit */ + return handle->deviceCallback(handle, kUSB_DeviceEventError, NULL); +} +#endif /* USB_DEVICE_CONFIG_ERROR_HANDLING */ + +#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)) +/*! + * @brief Handle the detach notification. + * + * This function is used to handle the detach notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceDetachNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the device is disconnected from a host. + the deviceCallback is the second parameter of USB_DeviceInit */ + return handle->deviceCallback(handle, kUSB_DeviceEventDetach, NULL); +} + +/*! + * @brief Handle the attach notification. + * + * This function is used to handle the attach notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceAttachNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the device is connected to a host. + the deviceCallback is the second parameter of USB_DeviceInit */ + return handle->deviceCallback(handle, kUSB_DeviceEventAttach, NULL); +} +#endif + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + ((defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) || \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))) +/*! + * @brief Handle the dcd module timeout notification. + * + * This function is used to handle the dcd module timeout notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceDcdTimeOutNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the device charger detect timeout happened. + the deviceCallback is the second parameter of USB_DeviceInit */ + return handle->deviceCallback(handle, kUSB_DeviceEventDcdTimeOut, NULL); +} + +/*! + * @brief Handle the dcd module unknown port type notification. + * + * This function is used to handle the dcd module unknown port type notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceDcdUnknownPortTypeNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the device charger detect unknown port type happened. + the deviceCallback is the second parameter of USB_DeviceInit */ + return handle->deviceCallback(handle, kUSB_DeviceEventDcdUnknownType, NULL); +} + +/*! + * @brief Handle the SDP facility is detected notification. + * + * This function is used to handle the SDP facility is detectednotification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceDcdSDPDetectNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the SDP facility is detected. + the deviceCallback is the second parameter of USB_DeviceInit */ + return handle->deviceCallback(handle, kUSB_DeviceEventSDPDetected, NULL); +} + +/*! + * @brief Handle the charging port is detected notification. + * + * This function is used to handle the charging port is detectednotification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceDcdChargingPortDetectNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the charing port is detected. + the deviceCallback is the second parameter of USB_DeviceInit */ + return handle->deviceCallback(handle, kUSB_DeviceEventChargingPortDetected, NULL); +} + +/*! + * @brief Handle the CDP facility is detected notification. + * + * This function is used to handle the CDP facility is detectednotification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceDcdChargingHostDetectNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the CDP facility is detected. + the deviceCallback is the second parameter of USB_DeviceInit */ + return handle->deviceCallback(handle, kUSB_DeviceEventChargingHostDetected, NULL); +} + +/*! + * @brief Handle the DCP facility is detected notification. + * + * This function is used to handle the DCP facility is detectednotification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ + +static usb_status_t USB_DeviceDcdDedicatedChargerDetectNotification(usb_device_struct_t *handle, + usb_device_callback_message_struct_t *message) +{ + /* Call device callback to notify the application that the DCP facility is detected. + the deviceCallback is the second parameter of USB_DeviceInit */ + return handle->deviceCallback(handle, kUSB_DeviceEventDedicatedChargerDetected, NULL); +} +#endif + +/*! + * @brief Handle the attach notification. + * + * This function is used to handle the attach notification. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +static usb_status_t USB_DeviceNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message) +{ + uint8_t endpoint = message->code & USB_ENDPOINT_NUMBER_MASK; + uint8_t direction = (message->code & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + usb_status_t error = kStatus_USB_Error; + + switch (message->code) + { + case kUSB_DeviceNotifyBusReset: + error = USB_DeviceResetNotification(handle, message); + break; +#if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) + case kUSB_DeviceNotifySuspend: + error = USB_DeviceSuspendNotification(handle, message); + break; + case kUSB_DeviceNotifyResume: + error = USB_DeviceResumeNotification(handle, message); + break; +#if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U)) + case kUSB_DeviceNotifyLPMSleep: + error = USB_DeviceSleepNotification(handle, message); + break; +#endif +#endif + +#if (defined(USB_DEVICE_CONFIG_ERROR_HANDLING) && (USB_DEVICE_CONFIG_ERROR_HANDLING > 0U)) + case kUSB_DeviceNotifyError: + error = USB_DeviceErrorNotification(handle, message); + break; +#endif + +#if USB_DEVICE_CONFIG_DETACH_ENABLE + case kUSB_DeviceNotifyDetach: + error = USB_DeviceDetachNotification(handle, message); + break; + case kUSB_DeviceNotifyAttach: + error = USB_DeviceAttachNotification(handle, message); + break; +#endif +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + ((defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) || \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))) + case kUSB_DeviceNotifyDcdTimeOut: + error = USB_DeviceDcdTimeOutNotification(handle, message); + break; + case kUSB_DeviceNotifyDcdUnknownPortType: + error = USB_DeviceDcdUnknownPortTypeNotification(handle, message); + break; + case kUSB_DeviceNotifySDPDetected: + error = USB_DeviceDcdSDPDetectNotification(handle, message); + break; + case kUSB_DeviceNotifyChargingPortDetected: + error = USB_DeviceDcdChargingPortDetectNotification(handle, message); + break; + case kUSB_DeviceNotifyChargingHostDetected: + error = USB_DeviceDcdChargingHostDetectNotification(handle, message); + break; + case kUSB_DeviceNotifyDedicatedChargerDetected: + error = USB_DeviceDcdDedicatedChargerDetectNotification(handle, message); + break; +#endif + + default: + if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS) + { + if (handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn) + { + usb_device_endpoint_callback_message_struct_t endpointCallbackMessage; + endpointCallbackMessage.buffer = message->buffer; + endpointCallbackMessage.length = message->length; + endpointCallbackMessage.isSetup = message->isSetup; + if (message->isSetup) + { + handle->epCallback[0].isBusy = 0U; + handle->epCallback[1].isBusy = 0U; + } + else + { + handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U; + } + /* Call endpoint callback, callbackFn is in the third parameter of USB_DeviceInitEndpoint */ + error = handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn( + handle, &endpointCallbackMessage, + handle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam); + } + } + break; + } + return error; +} + +/*! + * @brief Notify the device that the controller status changed. + * + * This function is used to notify the device that the controller status changed. + * + * @param handle The device handle. It equals the value returned from USB_DeviceInit. + * @param message The device callback message handle. + * + * @return A USB error code or kStatus_USB_Success. + */ +usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + usb_device_callback_message_struct_t *message = (usb_device_callback_message_struct_t *)msg; + + if ((NULL == msg) || (NULL == handle)) + { + return kStatus_USB_InvalidHandle; + } + + /* The device callback is invalid or not. */ + if (!deviceHandle->deviceCallback) + { + return kStatus_USB_Error; + } + +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + if (deviceHandle->epCallbackDirectly) + { + if ((message->code & USB_ENDPOINT_NUMBER_MASK) && (!(message->code & 0x70U))) + { + return USB_DeviceNotification(deviceHandle, message); + } + } + + /* Add the message to message queue when the device task is enabled. */ + if (kStatus_USB_OSA_Success != USB_OsaMsgqSend(deviceHandle->notificationQueue, (void *)message)) + { + return kStatus_USB_Busy; + } + return kStatus_USB_Success; +#else + /* Handle the notification by calling USB_DeviceNotification. */ + return USB_DeviceNotification(deviceHandle, message); +#endif +} + +/*! + * @brief Initialize the USB device stack. + * + * This function initializes the USB device module specified by the controllerId. + * + * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t. + * @param deviceCallback Function pointer of the device callback. + * @param handle It is out parameter, is used to return pointer of the device handle to the caller. + * + * @retval kStatus_USB_Success The device is initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. + * @retval kStatus_USB_Busy Cannot allocate a device handle. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller according to the controller id. + * @retval kStatus_USB_InvalidControllerInterface The controller driver interfaces is invaild, There is an empty + * interface entity. + * @retval kStatus_USB_Error The macro USB_DEVICE_CONFIG_ENDPOINTS is more than IP's endpoint number. + * Or, the device has been initialized. + * Or, the message queue is created failed. + */ +usb_status_t USB_DeviceInit(uint8_t controllerId, usb_device_callback_t deviceCallback, usb_device_handle *handle) +{ + usb_device_struct_t *deviceHandle = NULL; + usb_status_t error; + uint32_t count; + + if (NULL == handle) + { + return kStatus_USB_InvalidHandle; + } + + /* Allocate a device handle by using the controller id. */ + error = USB_DeviceAllocateHandle(controllerId, &deviceHandle); + + if (kStatus_USB_Success != error) + { + return error; + } + + /* Save the device callback */ + deviceHandle->deviceCallback = deviceCallback; + /* Save the controller id */ + deviceHandle->controllerId = controllerId; + /* Clear the device address */ + deviceHandle->deviceAddress = 0U; + /* Clear the device reset state */ + deviceHandle->isResetting = 0U; + + /* Initialize the endpoints */ + for (count = 0U; count < (USB_DEVICE_CONFIG_ENDPOINTS * 2U); count++) + { + deviceHandle->epCallback[count].callbackFn = (usb_device_endpoint_callback_t)NULL; + deviceHandle->epCallback[count].callbackParam = NULL; + deviceHandle->epCallback[count].isBusy = 0U; + } + + /* Get the controller interface according to the controller id */ + error = USB_DeviceGetControllerInterface(controllerId, &deviceHandle->controllerInterface); + if (kStatus_USB_Success != error) + { + USB_DeviceFreeHandle(deviceHandle); + return error; + } + if (NULL == deviceHandle->controllerInterface) + { + USB_DeviceFreeHandle(deviceHandle); + return kStatus_USB_ControllerNotFound; + } + if (((usb_device_controller_init_t)NULL == deviceHandle->controllerInterface->deviceInit) || + ((usb_device_controller_deinit_t)NULL == deviceHandle->controllerInterface->deviceDeinit) || + ((usb_device_controller_send_t)NULL == deviceHandle->controllerInterface->deviceSend) || + ((usb_device_controller_recv_t)NULL == deviceHandle->controllerInterface->deviceRecv) || + ((usb_device_controller_cancel_t)NULL == deviceHandle->controllerInterface->deviceCancel) || + ((usb_device_controller_control_t)NULL == deviceHandle->controllerInterface->deviceControl)) + { + USB_DeviceFreeHandle(deviceHandle); + return kStatus_USB_InvalidControllerInterface; + } + +#if USB_DEVICE_CONFIG_USE_TASK + /* Create a message queue when the device handle is enabled. */ + if (kStatus_USB_OSA_Success != + USB_OsaMsgqCreate(&deviceHandle->notificationQueue, USB_DEVICE_CONFIG_MAX_MESSAGES, + (1U + (sizeof(usb_device_callback_message_struct_t) - 1U) / sizeof(uint32_t)))) + { + USB_DeviceDeinit(deviceHandle); + return kStatus_USB_Error; + } +#endif + + *handle = deviceHandle; + + /* Initialize the controller, the callbackFn is initialized in USB_DeviceGetControllerInterface */ + error = deviceHandle->controllerInterface->deviceInit(controllerId, deviceHandle, &deviceHandle->controllerHandle); + if (kStatus_USB_Success != error) + { + USB_DeviceDeinit(deviceHandle); + *handle = NULL; + return error; + } + /* Set the device to deafult state */ + deviceHandle->state = kUSB_DeviceStateDefault; + + return error; +} + +/*! + * @brief Enable the device functionality. + * + * The function enables the device functionality, so that the device can be recognized by the host when the device + * detects that it has been connected to a host. + * + * @param handle The device handle got from USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is run successfully. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + * + */ +usb_status_t USB_DeviceRun(usb_device_handle handle) +{ + return USB_DeviceControl(handle, kUSB_DeviceControlRun, NULL); +} +/*! + * @brief Disable the device functionality. + * + * The function disables the device functionality, after this function called, even the device is detached to the host, + * and the device can't work. + * + * @param handle The device handle got from USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is stopped successfully. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + */ +usb_status_t USB_DeviceStop(usb_device_handle handle) +{ + return USB_DeviceControl(handle, kUSB_DeviceControlStop, NULL); +} +/*! + * @brief De-initialize the device controller. + * + * The function de-initializes the device controller specified by the handle. + * + * @param handle The device handle got from USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is stopped successfully. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + */ +usb_status_t USB_DeviceDeinit(usb_device_handle handle) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + + if (NULL == deviceHandle) + { + return kStatus_USB_InvalidHandle; + } + /* De-initialize the controller */ + if (NULL != deviceHandle->controllerInterface) + { + /* the callbackFn is initialized in USB_DeviceGetControllerInterface */ + deviceHandle->controllerInterface->deviceDeinit(deviceHandle->controllerHandle); + deviceHandle->controllerInterface = (usb_device_controller_interface_struct_t *)NULL; + } + +#if USB_DEVICE_CONFIG_USE_TASK + /* Destroy the message queue. */ + if (NULL != deviceHandle->notificationQueue) + { + USB_OsaMsgqDestroy(deviceHandle->notificationQueue); + deviceHandle->notificationQueue = NULL; + } +#endif + + /* Free the device handle. */ + USB_DeviceFreeHandle(deviceHandle); + return kStatus_USB_Success; +} + +/*! + * @brief Send data through a specified endpoint. + * + * The function is used to send data through a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint index. + * @param buffer The memory address to hold the data need to be sent. + * @param length The data length need to be sent. + * + * @retval kStatus_USB_Success The send request is sent successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_Busy Cannot allocate dtds for current transfer in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error The device is doing reset. + * + * @note The return value just means if the sending request is successful or not; the transfer done is notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceSendRequest(usb_device_handle handle, uint8_t endpointAddress, uint8_t *buffer, uint32_t length) +{ + return USB_DeviceTransfer(handle, (endpointAddress & USB_ENDPOINT_NUMBER_MASK) | + (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT), + buffer, length); +} + +/*! + * @brief Receive data through a specified endpoint. + * + * The function is used to receive data through a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint index. + * @param buffer The memory address to save the received data. + * @param length The data length want to be received. + * + * @retval kStatus_USB_Success The receive request is sent successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_Busy Cannot allocate dtds for current transfer in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error The device is doing reset. + * + * @note The return value just means if the receiving request is successful or not; the transfer done is notified by the + * corresponding callback function. + * Currently, only one transfer request can be supported for one specific endpoint. + * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application + * should implement a queue in the application level. + * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint + * callback). + */ +usb_status_t USB_DeviceRecvRequest(usb_device_handle handle, uint8_t endpointAddress, uint8_t *buffer, uint32_t length) +{ + return USB_DeviceTransfer(handle, (endpointAddress & USB_ENDPOINT_NUMBER_MASK) | + (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT), + buffer, length); +} + +/*! + * @brief Cancel the pending transfer in a specified endpoint. + * + * The function is used to cancel the pending transfer in a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT. + * + * @retval kStatus_USB_Success The transfer is cancelled. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +usb_status_t USB_DeviceCancel(usb_device_handle handle, uint8_t endpointAddress) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + usb_status_t error = kStatus_USB_Error; + + if (NULL == deviceHandle) + { + return kStatus_USB_InvalidHandle; + } + + if (NULL != deviceHandle->controllerInterface) + { + /* the callbackFn is initialized in USB_DeviceGetControllerInterface */ + error = deviceHandle->controllerInterface->deviceCancel(deviceHandle->controllerHandle, endpointAddress); + } + else + { + error = kStatus_USB_ControllerNotFound; + } + return error; +} + +/*! + * @brief Initialize a specified endpoint. + * + * The function is used to initialize a specified endpoint and the corresponding endpoint callback is also initialized. + * + * @param handle The device handle got from USB_DeviceInit. + * @param epInit Endpoint initialization structure. Please refer to the structure usb_device_endpoint_init_struct_t. + * @param epCallback Endpoint callback structure. Please refer to the structure + * usb_device_endpoint_callback_struct_t. + * + * @retval kStatus_USB_Success The endpoint is initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The epInit or epCallback is NULL pointer. Or the endpoint number is + * more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +usb_status_t USB_DeviceInitEndpoint(usb_device_handle handle, + usb_device_endpoint_init_struct_t *epInit, + usb_device_endpoint_callback_struct_t *epCallback) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + uint8_t endpoint; + uint8_t direction; + + if (!deviceHandle) + { + return kStatus_USB_InvalidHandle; + } + + if ((!epInit) || (!epCallback)) + { + return kStatus_USB_InvalidParameter; + } + + endpoint = epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK; + direction = (epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + + if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS) + { + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn = epCallback->callbackFn; + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam = + epCallback->callbackParam; + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U; + } + else + { + return kStatus_USB_InvalidParameter; + } + return USB_DeviceControl(handle, kUSB_DeviceControlEndpointInit, epInit); +} + +/*! + * @brief De-initizlize a specified endpoint. + * + * The function is used to de-initizlize a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is de-initialized successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +usb_status_t USB_DeviceDeinitEndpoint(usb_device_handle handle, uint8_t endpointAddress) +{ + usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle; + uint8_t endpoint = endpointAddress & USB_ENDPOINT_NUMBER_MASK; + uint8_t direction = (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> + USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT; + usb_status_t error = kStatus_USB_Error; +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + USB_OSA_SR_ALLOC(); +#endif + + if (!deviceHandle) + { + return kStatus_USB_InvalidHandle; + } +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + USB_OSA_ENTER_CRITICAL(); + deviceHandle->epCallbackDirectly = 1; + USB_OSA_EXIT_CRITICAL(); +#endif + error = USB_DeviceControl(handle, kUSB_DeviceControlEndpointDeinit, &endpointAddress); +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + USB_OSA_ENTER_CRITICAL(); + deviceHandle->epCallbackDirectly = 0; + USB_OSA_EXIT_CRITICAL(); +#endif + + if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS) + { + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn = + (usb_device_endpoint_callback_t)NULL; + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam = NULL; + deviceHandle->epCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].isBusy = 0U; + } + else + { + return kStatus_USB_InvalidParameter; + } + return error; +} + +/*! + * @brief Stall a specified endpoint. + * + * The function is used to stall a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is stalled successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +usb_status_t USB_DeviceStallEndpoint(usb_device_handle handle, uint8_t endpointAddress) +{ + if ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS) + { + return USB_DeviceControl(handle, kUSB_DeviceControlEndpointStall, &endpointAddress); + } + else + { + return kStatus_USB_InvalidParameter; + } +} + +/*! + * @brief Un-stall a specified endpoint. + * + * The function is used to un-stall a specified endpoint. + * + * @param handle The device handle got from USB_DeviceInit. + * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT. + * + * @retval kStatus_USB_Success The endpoint is un-stalled successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + */ +usb_status_t USB_DeviceUnstallEndpoint(usb_device_handle handle, uint8_t endpointAddress) +{ + if ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS) + { + return USB_DeviceControl(handle, kUSB_DeviceControlEndpointUnstall, &endpointAddress); + } + else + { + return kStatus_USB_InvalidParameter; + } +} + +/*! + * @brief Get the status of the selected item. + * + * The function is used to get the status of the selected item. + * + * @param handle The device handle got from USB_DeviceInit. + * @param type The selected item. Please refer to the structure usb_device_status_t. + * @param param The param type is determined by the selected item. + * + * @retval kStatus_USB_Success Get status successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_InvalidParameter The param is NULL pointer. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error Unsupported type. + */ +usb_status_t USB_DeviceGetStatus(usb_device_handle handle, usb_device_status_t type, void *param) +{ + uint8_t *temp8; + usb_status_t error = kStatus_USB_Error; + + if (NULL == param) + { + return kStatus_USB_InvalidParameter; + } + switch (type) + { + case kUSB_DeviceStatusSpeed: + error = USB_DeviceControl(handle, kUSB_DeviceControlGetSpeed, param); + break; + case kUSB_DeviceStatusOtg: + error = USB_DeviceControl(handle, kUSB_DeviceControlGetOtgStatus, param); + break; + case kUSB_DeviceStatusDeviceState: + temp8 = (uint8_t *)param; + error = kStatus_USB_Success; + *temp8 = ((usb_device_struct_t *)handle)->state; + break; + case kUSB_DeviceStatusAddress: + temp8 = (uint8_t *)param; + error = kStatus_USB_Success; + *temp8 = ((usb_device_struct_t *)handle)->deviceAddress; + break; + case kUSB_DeviceStatusDevice: + error = USB_DeviceControl(handle, kUSB_DeviceControlGetDeviceStatus, param); + break; + case kUSB_DeviceStatusEndpoint: + error = USB_DeviceControl(handle, kUSB_DeviceControlGetEndpointStatus, param); + break; + case kUSB_DeviceStatusSynchFrame: + error = USB_DeviceControl(handle, kUSB_DeviceControlGetSynchFrame, param); + break; +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + case kUSB_DeviceStatusRemoteWakeup: + temp8 = (uint8_t *)param; + error = kStatus_USB_Success; + *temp8 = ((usb_device_struct_t *)handle)->remotewakeup; + break; +#endif + default: + break; + } + return error; +} + +/*! + * @brief Set the status of the selected item. + * + * The function is used to set the status of the selected item. + * + * @param handle The device handle got from USB_DeviceInit. + * @param type The selected item. Please refer to the structure usb_device_status_t. + * @param param The param type is determined by the selected item. + * + * @retval kStatus_USB_Success Set status successfully. + * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_Error Unsupported type, or the param is NULL pointer. + */ +usb_status_t USB_DeviceSetStatus(usb_device_handle handle, usb_device_status_t type, void *param) +{ + usb_status_t error = kStatus_USB_Error; + switch (type) + { +#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) || \ + (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) && \ + (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U)) + case kUSB_DeviceStatusTestMode: + error = USB_DeviceControl(handle, kUSB_DeviceControlSetTestMode, param); + break; +#endif + case kUSB_DeviceStatusOtg: + error = USB_DeviceControl(handle, kUSB_DeviceControlSetOtgStatus, param); + break; + case kUSB_DeviceStatusDeviceState: + if (NULL != param) + { + error = kStatus_USB_Success; + ((usb_device_struct_t *)handle)->state = (uint8_t)(*(uint8_t *)param); + } + break; + case kUSB_DeviceStatusAddress: + if (kUSB_DeviceStateAddressing != ((usb_device_struct_t *)handle)->state) + { + if (NULL != param) + { + error = kStatus_USB_Success; + ((usb_device_struct_t *)handle)->deviceAddress = (uint8_t)(*(uint8_t *)param); + ((usb_device_struct_t *)handle)->state = kUSB_DeviceStateAddressing; + USB_DeviceControl(handle, kUSB_DeviceControlPreSetDeviceAddress, + &((usb_device_struct_t *)handle)->deviceAddress); + } + } + else + { + error = USB_DeviceControl(handle, kUSB_DeviceControlSetDeviceAddress, + &((usb_device_struct_t *)handle)->deviceAddress); + } + break; + case kUSB_DeviceStatusBusResume: + error = USB_DeviceControl(handle, kUSB_DeviceControlResume, param); + break; + case kUSB_DeviceStatusBusSleepResume: + error = USB_DeviceControl(handle, kUSB_DeviceControlSleepResume, param); + break; +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + case kUSB_DeviceStatusRemoteWakeup: + if (NULL != param) + { + error = kStatus_USB_Success; + ((usb_device_struct_t *)handle)->remotewakeup = (uint8_t)(*(uint8_t *)param); + } + break; +#endif + case kUSB_DeviceStatusBusSuspend: + error = USB_DeviceControl(handle, kUSB_DeviceControlSuspend, param); + break; + case kUSB_DeviceStatusBusSleep: + error = USB_DeviceControl(handle, kUSB_DeviceControlSleep, param); + break; + default: + break; + } + return error; +} + +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) && \ + ((defined(FSL_FEATURE_SOC_USBDCD_COUNT) && (FSL_FEATURE_SOC_USBDCD_COUNT > 0U)) || \ + (defined(FSL_FEATURE_SOC_USBHSDCD_COUNT) && (FSL_FEATURE_SOC_USBHSDCD_COUNT > 0U))) +/*! + * @brief Initializes the device dcd module. + * + * The function initializes the device dcd module. + * + * @param handle The device handle got from USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is run successfully. + * @retval kStatus_USB_ControllerNotFound Cannot find the controller. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + * + */ +usb_status_t USB_DeviceDcdInitModule(usb_device_handle handle, void *time_param) +{ + return USB_DeviceControl(handle, kUSB_DeviceControlDcdInitModule, time_param); +} + +/*! + * @brief De-initializes the device dcd module. + * + * The function de-intializes the device dcd module. + * + * @param handle The device handle got from USB_DeviceInit. + * + * @retval kStatus_USB_Success The device is run successfully. + * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid. + * + */ +usb_status_t USB_DeviceDcdDeinitModule(usb_device_handle handle) +{ + return USB_DeviceControl(handle, kUSB_DeviceControlDcdDeinitModule, NULL); +} +#endif + +#if USB_DEVICE_CONFIG_USE_TASK +/*! + * @brief Device task function. + * + * The function is used to handle controller message. + * This function should not be called in application directly. + * + * @param handle The device handle got from USB_DeviceInit. + */ +void USB_DeviceTaskFunction(void *deviceHandle) +{ + usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle; + static usb_device_callback_message_struct_t message; + + if (deviceHandle) + { + /* Get the message from the queue */ + if (kStatus_USB_OSA_Success == USB_OsaMsgqRecv(handle->notificationQueue, (uint32_t *)&message, 0U)) + { + /* Handle the message */ + USB_DeviceNotification(handle, &message); + } + } +} +#endif + +/*! + * @brief Get device stack version function. + * + * The function is used to get device stack version. + * + * @param[out] version The version structure pointer to keep the device stack version. + * + */ +void USB_DeviceGetVersion(uint32_t *version) +{ + if (version) + { + *version = + (uint32_t)USB_MAKE_VERSION(USB_STACK_VERSION_MAJOR, USB_STACK_VERSION_MINOR, USB_STACK_VERSION_BUGFIX); + } +} + +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) +/*! + * @brief Update the hardware tick. + * + * The function is used to update the hardware tick. + * + * @param[in] handle The device handle got from #USB_DeviceInit. + * @param[in] tick Current hardware tick. + * + */ +usb_status_t USB_DeviceUpdateHwTick(usb_device_handle handle, uint64_t tick) +{ + usb_device_struct_t *deviceHandle; + usb_status_t status = kStatus_USB_Success; + + if (handle == NULL) + { + return kStatus_USB_InvalidHandle; + } + deviceHandle = (usb_device_struct_t *)handle; + + deviceHandle->hwTick = tick; + + return status; +} +#endif +#endif /* USB_DEVICE_CONFIG_NUM */ diff --git a/usb/device/source/usb_device_dci.h b/usb/device/source/usb_device_dci.h new file mode 100644 index 0000000..dba5165 --- /dev/null +++ b/usb/device/source/usb_device_dci.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_DEVICE_DCI_H__ +#define __USB_DEVICE_DCI_H__ + +/*! + * @addtogroup usb_device_controller_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Macro to define controller handle */ +#define usb_device_controller_handle usb_device_handle + +/*! @brief Available notify types for device notification */ +typedef enum _usb_device_notification +{ + kUSB_DeviceNotifyBusReset = 0x10U, /*!< Reset signal detected */ + kUSB_DeviceNotifySuspend, /*!< Suspend signal detected */ + kUSB_DeviceNotifyResume, /*!< Resume signal detected */ + kUSB_DeviceNotifyLPMSleep, /*!< LPM signal detected */ + kUSB_DeviceNotifyLPMResume, /*!< Resume signal detected */ + kUSB_DeviceNotifyError, /*!< Errors happened in bus */ + kUSB_DeviceNotifyDetach, /*!< Device disconnected from a host */ + kUSB_DeviceNotifyAttach, /*!< Device connected to a host */ +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) + kUSB_DeviceNotifyDcdTimeOut, /*!< Device charger detection timeout */ + kUSB_DeviceNotifyDcdUnknownPortType, /*!< Device charger detection unknown port type */ + kUSB_DeviceNotifySDPDetected, /*!< The SDP facility is detected */ + kUSB_DeviceNotifyChargingPortDetected, /*!< The charging port is detected */ + kUSB_DeviceNotifyChargingHostDetected, /*!< The CDP facility is detected */ + kUSB_DeviceNotifyDedicatedChargerDetected, /*!< The DCP facility is detected */ +#endif +} usb_device_notification_t; + +/*! @brief Device notification message structure */ +typedef struct _usb_device_callback_message_struct +{ + uint8_t *buffer; /*!< Transferred buffer */ + uint32_t length; /*!< Transferred data length */ + uint8_t code; /*!< Notification code */ + uint8_t isSetup; /*!< Is in a setup phase */ +} usb_device_callback_message_struct_t; + +/*! @brief Control type for controller */ +typedef enum _usb_device_control_type +{ + kUSB_DeviceControlRun = 0U, /*!< Enable the device functionality */ + kUSB_DeviceControlStop, /*!< Disable the device functionality */ + kUSB_DeviceControlEndpointInit, /*!< Initialize a specified endpoint */ + kUSB_DeviceControlEndpointDeinit, /*!< De-initialize a specified endpoint */ + kUSB_DeviceControlEndpointStall, /*!< Stall a specified endpoint */ + kUSB_DeviceControlEndpointUnstall, /*!< Un-stall a specified endpoint */ + kUSB_DeviceControlGetDeviceStatus, /*!< Get device status */ + kUSB_DeviceControlGetEndpointStatus, /*!< Get endpoint status */ + kUSB_DeviceControlSetDeviceAddress, /*!< Set device address */ + kUSB_DeviceControlGetSynchFrame, /*!< Get current frame */ + kUSB_DeviceControlResume, /*!< Drive controller to generate a resume signal in USB bus */ + kUSB_DeviceControlSleepResume, /*!< Drive controller to generate a LPM resume signal in USB bus */ + kUSB_DeviceControlSuspend, /*!< Drive controller to enter into suspend mode */ + kUSB_DeviceControlSleep, /*!< Drive controller to enter into sleep mode */ + kUSB_DeviceControlSetDefaultStatus, /*!< Set controller to default status */ + kUSB_DeviceControlGetSpeed, /*!< Get current speed */ + kUSB_DeviceControlGetOtgStatus, /*!< Get OTG status */ + kUSB_DeviceControlSetOtgStatus, /*!< Set OTG status */ + kUSB_DeviceControlSetTestMode, /*!< Drive xCHI into test mode */ + kUSB_DeviceControlGetRemoteWakeUp, /*!< Get flag of LPM Remote Wake-up Enabled by USB host. */ +#if (defined(USB_DEVICE_CHARGER_DETECT_ENABLE) && (USB_DEVICE_CHARGER_DETECT_ENABLE > 0U)) + kUSB_DeviceControlDcdInitModule, + kUSB_DeviceControlDcdDeinitModule, +#endif + kUSB_DeviceControlPreSetDeviceAddress, /*!< Pre set device address */ +} usb_device_control_type_t; + +/*! @brief USB device controller initialization function typedef */ +typedef usb_status_t (*usb_device_controller_init_t)(uint8_t controllerId, + usb_device_handle handle, + usb_device_controller_handle *controllerHandle); + +/*! @brief USB device controller de-initialization function typedef */ +typedef usb_status_t (*usb_device_controller_deinit_t)(usb_device_controller_handle controllerHandle); + +/*! @brief USB device controller send data function typedef */ +typedef usb_status_t (*usb_device_controller_send_t)(usb_device_controller_handle controllerHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! @brief USB device controller receive data function typedef */ +typedef usb_status_t (*usb_device_controller_recv_t)(usb_device_controller_handle controllerHandle, + uint8_t endpointAddress, + uint8_t *buffer, + uint32_t length); + +/*! @brief USB device controller cancel transfer function in a specified endpoint typedef */ +typedef usb_status_t (*usb_device_controller_cancel_t)(usb_device_controller_handle controllerHandle, + uint8_t endpointAddress); + +/*! @brief USB device controller control function typedef */ +typedef usb_status_t (*usb_device_controller_control_t)(usb_device_controller_handle controllerHandle, + usb_device_control_type_t command, + void *param); + +/*! @brief USB device controller interface structure */ +typedef struct _usb_device_controller_interface_struct +{ + usb_device_controller_init_t deviceInit; /*!< Controller initialization */ + usb_device_controller_deinit_t deviceDeinit; /*!< Controller de-initialization */ + usb_device_controller_send_t deviceSend; /*!< Controller send data */ + usb_device_controller_recv_t deviceRecv; /*!< Controller receive data */ + usb_device_controller_cancel_t deviceCancel; /*!< Controller cancel transfer */ + usb_device_controller_control_t deviceControl; /*!< Controller control */ +} usb_device_controller_interface_struct_t; + +/*! @brief USB device status structure */ +typedef struct _usb_device_struct +{ +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + volatile uint64_t hwTick; /*!< Current hw tick(ms)*/ +#endif + usb_device_controller_handle controllerHandle; /*!< Controller handle */ + const usb_device_controller_interface_struct_t *controllerInterface; /*!< Controller interface handle */ +#if USB_DEVICE_CONFIG_USE_TASK + usb_osa_msgq_handle notificationQueue; /*!< Message queue */ +#endif + usb_device_callback_t deviceCallback; /*!< Device callback function pointer */ + usb_device_endpoint_callback_struct_t + epCallback[USB_DEVICE_CONFIG_ENDPOINTS << 1U]; /*!< Endpoint callback function structure */ + uint8_t deviceAddress; /*!< Current device address */ + uint8_t controllerId; /*!< Controller ID */ + uint8_t state; /*!< Current device state */ +#if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)) + uint8_t remotewakeup; /*!< Remote wakeup is enabled or not */ +#endif + uint8_t isResetting; /*!< Is doing device reset or not */ +#if (defined(USB_DEVICE_CONFIG_USE_TASK) && (USB_DEVICE_CONFIG_USE_TASK > 0U)) + uint8_t epCallbackDirectly; /*!< Whether call ep callback directly when the task is enabled */ +#endif +} usb_device_struct_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! @}*/ + +#endif /* __USB_DEVICE_DCI_H__ */ diff --git a/usb/include/usb.h b/usb/include/usb.h new file mode 100644 index 0000000..4af703c --- /dev/null +++ b/usb/include/usb.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_H__ +#define __USB_H__ + +#include +#include +#include "fsl_common.h" +#include "usb_osa.h" +#include "usb_misc.h" +#include "usb_spec.h" + + + +/*! + * @addtogroup usb_drv + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief Defines USB stack major version */ +#define USB_STACK_VERSION_MAJOR (2U) +/*! @brief Defines USB stack minor version */ +#define USB_STACK_VERSION_MINOR (1U) +/*! @brief Defines USB stack bugfix version */ +#define USB_STACK_VERSION_BUGFIX (0U) + +/*! @brief USB stack version definition */ +#define USB_MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix)) + +#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix)) + +/*! @brief USB stack component version definition, changed with component in yaml together */ +#define USB_STACK_COMPONENT_VERSION MAKE_VERSION(2,1,0) + +/*! @brief USB error code */ +typedef enum _usb_status +{ + kStatus_USB_Success = 0x00U, /*!< Success */ + kStatus_USB_Error, /*!< Failed */ + + kStatus_USB_Busy, /*!< Busy */ + kStatus_USB_InvalidHandle, /*!< Invalid handle */ + kStatus_USB_InvalidParameter, /*!< Invalid parameter */ + kStatus_USB_InvalidRequest, /*!< Invalid request */ + kStatus_USB_ControllerNotFound, /*!< Controller cannot be found */ + kStatus_USB_InvalidControllerInterface, /*!< Invalid controller interface */ + + kStatus_USB_NotSupported, /*!< Configuration is not supported */ + kStatus_USB_Retry, /*!< Enumeration get configuration retry */ + kStatus_USB_TransferStall, /*!< Transfer stalled */ + kStatus_USB_TransferFailed, /*!< Transfer failed */ + kStatus_USB_AllocFail, /*!< Allocation failed */ + kStatus_USB_LackSwapBuffer, /*!< Insufficient swap buffer for KHCI */ + kStatus_USB_TransferCancel, /*!< The transfer cancelled */ + kStatus_USB_BandwidthFail, /*!< Allocate bandwidth failed */ + kStatus_USB_MSDStatusFail, /*!< For MSD, the CSW status means fail */ + kStatus_USB_EHCIAttached, + kStatus_USB_EHCIDetached, +} usb_status_t; + +/*! @brief USB host handle type define */ +typedef void *usb_host_handle; + +/*! @brief USB device handle type define. For device stack it is the whole device handle; for host stack it is the + * attached device instance handle*/ +typedef void *usb_device_handle; + +/*! @brief USB OTG handle type define */ +typedef void *usb_otg_handle; + +/*! @brief USB controller ID */ +typedef enum _usb_controller_index +{ + kUSB_ControllerKhci0 = 0U, /*!< KHCI 0U */ + kUSB_ControllerKhci1 = 1U, /*!< KHCI 1U, Currently, there are no platforms which have two KHCI IPs, this is reserved + to be used in the future. */ + kUSB_ControllerEhci0 = 2U, /*!< EHCI 0U */ + kUSB_ControllerEhci1 = 3U, /*!< EHCI 1U, Currently, there are no platforms which have two EHCI IPs, this is reserved + to be used in the future. */ + + kUSB_ControllerLpcIp3511Fs0 = 4U, /*!< LPC USB IP3511 FS controller 0 */ + kUSB_ControllerLpcIp3511Fs1 = + 5U, /*!< LPC USB IP3511 FS controller 1, there are no platforms which have two IP3511 IPs, this is reserved + to be used in the future. */ + + kUSB_ControllerLpcIp3511Hs0 = 6U, /*!< LPC USB IP3511 HS controller 0 */ + kUSB_ControllerLpcIp3511Hs1 = + 7U, /*!< LPC USB IP3511 HS controller 1, there are no platforms which have two IP3511 IPs, this is reserved + to be used in the future. */ + + kUSB_ControllerOhci0 = 8U, /*!< OHCI 0U */ + kUSB_ControllerOhci1 = 9U, /*!< OHCI 1U, Currently, there are no platforms which have two OHCI IPs, this is reserved + to be used in the future. */ + + kUSB_ControllerIp3516Hs0 = 10U, /*!< IP3516HS 0U */ + kUSB_ControllerIp3516Hs1 = + 11U, /*!< IP3516HS 1U, Currently, there are no platforms which have two IP3516HS IPs, this is reserved + to be used in the future. */ + kUSB_ControllerDwc30 = 12U, /*!< DWC3 0U */ + kUSB_ControllerDwc31 = + 13U, /*!< DWC3 1U Currently, there are no platforms which have two Dwc IPs, this is reserved + to be used in the future.*/ +} usb_controller_index_t; + +/** +* @brief USB stack version fields +*/ +typedef struct _usb_version +{ + uint8_t major; /*!< Major */ + uint8_t minor; /*!< Minor */ + uint8_t bugfix; /*!< Bug fix */ +} usb_version_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! @} */ + +#endif /* __USB_H__ */ diff --git a/usb/include/usb_misc.h b/usb/include/usb_misc.h new file mode 100644 index 0000000..8c5215f --- /dev/null +++ b/usb/include/usb_misc.h @@ -0,0 +1,430 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_MISC_H__ +#define __USB_MISC_H__ + +#ifndef ENDIANNESS + +#error ENDIANNESS should be defined, and then rebulid the project. + +#endif + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Define USB printf */ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +extern int DbgConsole_Printf(const char *fmt_s, ...); + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +#if defined(SDK_DEBUGCONSOLE) && (SDK_DEBUGCONSOLE < 1) +#define usb_echo printf +#else +#define usb_echo DbgConsole_Printf +#endif + +#if defined(__ICCARM__) + +#ifndef STRUCT_PACKED +#define STRUCT_PACKED __packed +#endif + +#ifndef STRUCT_UNPACKED +#define STRUCT_UNPACKED +#endif + +#elif defined(__GNUC__) + +#ifndef STRUCT_PACKED +#define STRUCT_PACKED +#endif + +#ifndef STRUCT_UNPACKED +#define STRUCT_UNPACKED __attribute__((__packed__)) +#endif + +#elif defined(__CC_ARM) || (defined(__ARMCC_VERSION)) + +#ifndef STRUCT_PACKED +#define STRUCT_PACKED _Pragma("pack(1U)") +#endif + +#ifndef STRUCT_UNPACKED +#define STRUCT_UNPACKED _Pragma("pack()") +#endif + +#endif + +#define USB_SHORT_GET_LOW(x) (((uint16_t)x) & 0xFFU) +#define USB_SHORT_GET_HIGH(x) ((uint8_t)(((uint16_t)x) >> 8U) & 0xFFU) + +#define USB_LONG_GET_BYTE0(x) ((uint8_t)(((uint32_t)(x))) & 0xFFU) +#define USB_LONG_GET_BYTE1(x) ((uint8_t)(((uint32_t)(x)) >> 8U) & 0xFFU) +#define USB_LONG_GET_BYTE2(x) ((uint8_t)(((uint32_t)(x)) >> 16U) & 0xFFU) +#define USB_LONG_GET_BYTE3(x) ((uint8_t)(((uint32_t)(x)) >> 24U) & 0xFFU) + +#define USB_MEM4_ALIGN_MASK (0x03U) + +/* accessory macro */ +#define USB_MEM4_ALIGN(n) ((n + 3U) & (0xFFFFFFFCu)) +#define USB_MEM32_ALIGN(n) ((n + 31U) & (0xFFFFFFE0u)) +#define USB_MEM64_ALIGN(n) ((n + 63U) & (0xFFFFFFC0u)) + +/* big/little endian */ +#define SWAP2BYTE_CONST(n) ((((n)&0x00FFU) << 8U) | (((n)&0xFF00U) >> 8U)) +#define SWAP4BYTE_CONST(n) \ + ((((n)&0x000000FFU) << 24U) | (((n)&0x0000FF00U) << 8U) | (((n)&0x00FF0000U) >> 8U) | (((n)&0xFF000000U) >> 24U)) + +#define USB_ASSIGN_VALUE_ADDRESS_LONG_BY_BYTE(n, m) \ + { \ + *((uint8_t *)&(n)) = *((uint8_t *)&(m)); \ + *((uint8_t *)&(n) + 1) = *((uint8_t *)&(m) + 1); \ + *((uint8_t *)&(n) + 2) = *((uint8_t *)&(m) + 2); \ + *((uint8_t *)&(n) + 3) = *((uint8_t *)&(m) + 3); \ + } + +#define USB_ASSIGN_VALUE_ADDRESS_SHORT_BY_BYTE(n, m) \ + { \ + *((uint8_t *)&(n)) = *((uint8_t *)&(m)); \ + *((uint8_t *)&(n) + 1) = *((uint8_t *)&(m) + 1); \ + } + +#define USB_ASSIGN_MACRO_VALUE_ADDRESS_LONG_BY_BYTE(n, m) \ + { \ + *((uint8_t *)&(n)) = (uint8_t)m; \ + *((uint8_t *)&(n) + 1) = (uint8_t)(m >> 8); \ + *((uint8_t *)&(n) + 2) = (uint8_t)(m >> 16); \ + *((uint8_t *)&(n) + 3) = (uint8_t)(m >> 24); \ + } + +#define USB_ASSIGN_MACRO_VALUE_ADDRESS_SHORT_BY_BYTE(n, m) \ + { \ + *((uint8_t *)&(n)) = (uint8_t)m; \ + *((uint8_t *)&(n) + 1) = (uint8_t)(m >> 8); \ + } + +#if (ENDIANNESS == USB_BIG_ENDIAN) + +#define USB_SHORT_TO_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n) +#define USB_LONG_TO_LITTLE_ENDIAN(n) SWAP4BYTE_CONST(n) +#define USB_SHORT_FROM_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n) +#define USB_LONG_FROM_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n) + +#define USB_SHORT_TO_BIG_ENDIAN(n) (n) +#define USB_LONG_TO_BIG_ENDIAN(n) (n) +#define USB_SHORT_FROM_BIG_ENDIAN(n) (n) +#define USB_LONG_FROM_BIG_ENDIAN(n) (n) + +#define USB_LONG_TO_LITTLE_ENDIAN_ADDRESS(n, m) \ + { \ + m[3] = ((((uint32_t)(n)) >> 24U) & 0xFFU); \ + m[2] = ((((uint32_t)(n)) >> 16U) & 0xFFU); \ + m[1] = ((((uint32_t)(n)) >> 8U) & 0xFFU); \ + m[0] = (((uint32_t)(n)) & 0xFFU); \ + } + +#define USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(n) \ + ((uint32_t)((((uint8_t)n[3]) << 24U) | (((uint8_t)n[2]) << 16U) | (((uint8_t)n[1]) << 8U) | \ + (((uint8_t)n[0]) << 0U))) + +#define USB_LONG_TO_BIG_ENDIAN_ADDRESS(n, m) \ + { \ + m[0] = ((((uint32_t)(n)) >> 24U) & 0xFFU); \ + m[1] = ((((uint32_t)(n)) >> 16U) & 0xFFU); \ + m[2] = ((((uint32_t)(n)) >> 8U) & 0xFFU); \ + m[3] = (((uint32_t)(n)) & 0xFFU); \ + } + +#define USB_LONG_FROM_BIG_ENDIAN_ADDRESS(n) \ + ((uint32_t)((((uint8_t)n[0]) << 24U) | (((uint8_t)n[1]) << 16U) | (((uint8_t)n[2]) << 8U) | \ + (((uint8_t)n[3]) << 0U))) + +#define USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(n, m) \ + { \ + m[1] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \ + m[0] = (((uint16_t)(n)) & 0xFFU); \ + } + +#define USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[1]) << 8U) | (((uint8_t)n[0]) << 0U))) + +#define USB_SHORT_TO_BIG_ENDIAN_ADDRESS(n, m) \ + { \ + m[0] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \ + m[1] = (((uint16_t)(n)) & 0xFFU); \ + } + +#define USB_SHORT_FROM_BIG_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[0]) << 8U) | (((uint8_t)n[1]) << 0U))) + +#define USB_LONG_TO_LITTLE_ENDIAN_DATA(n, m) \ + { \ + *((uint8_t *)&(m) + 3) = ((((uint32_t)(n)) >> 24U) & 0xFFU); \ + *((uint8_t *)&(m) + 2) = ((((uint32_t)(n)) >> 16U) & 0xFFU); \ + *((uint8_t *)&(m) + 1) = ((((uint32_t)(n)) >> 8U) & 0xFFU); \ + *((uint8_t *)&(m) + 0) = (((uint32_t)(n)) & 0xFFU); \ + } + +#define USB_LONG_FROM_LITTLE_ENDIAN_DATA(n) \ + ((uint32_t)(((*((uint8_t *)&(n) + 3)) << 24U) | ((*((uint8_t *)&(n) + 2)) << 16U) | \ + ((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n))) << 0U))) + +#define USB_SHORT_TO_LITTLE_ENDIAN_DATA(n, m) \ + { \ + *((uint8_t *)&(m) + 1) = ((((uint16_t)(n)) >> 8U) & 0xFFU); \ + *((uint8_t *)&(m)) = ((((uint16_t)(n))) & 0xFFU); \ + } + +#define USB_SHORT_FROM_LITTLE_ENDIAN_DATA(n) ((uint32_t)(((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n)))))) + +#else + +#define USB_SHORT_TO_LITTLE_ENDIAN(n) (n) +#define USB_LONG_TO_LITTLE_ENDIAN(n) (n) +#define USB_SHORT_FROM_LITTLE_ENDIAN(n) (n) +#define USB_LONG_FROM_LITTLE_ENDIAN(n) (n) + +#define USB_SHORT_TO_BIG_ENDIAN(n) SWAP2BYTE_CONST(n) +#define USB_LONG_TO_BIG_ENDIAN(n) SWAP4BYTE_CONST(n) +#define USB_SHORT_FROM_BIG_ENDIAN(n) SWAP2BYTE_CONST(n) +#define USB_LONG_FROM_BIG_ENDIAN(n) SWAP4BYTE_CONST(n) + +#define USB_LONG_TO_LITTLE_ENDIAN_ADDRESS(n, m) \ + { \ + m[3] = ((((uint32_t)(n)) >> 24U) & 0xFFU); \ + m[2] = ((((uint32_t)(n)) >> 16U) & 0xFFU); \ + m[1] = ((((uint32_t)(n)) >> 8U) & 0xFFU); \ + m[0] = (((uint32_t)(n)) & 0xFFU); \ + } + +#define USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(n) \ + ((uint32_t)((((uint8_t)n[3]) << 24U) | (((uint8_t)n[2]) << 16U) | (((uint8_t)n[1]) << 8U) | \ + (((uint8_t)n[0]) << 0U))) + +#define USB_LONG_TO_BIG_ENDIAN_ADDRESS(n, m) \ + { \ + m[0] = ((((uint32_t)(n)) >> 24U) & 0xFFU); \ + m[1] = ((((uint32_t)(n)) >> 16U) & 0xFFU); \ + m[2] = ((((uint32_t)(n)) >> 8U) & 0xFFU); \ + m[3] = (((uint32_t)(n)) & 0xFFU); \ + } + +#define USB_LONG_FROM_BIG_ENDIAN_ADDRESS(n) \ + ((uint32_t)((((uint8_t)n[0]) << 24U) | (((uint8_t)n[1]) << 16U) | (((uint8_t)n[2]) << 8U) | \ + (((uint8_t)n[3]) << 0U))) + +#define USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(n, m) \ + { \ + m[1] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \ + m[0] = (((uint16_t)(n)) & 0xFFU); \ + } + +#define USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[1]) << 8U) | (((uint8_t)n[0]) << 0U))) + +#define USB_SHORT_TO_BIG_ENDIAN_ADDRESS(n, m) \ + { \ + m[0] = ((((uint16_t)(n)) >> 8U) & 0xFFU); \ + m[1] = (((uint16_t)(n)) & 0xFFU); \ + } + +#define USB_SHORT_FROM_BIG_ENDIAN_ADDRESS(n) ((uint32_t)((((uint8_t)n[0]) << 8U) | (((uint8_t)n[1]) << 0U))) + +#define USB_LONG_TO_LITTLE_ENDIAN_DATA(n, m) \ + { \ + *((uint8_t *)&(m) + 3) = ((((uint32_t)(n)) >> 24U) & 0xFFU); \ + *((uint8_t *)&(m) + 2) = ((((uint32_t)(n)) >> 16U) & 0xFFU); \ + *((uint8_t *)&(m) + 1) = ((((uint32_t)(n)) >> 8U) & 0xFFU); \ + *((uint8_t *)&(m) + 0) = (((uint32_t)(n)) & 0xFFU); \ + } + +#define USB_LONG_FROM_LITTLE_ENDIAN_DATA(n) \ + ((uint32_t)(((*((uint8_t *)&(n) + 3)) << 24U) | ((*((uint8_t *)&(n) + 2)) << 16U) | \ + ((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n))) << 0U))) + +#define USB_SHORT_TO_LITTLE_ENDIAN_DATA(n, m) \ + { \ + *((uint8_t *)&(m) + 1) = ((((uint16_t)(n)) >> 8U) & 0xFFU); \ + *((uint8_t *)&(m)) = ((((uint16_t)(n))) & 0xFFU); \ + } + +#define USB_SHORT_FROM_LITTLE_ENDIAN_DATA(n) ((uint32_t)(((*((uint8_t *)&(n) + 1)) << 8U) | ((*((uint8_t *)&(n)))))) + +#endif + +/* + * The following MACROs (USB_GLOBAL, USB_BDT, USB_RAM_ADDRESS_ALIGNMENT, etc) are only used for USB device stack. + * The USB device global variables are put into the section m_usb_global and m_usb_bdt or the section + * .bss.m_usb_global and .bss.m_usb_bdt by using the MACRO USB_GLOBAL and USB_BDT. In this way, the USB device + * global variables can be linked into USB dedicated RAM by USB_STACK_USE_DEDICATED_RAM. + * The MACRO USB_STACK_USE_DEDICATED_RAM is used to decide the USB stack uses dedicated RAM or not. The value of + * the macro can be set as 0, USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL, or USB_STACK_DEDICATED_RAM_TYPE_BDT. + * The MACRO USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL means USB device global variables, including USB_BDT and + * USB_GLOBAL, are put into the USB dedicated RAM. This feature can only be enabled when the USB dedicated RAM + * is not less than 2K Bytes. + * The MACRO USB_STACK_DEDICATED_RAM_TYPE_BDT means USB device global variables, only including USB_BDT, are put + * into the USB dedicated RAM, the USB_GLOBAL will be put into .bss section. This feature is used for some SOCs, + * the USB dedicated RAM size is not more than 512 Bytes. + */ +#define USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL 1 +#define USB_STACK_DEDICATED_RAM_TYPE_BDT 2 + +#if defined(__ICCARM__) + +#define USB_WEAK_VAR __attribute__((weak)) +#define USB_WEAK_FUN __attribute__((weak)) +/* disable misra 19.13 */ +_Pragma("diag_suppress=Pm120") +#define USB_ALIGN_PRAGMA(x) _Pragma(#x) + _Pragma("diag_default=Pm120") + +#define USB_RAM_ADDRESS_ALIGNMENT(n) USB_ALIGN_PRAGMA(data_alignment = n) + _Pragma("diag_suppress=Pm120") +#define USB_LINK_SECTION_PART(str) _Pragma(#str) +#define USB_LINK_DMA_INIT_DATA(sec) USB_LINK_SECTION_PART(location = #sec) +#define USB_LINK_USB_GLOBAL _Pragma("location = \"m_usb_global\"") +#define USB_LINK_USB_BDT _Pragma("location = \"m_usb_bdt\"") +#define USB_LINK_USB_GLOBAL_BSS _Pragma("location = \".bss.m_usb_global\"") +#define USB_LINK_USB_BDT_BSS _Pragma("location = \".bss.m_usb_bdt\"") + _Pragma("diag_default=Pm120") +#define USB_LINK_DMA_NONINIT_DATA _Pragma("location = \"m_usb_dma_noninit_data\"") +#define USB_LINK_NONCACHE_NONINIT_DATA _Pragma("location = \"NonCacheable\"") +#elif defined(__CC_ARM) || (defined(__ARMCC_VERSION)) + +#define USB_WEAK_VAR __attribute__((weak)) +#define USB_WEAK_FUN __attribute__((weak)) +#define USB_RAM_ADDRESS_ALIGNMENT(n) __attribute__((aligned(n))) +#define USB_LINK_DMA_INIT_DATA(sec) __attribute__((section(#sec))) +#define USB_LINK_USB_GLOBAL __attribute__((section("m_usb_global"))) __attribute__((zero_init)) +#define USB_LINK_USB_BDT __attribute__((section("m_usb_bdt"))) __attribute__((zero_init)) +#define USB_LINK_USB_GLOBAL_BSS __attribute__((section(".bss.m_usb_global"))) __attribute__((zero_init)) +#define USB_LINK_USB_BDT_BSS __attribute__((section(".bss.m_usb_bdt"))) __attribute__((zero_init)) +#define USB_LINK_DMA_NONINIT_DATA __attribute__((section("m_usb_dma_noninit_data"))) __attribute__((zero_init)) +#define USB_LINK_NONCACHE_NONINIT_DATA __attribute__((section("NonCacheable"))) __attribute__((zero_init)) + +#elif defined(__GNUC__) + +#define USB_WEAK_VAR __attribute__((weak)) +#define USB_WEAK_FUN __attribute__((weak)) +#define USB_RAM_ADDRESS_ALIGNMENT(n) __attribute__((aligned(n))) +#define USB_LINK_DMA_INIT_DATA(sec) __attribute__((section(#sec))) +#define USB_LINK_USB_GLOBAL __attribute__((section("m_usb_global, \"aw\", %nobits @"))) +#define USB_LINK_USB_BDT __attribute__((section("m_usb_bdt, \"aw\", %nobits @"))) +#define USB_LINK_USB_GLOBAL_BSS __attribute__((section(".bss.m_usb_global, \"aw\", %nobits @"))) +#define USB_LINK_USB_BDT_BSS __attribute__((section(".bss.m_usb_bdt, \"aw\", %nobits @"))) +#define USB_LINK_DMA_NONINIT_DATA __attribute__((section("m_usb_dma_noninit_data, \"aw\", %nobits @"))) +#define USB_LINK_NONCACHE_NONINIT_DATA __attribute__((section("NonCacheable, \"aw\", %nobits @"))) + +#else +#error The tool-chain is not supported. +#endif + +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \ + (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) + +#if ((defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)) && (defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))) +#define USB_CACHE_LINESIZE MAX(FSL_FEATURE_L2CACHE_LINESIZE_BYTE, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#elif(defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)) +#define USB_CACHE_LINESIZE MAX(FSL_FEATURE_L2CACHE_LINESIZE_BYTE, 0) +#elif(defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)) +#define USB_CACHE_LINESIZE MAX(0, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#else +#define USB_CACHE_LINESIZE 4 +#endif + +#else +#define USB_CACHE_LINESIZE 4 +#endif + +#if (((defined(USB_DEVICE_CONFIG_LPCIP3511FS)) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)) || \ + ((defined(USB_DEVICE_CONFIG_LPCIP3511HS)) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) +#define USB_DATA_ALIGN 64 +#else +#define USB_DATA_ALIGN 4 +#endif + +#define USB_DATA_ALIGN_SIZE MAX(USB_CACHE_LINESIZE, USB_DATA_ALIGN) + +#define USB_DATA_ALIGN_SIZE_MULTIPLE(n) ((n + USB_DATA_ALIGN_SIZE - 1) & (~(USB_DATA_ALIGN_SIZE - 1))) + +#if defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM == USB_STACK_DEDICATED_RAM_TYPE_BDT_GLOBAL) + +#define USB_GLOBAL USB_LINK_USB_GLOBAL +#define USB_BDT USB_LINK_USB_BDT + +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \ + (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) +#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA +#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(m_usb_dma_init_data) +#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA +#else +#define USB_DMA_DATA_NONINIT_SUB +#define USB_DMA_DATA_INIT_SUB +#define USB_CONTROLLER_DATA USB_LINK_USB_GLOBAL +#endif + +#elif defined(USB_STACK_USE_DEDICATED_RAM) && (USB_STACK_USE_DEDICATED_RAM == USB_STACK_DEDICATED_RAM_TYPE_BDT) + +#define USB_BDT USB_LINK_USB_BDT + +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \ + (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) +#define USB_GLOBAL USB_LINK_DMA_NONINIT_DATA +#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA +#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(m_usb_dma_init_data) +#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA +#else +#define USB_GLOBAL USB_LINK_USB_GLOBAL_BSS +#define USB_DMA_DATA_NONINIT_SUB +#define USB_DMA_DATA_INIT_SUB +#define USB_CONTROLLER_DATA +#endif + +#else + +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \ + (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) + +#define USB_GLOBAL USB_LINK_DMA_NONINIT_DATA +#define USB_BDT USB_LINK_NONCACHE_NONINIT_DATA +#define USB_DMA_DATA_NONINIT_SUB USB_LINK_DMA_NONINIT_DATA +#define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(m_usb_dma_init_data) +#define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA + +#else +#define USB_GLOBAL USB_LINK_USB_GLOBAL_BSS +#define USB_BDT USB_LINK_USB_BDT_BSS +#define USB_DMA_DATA_NONINIT_SUB +#define USB_DMA_DATA_INIT_SUB +#define USB_CONTROLLER_DATA +#endif + +#endif + +#define USB_DMA_NONINIT_DATA_ALIGN(n) USB_RAM_ADDRESS_ALIGNMENT(n) USB_DMA_DATA_NONINIT_SUB +#define USB_DMA_INIT_DATA_ALIGN(n) USB_RAM_ADDRESS_ALIGNMENT(n) USB_DMA_DATA_INIT_SUB + +#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE)) || \ + (defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) +#define USB_DMA_DATA_NONCACHEABLE USB_LINK_NONCACHE_NONINIT_DATA + +#else +#define USB_DMA_DATA_NONCACHEABLE +#endif + +#define USB_GLOBAL_DEDICATED_RAM USB_LINK_USB_GLOBAL + +/* #define USB_RAM_ADDRESS_NONCACHEREG_ALIGNMENT(n, var) AT_NONCACHEABLE_SECTION_ALIGN(var, n) */ +/* #define USB_RAM_ADDRESS_NONCACHEREG(var) AT_NONCACHEABLE_SECTION(var) */ + +#endif /* __USB_MISC_H__ */ diff --git a/usb/include/usb_spec.h b/usb/include/usb_spec.h new file mode 100644 index 0000000..f9f33a6 --- /dev/null +++ b/usb/include/usb_spec.h @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __USB_SPEC_H__ +#define __USB_SPEC_H__ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* USB speed (the value cannot be changed because EHCI QH use the value directly)*/ +#define USB_SPEED_FULL (0x00U) +#define USB_SPEED_LOW (0x01U) +#define USB_SPEED_HIGH (0x02U) +#define USB_SPEED_SUPER (0x04U) + +/* Set up packet structure */ +typedef struct _usb_setup_struct +{ + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} usb_setup_struct_t; + +/* USB standard descriptor endpoint type */ +#define USB_ENDPOINT_CONTROL (0x00U) +#define USB_ENDPOINT_ISOCHRONOUS (0x01U) +#define USB_ENDPOINT_BULK (0x02U) +#define USB_ENDPOINT_INTERRUPT (0x03U) + +/* USB standard descriptor transfer direction (cannot change the value because iTD use the value directly) */ +#define USB_OUT (0U) +#define USB_IN (1U) + +/* USB standard descriptor length */ +#define USB_DESCRIPTOR_LENGTH_DEVICE (0x12U) +#define USB_DESCRIPTOR_LENGTH_CONFIGURE (0x09U) +#define USB_DESCRIPTOR_LENGTH_INTERFACE (0x09U) +#define USB_DESCRIPTOR_LENGTH_ENDPOINT (0x07U) +#define USB_DESCRIPTOR_LENGTH_ENDPOINT_COMPANION (0x06U) +#define USB_DESCRIPTOR_LENGTH_DEVICE_QUALITIER (0x0AU) +#define USB_DESCRIPTOR_LENGTH_OTG_DESCRIPTOR (5U) +#define USB_DESCRIPTOR_LENGTH_BOS_DESCRIPTOR (5U) +#define USB_DESCRIPTOR_LENGTH_DEVICE_CAPABILITY_USB20_EXTENSION (0x07U) +#define USB_DESCRIPTOR_LENGTH_DEVICE_CAPABILITY_SUPERSPEED (0x0AU) + +/* USB Device Capability Type Codes */ +#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY_WIRELESS (0x01U) +#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY_USB20_EXTENSION (0x02U) +#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY_SUPERSPEED (0x03U) + +/* USB standard descriptor type */ +#define USB_DESCRIPTOR_TYPE_DEVICE (0x01U) +#define USB_DESCRIPTOR_TYPE_CONFIGURE (0x02U) +#define USB_DESCRIPTOR_TYPE_STRING (0x03U) +#define USB_DESCRIPTOR_TYPE_INTERFACE (0x04U) +#define USB_DESCRIPTOR_TYPE_ENDPOINT (0x05U) +#define USB_DESCRIPTOR_TYPE_DEVICE_QUALITIER (0x06U) +#define USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION (0x07U) +#define USB_DESCRIPTOR_TYPE_INTERFAACE_POWER (0x08U) +#define USB_DESCRIPTOR_TYPE_OTG (0x09U) +#define USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION (0x0BU) +#define USB_DESCRIPTOR_TYPE_BOS (0x0F) +#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY (0x10) + +#define USB_DESCRIPTOR_TYPE_HID (0x21U) +#define USB_DESCRIPTOR_TYPE_HID_REPORT (0x22U) +#define USB_DESCRIPTOR_TYPE_HID_PHYSICAL (0x23U) + +#define USB_DESCRIPTOR_TYPE_ENDPOINT_COMPANION (0x30U) + +/* USB standard request type */ +#define USB_REQUEST_TYPE_DIR_MASK (0x80U) +#define USB_REQUEST_TYPE_DIR_SHIFT (7U) +#define USB_REQUEST_TYPE_DIR_OUT (0x00U) +#define USB_REQUEST_TYPE_DIR_IN (0x80U) + +#define USB_REQUEST_TYPE_TYPE_MASK (0x60U) +#define USB_REQUEST_TYPE_TYPE_SHIFT (5U) +#define USB_REQUEST_TYPE_TYPE_STANDARD (0U) +#define USB_REQUEST_TYPE_TYPE_CLASS (0x20U) +#define USB_REQUEST_TYPE_TYPE_VENDOR (0x40U) + +#define USB_REQUEST_TYPE_RECIPIENT_MASK (0x1FU) +#define USB_REQUEST_TYPE_RECIPIENT_SHIFT (0U) +#define USB_REQUEST_TYPE_RECIPIENT_DEVICE (0x00U) +#define USB_REQUEST_TYPE_RECIPIENT_INTERFACE (0x01U) +#define USB_REQUEST_TYPE_RECIPIENT_ENDPOINT (0x02U) +#define USB_REQUEST_TYPE_RECIPIENT_OTHER (0x03U) + +/* USB standard request */ +#define USB_REQUEST_STANDARD_GET_STATUS (0x00U) +#define USB_REQUEST_STANDARD_CLEAR_FEATURE (0x01U) +#define USB_REQUEST_STANDARD_SET_FEATURE (0x03U) +#define USB_REQUEST_STANDARD_SET_ADDRESS (0x05U) +#define USB_REQUEST_STANDARD_GET_DESCRIPTOR (0x06U) +#define USB_REQUEST_STANDARD_SET_DESCRIPTOR (0x07U) +#define USB_REQUEST_STANDARD_GET_CONFIGURATION (0x08U) +#define USB_REQUEST_STANDARD_SET_CONFIGURATION (0x09U) +#define USB_REQUEST_STANDARD_GET_INTERFACE (0x0AU) +#define USB_REQUEST_STANDARD_SET_INTERFACE (0x0BU) +#define USB_REQUEST_STANDARD_SYNCH_FRAME (0x0CU) + +/* USB standard request GET Status */ +#define USB_REQUEST_STANDARD_GET_STATUS_DEVICE_SELF_POWERED_SHIFT (0U) +#define USB_REQUEST_STANDARD_GET_STATUS_DEVICE_REMOTE_WARKUP_SHIFT (1U) + +#define USB_REQUEST_STANDARD_GET_STATUS_ENDPOINT_HALT_MASK (0x01U) +#define USB_REQUEST_STANDARD_GET_STATUS_ENDPOINT_HALT_SHIFT (0U) + +#define USB_REQUEST_STANDARD_GET_STATUS_OTG_STATUS_SELECTOR (0xF000U) + +/* USB standard request CLEAR/SET feature */ +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT (0U) +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_REMOTE_WAKEUP (1U) +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_TEST_MODE (2U) +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_B_HNP_ENABLE (3U) +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_A_HNP_SUPPORT (4U) +#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_A_ALT_HNP_SUPPORT (5U) + +/* USB standard descriptor configure bmAttributes */ +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_MASK (0x80U) +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_SHIFT (7U) + +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_MASK (0x40U) +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_SHIFT (6U) + +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_MASK (0x20U) +#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_SHIFT (5U) + +/* USB standard descriptor endpoint bmAttributes */ +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK (0x80U) +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT (7U) +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT (0U) +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN (0x80U) + +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK (0x0FU) +#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_SHFIT (0U) + +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK (0x03U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_NUMBER_SHFIT (0U) + +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_MASK (0x0CU) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_SHFIT (2U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_NO_SYNC (0x00U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_ASYNC (0x04U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_ADAPTIVE (0x08U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_SYNC (0x0CU) + +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_MASK (0x30U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_SHFIT (4U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_DATA_ENDPOINT (0x00U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_FEEDBACK_ENDPOINT (0x10U) +#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_IMPLICIT_FEEDBACK_DATA_ENDPOINT (0x20U) + +#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK (0x07FFu) +#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK (0x1800u) +#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_SHFIT (11U) + +/* USB standard descriptor otg bmAttributes */ +#define USB_DESCRIPTOR_OTG_ATTRIBUTES_SRP_MASK (0x01u) +#define USB_DESCRIPTOR_OTG_ATTRIBUTES_HNP_MASK (0x02u) +#define USB_DESCRIPTOR_OTG_ATTRIBUTES_ADP_MASK (0x04u) + +/* USB standard descriptor device capability usb20 extension bmAttributes */ +#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_LPM_MASK (0x02U) +#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_LPM_SHIFT (1U) +#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_BESL_MASK (0x04U) +#define USB_DESCRIPTOR_DEVICE_CAPABILITY_USB20_EXTENSION_BESL_SHIFT (2U) + + +/* Language structure */ +typedef struct _usb_language +{ + uint8_t **string; /* The Strings descriptor array */ + uint32_t *length; /* The strings descriptor length array */ + uint16_t languageId; /* The language id of current language */ +} usb_language_t; + +typedef struct _usb_language_list +{ + uint8_t *languageString; /* The String 0U pointer */ + uint32_t stringLength; /* The String 0U Length */ + usb_language_t *languageList; /* The language list */ + uint8_t count; /* The language count */ +} usb_language_list_t; + +typedef struct _usb_descriptor_common +{ + uint8_t bLength; /* Size of this descriptor in bytes */ + uint8_t bDescriptorType; /* DEVICE Descriptor Type */ + uint8_t bData[1]; /* Data */ +} usb_descriptor_common_t; + +typedef struct _usb_descriptor_device +{ + uint8_t bLength; /* Size of this descriptor in bytes */ + uint8_t bDescriptorType; /* DEVICE Descriptor Type */ + uint8_t bcdUSB[2]; /* UUSB Specification Release Number in Binary-Coded Decimal, e.g. 0x0200U */ + uint8_t bDeviceClass; /* Class code */ + uint8_t bDeviceSubClass; /* Sub-Class code */ + uint8_t bDeviceProtocol; /* Protocol code */ + uint8_t bMaxPacketSize0; /* Maximum packet size for endpoint zero */ + uint8_t idVendor[2]; /* Vendor ID (assigned by the USB-IF) */ + uint8_t idProduct[2]; /* Product ID (assigned by the manufacturer) */ + uint8_t bcdDevice[2]; /* Device release number in binary-coded decimal */ + uint8_t iManufacturer; /* Index of string descriptor describing manufacturer */ + uint8_t iProduct; /* Index of string descriptor describing product */ + uint8_t iSerialNumber; /* Index of string descriptor describing the device serial number */ + uint8_t bNumConfigurations; /* Number of possible configurations */ +} usb_descriptor_device_t; + +typedef struct _usb_descriptor_configuration +{ + uint8_t bLength; /* Descriptor size in bytes = 9U */ + uint8_t bDescriptorType; /* CONFIGURATION type = 2U or 7U */ + uint8_t wTotalLength[2]; /* Length of concatenated descriptors */ + uint8_t bNumInterfaces; /* Number of interfaces, this configuration. */ + uint8_t bConfigurationValue; /* Value to set this configuration. */ + uint8_t iConfiguration; /* Index to configuration string */ + uint8_t bmAttributes; /* Configuration characteristics */ + uint8_t bMaxPower; /* Maximum power from bus, 2 mA units */ +} usb_descriptor_configuration_t; + +typedef struct _usb_descriptor_interface +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} usb_descriptor_interface_t; + +typedef struct _usb_descriptor_endpoint +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint8_t wMaxPacketSize[2]; + uint8_t bInterval; +} usb_descriptor_endpoint_t; + +typedef struct _usb_descriptor_endpoint_companion +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bMaxBurst; + uint8_t bmAttributes; + uint8_t wBytesPerInterval[2]; +} usb_descriptor_endpoint_companion_t; + +typedef struct _usb_descriptor_binary_device_object_store +{ + uint8_t bLength; /* Descriptor size in bytes = 5U */ + uint8_t bDescriptorType; /* BOS Descriptor type = 0FU*/ + uint8_t wTotalLength[2]; /*Length of this descriptor and all of its sub descriptors*/ + uint8_t bNumDeviceCaps; /*The number of separate device capability descriptors in the BOS*/ +} usb_descriptor_bos_t; + +typedef struct _usb_descriptor_usb20_extension +{ + uint8_t bLength; /* Descriptor size in bytes = 7U */ + uint8_t bDescriptorType; /* DEVICE CAPABILITY Descriptor type = 0x10U*/ + uint8_t bDevCapabilityType; /*Length of this descriptor and all of its sub descriptors*/ + uint8_t bmAttributes[4]; /*Bitmap encoding of supported device level features.*/ +} usb_descriptor_usb20_extension_t; +typedef struct _usb_descriptor_super_speed_device_capability +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDevCapabilityType; + uint8_t bmAttributes; + uint8_t wSpeedsSupported[2]; + uint8_t bFunctionalitySupport; + uint8_t bU1DevExitLat; + uint8_t wU2DevExitLat[2]; +} usb_bos_device_capability_susperspeed_desc_t; +typedef union _usb_descriptor_union +{ + usb_descriptor_common_t common; /* Common descriptor */ + usb_descriptor_device_t device; /* Device descriptor */ + usb_descriptor_configuration_t configuration; /* Configuration descriptor */ + usb_descriptor_interface_t interface; /* Interface descriptor */ + usb_descriptor_endpoint_t endpoint; /* Endpoint descriptor */ + usb_descriptor_endpoint_companion_t endpointCompanion; /* Endpoint companion descriptor */ +} usb_descriptor_union_t; + +#endif /* __USB_SPEC_H__ */ diff --git a/usb/phy/usb_phy.c b/usb/phy/usb_phy.c new file mode 100644 index 0000000..c4be356 --- /dev/null +++ b/usb/phy/usb_phy.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "usb.h" +#include "fsl_device_registers.h" + +#include "usb_phy.h" + +void *USB_EhciPhyGetBase(uint8_t controllerId) +{ + void *usbPhyBase = NULL; +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) + uint32_t instance; + uint32_t newinstance = 0; + uint32_t usbphy_base_temp[] = USBPHY_BASE_ADDRS; + uint32_t usbphy_base[] = USBPHY_BASE_ADDRS; + + if (controllerId < kUSB_ControllerEhci0) + { + return NULL; + } + + if ((controllerId == kUSB_ControllerEhci0) || (controllerId == kUSB_ControllerEhci1)) + { + controllerId = controllerId - kUSB_ControllerEhci0; + } + else if ((controllerId == kUSB_ControllerLpcIp3511Hs0) || (controllerId == kUSB_ControllerLpcIp3511Hs1)) + { + controllerId = controllerId - kUSB_ControllerLpcIp3511Hs0; + } + else if ((controllerId == kUSB_ControllerIp3516Hs0) || (controllerId == kUSB_ControllerIp3516Hs1)) + { + controllerId = controllerId - kUSB_ControllerIp3516Hs0; + } + else + { + } + + for (instance = 0; instance < (sizeof(usbphy_base_temp) / sizeof(usbphy_base_temp[0])); instance++) + { + if (usbphy_base_temp[instance]) + { + usbphy_base[newinstance++] = usbphy_base_temp[instance]; + } + } + if (controllerId > newinstance) + { + return NULL; + } + + usbPhyBase = (void *)usbphy_base[controllerId]; +#endif + return usbPhyBase; +} + +/*! + * @brief ehci phy initialization. + * + * This function initialize ehci phy IP. + * + * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t. + * @param[in] freq the external input clock. + * for example: if the external input clock is 16M, the parameter freq should be 16000000. + * + * @retval kStatus_USB_Success cancel successfully. + * @retval kStatus_USB_Error the freq value is incorrect. + */ +uint32_t USB_EhciPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig) +{ +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) + USBPHY_Type *usbPhyBase; + + usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId); + if (NULL == usbPhyBase) + { + return kStatus_USB_Error; + } + +#if ((defined FSL_FEATURE_SOC_ANATOP_COUNT) && (FSL_FEATURE_SOC_ANATOP_COUNT > 0U)) + ANATOP->HW_ANADIG_REG_3P0.RW = + (ANATOP->HW_ANADIG_REG_3P0.RW & + (~(ANATOP_HW_ANADIG_REG_3P0_OUTPUT_TRG(0x1F) | ANATOP_HW_ANADIG_REG_3P0_ENABLE_ILIMIT_MASK))) | + ANATOP_HW_ANADIG_REG_3P0_OUTPUT_TRG(0x17) | ANATOP_HW_ANADIG_REG_3P0_ENABLE_LINREG_MASK; + ANATOP->HW_ANADIG_USB2_CHRG_DETECT.SET = + ANATOP_HW_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B_MASK | ANATOP_HW_ANADIG_USB2_CHRG_DETECT_EN_B_MASK; +#endif + +#if (defined USB_ANALOG) + USB_ANALOG->INSTANCE[controllerId - kUSB_ControllerEhci0].CHRG_DETECT_SET = USB_ANALOG_CHRG_DETECT_CHK_CHRG_B(1) | USB_ANALOG_CHRG_DETECT_EN_B(1); +#endif + +#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT))) + + usbPhyBase->TRIM_OVERRIDE_EN = 0x001fU; /* override IFR value */ +#endif + usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK; /* support LS device. */ + usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; /* support external FS Hub with LS device connected. */ + /* PWD register provides overall control of the PHY power state */ + usbPhyBase->PWD = 0U; + if ((kUSB_ControllerIp3516Hs0 == controllerId) || (kUSB_ControllerIp3516Hs1 == controllerId) || + (kUSB_ControllerLpcIp3511Hs0 == controllerId) || (kUSB_ControllerLpcIp3511Hs0 == controllerId)) + { + usbPhyBase->CTRL_SET = USBPHY_CTRL_SET_ENAUTOCLR_CLKGATE_MASK; + usbPhyBase->CTRL_SET = USBPHY_CTRL_SET_ENAUTOCLR_PHY_PWD_MASK; + } + if (NULL != phyConfig) + { + /* Decode to trim the nominal 17.78mA current source for the High Speed TX drivers on USB_DP and USB_DM. */ + usbPhyBase->TX = + ((usbPhyBase->TX & (~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK))) | + (USBPHY_TX_D_CAL(phyConfig->D_CAL) | USBPHY_TX_TXCAL45DP(phyConfig->TXCAL45DP) | + USBPHY_TX_TXCAL45DM(phyConfig->TXCAL45DM))); + } +#endif + + return kStatus_USB_Success; +} + +/*! + * @brief ehci phy initialization for suspend and resume. + * + * This function initialize ehci phy IP for suspend and resume. + * + * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t. + * @param[in] freq the external input clock. + * for example: if the external input clock is 16M, the parameter freq should be 16000000. + * + * @retval kStatus_USB_Success cancel successfully. + * @retval kStatus_USB_Error the freq value is incorrect. + */ +uint32_t USB_EhciLowPowerPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig) +{ +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) + USBPHY_Type *usbPhyBase; + + usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId); + if (NULL == usbPhyBase) + { + return kStatus_USB_Error; + } + +#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT))) + usbPhyBase->TRIM_OVERRIDE_EN = 0x001fU; /* override IFR value */ +#endif + +#if ((defined USBPHY_CTRL_AUTORESUME_EN_MASK) && (USBPHY_CTRL_AUTORESUME_EN_MASK > 0U)) + usbPhyBase->CTRL |= USBPHY_CTRL_AUTORESUME_EN_MASK; +#else + usbPhyBase->CTRL |= USBPHY_CTRL_ENAUTO_PWRON_PLL_MASK; +#endif + usbPhyBase->CTRL |= USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK | USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK; + usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK; /* support LS device. */ + usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; /* support external FS Hub with LS device connected. */ + /* PWD register provides overall control of the PHY power state */ + usbPhyBase->PWD = 0U; +#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT))) + /* now the 480MHz USB clock is up, then configure fractional divider after PLL with PFD + * pfd clock = 480MHz*18/N, where N=18~35 + * Please note that USB1PFDCLK has to be less than 180MHz for RUN or HSRUN mode + */ + usbPhyBase->ANACTRL |= USBPHY_ANACTRL_PFD_FRAC(24); /* N=24 */ + usbPhyBase->ANACTRL |= USBPHY_ANACTRL_PFD_CLK_SEL(1); /* div by 4 */ + + usbPhyBase->ANACTRL &= ~USBPHY_ANACTRL_DEV_PULLDOWN_MASK; + usbPhyBase->ANACTRL &= ~USBPHY_ANACTRL_PFD_CLKGATE_MASK; + while (!(usbPhyBase->ANACTRL & USBPHY_ANACTRL_PFD_STABLE_MASK)) + { + } +#endif + /* Decode to trim the nominal 17.78mA current source for the High Speed TX drivers on USB_DP and USB_DM. */ + usbPhyBase->TX = + ((usbPhyBase->TX & (~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK))) | + (USBPHY_TX_D_CAL(phyConfig->D_CAL) | USBPHY_TX_TXCAL45DP(phyConfig->TXCAL45DP) | + USBPHY_TX_TXCAL45DM(phyConfig->TXCAL45DM))); +#endif + + return kStatus_USB_Success; +} + +/*! + * @brief ehci phy de-initialization. + * + * This function de-initialize ehci phy IP. + * + * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t. + */ +void USB_EhciPhyDeinit(uint8_t controllerId) +{ +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) + USBPHY_Type *usbPhyBase; + + usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId); + if (NULL == usbPhyBase) + { + return; + } +#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT))) + usbPhyBase->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_POWER_MASK; /* power down PLL */ + usbPhyBase->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_EN_USB_CLKS_MASK; /* disable USB clock output from USB PHY PLL */ +#endif + usbPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* set to 1U to gate clocks */ +#endif +} + +/*! + * @brief ehci phy disconnect detection enable or disable. + * + * This function enable/disable host ehci disconnect detection. + * + * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t. + * @param[in] enable + * 1U - enable; + * 0U - disable; + */ +void USB_EhcihostPhyDisconnectDetectCmd(uint8_t controllerId, uint8_t enable) +{ +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) + USBPHY_Type *usbPhyBase; + + usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId); + if (NULL == usbPhyBase) + { + return; + } + + if (enable) + { + usbPhyBase->CTRL |= USBPHY_CTRL_ENHOSTDISCONDETECT_MASK; + } + else + { + usbPhyBase->CTRL &= (~USBPHY_CTRL_ENHOSTDISCONDETECT_MASK); + } +#endif +} diff --git a/usb/phy/usb_phy.h b/usb/phy/usb_phy.h new file mode 100644 index 0000000..f33533b --- /dev/null +++ b/usb/phy/usb_phy.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef __USB_PHY_H__ +#define __USB_PHY_H__ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +typedef struct _usb_phy_config_struct +{ + uint8_t D_CAL; /* Decode to trim the nominal 17.78mA current source */ + uint8_t TXCAL45DP; /* Decode to trim the nominal 45-Ohm series termination resistance to the USB_DP output pin */ + uint8_t TXCAL45DM; /* Decode to trim the nominal 45-Ohm series termination resistance to the USB_DM output pin */ +} usb_phy_config_struct_t; + +#if defined(__cplusplus) +extern "C" { +#endif + +/******************************************************************************* + * API + ******************************************************************************/ +/*! + * @brief EHCI PHY get USB phy bass address. + * + * This function is used to get USB phy bass address. + * + * @param[in] controllerId EHCI controller ID; See the #usb_controller_index_t. + * + * @retval USB phy bass address. + */ +extern void *USB_EhciPhyGetBase(uint8_t controllerId); + +/*! + * @brief EHCI PHY initialization. + * + * This function initializes the EHCI PHY IP. + * + * @param[in] controllerId EHCI controller ID; See the #usb_controller_index_t. + * @param[in] freq The external input clock. + * + * @retval kStatus_USB_Success Cancel successfully. + * @retval kStatus_USB_Error The freq value is incorrect. + */ +extern uint32_t USB_EhciPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig); + +/*! + * @brief ehci phy initialization for suspend and resume. + * + * This function initialize ehci phy IP for suspend and resume. + * + * @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t. + * @param[in] freq the external input clock. + * for example: if the external input clock is 16M, the parameter freq should be 16000000. + * + * @retval kStatus_USB_Success cancel successfully. + * @retval kStatus_USB_Error the freq value is incorrect. + */ +extern uint32_t USB_EhciLowPowerPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig); + +/*! + * @brief EHCI PHY deinitialization. + * + * This function deinitializes the EHCI PHY IP. + * + * @param[in] controllerId EHCI controller ID; See #usb_controller_index_t. + */ +extern void USB_EhciPhyDeinit(uint8_t controllerId); + +/*! + * @brief EHCI PHY disconnect detection enable or disable. + * + * This function enable/disable the host EHCI disconnect detection. + * + * @param[in] controllerId EHCI controller ID; See #usb_controller_index_t. + * @param[in] enable + * 1U - enable; + * 0U - disable; + */ +extern void USB_EhcihostPhyDisconnectDetectCmd(uint8_t controllerId, uint8_t enable); + +#if defined(__cplusplus) +} +#endif + +#endif /* __USB_PHY_H__ */